The OpenGL renderer listens for imageDataChanged() to invalidated cached
textures.
Before this change, the SimpleFFTDemo would display a static (outdated)
image on Windows when using the OpenGLRenderer.
When syncing from CPU->GPU storage, we currently copy the entire image
contents. The contents of the CPU backup completely replace the old GPU
image. Therefore, if any pixels need to retain their existing values, we
need to read those pixels before overwriting them. This in turn implies
that, when a BitmapData refers to a subsection of the image, we should
always flush GPU->CPU storage first, so that the subsequent CPU->GPU
sync doesn't clobber pixels outside of the BitmapData region with
outdated values.
It's clear that copying the entire image back and forth could be
suboptimal when writing to image subsections, but to optimise this
process we'd have to keep track of dirty image regions or similar, which
may in turn pessimise more common cases.
Previously, this function didn't store/copy the provided bitmap, so the
resulting image was blank. This also broke createSnapshot(), which would
always return a blank image.
This change also moves the startFrame and endFrame calls out of the
plain Direct2DImageContext and into a special-purpose "flushing" context
that is private to Direct2DPixelData.