What is the 'Is Volatile' pin for? (ToImage)

I’m using ToImage (Bitmap) and setting a Texture with it. I’ve been having some errors on a production machine and the crash logs indicate that it could be related to this operation. Examining it has me wondering exactly what the ‘Is Volatile’ and ‘TakeOwnership’ pins do in this node and the right way to use them.

In my case the bitmap changes pretty often and it isn’t very big, around 162x162 pixels at 32bit ARGB. The textures are resized later.

I guess is volatile means something like ‘this memory isn’t pinned’ or ‘garbage collection, beware’, and maybe Take ownership is for an image with a longer lifespan and changes will filter down through any part of the program referencing the image?

Take Ownership
It means that when disposing the wrapper, the underlying bitmap will also get disposed. This is useful if you are the one creating the bitmap and only pass it along via the image wrapper. There are cases where you do not control the lifetime of the bitmap itself (you do not have ownership) in which case you would pass false here.

Volatile
If true it tells consumers that the image is only valid for that current call. They must process the image right away and not hold on to it. Useful in scenarios where the underlying image refers to some so temporary buffer and gets passed to consumers via an event like observables.

2 Likes

So if I understand this correctly:

Since I’m making a lot of images, its best to use Take Ownership so the wrapper gets disposed, so, downstream, anything looking at the image as a reference will see the reference disappear at the same time as the data does.

With Is Volatile, the consumer anticipates that the image can only be used for that frame, so this also avoids the situation where the consumer tries to read memory that doesn’t exist.

Is that right? And if so, would a single switch that does both miss anything?

It would be easier to see a sketch of what your patch actually does. But in general I’d agree, if your images are short living (only for one frame), setting both flags to true should be correct.

Thanks @Elias. I see what you mean, well they’re more intermittent than that. which is to say they aren’t particularly volatile, changing maybe a once every couple of seconds.

I made my own QRCode generator a while back, and internally it uses GDI+. The benefit at the time was that I could switch the colours of foreground and background.

Previously that was getting converted to skImage and then a texture. I’ce streamlined it a bit now, but I’ll probably move over to vvvv’s QRCode encoder, since I was seeing some errors apparently related to it.

In this particular case with ToImage using the defaults (Take Ownership = false, Is Volatile = true) the TryFromImage node will allocate its own memory and copy the image to it. The resulting SKImage therefor has no reference to the original image. This should not lead to a crash. You do however leave it up to the garbage collector to clean up all the temporary allocated bitmaps. Assuming the region we see is a Cache region with Dispose Cached Outputs = true, the resulting SKImage gets disposed properly, no work for garbage collector (good).

Here is a sketch which also cleans up the bitmap right away to not rely on GC:

4 Likes