API review - Image Ops (RT-17409)
Jim Graham
james.graham at oracle.com
Wed May 16 16:08:50 PDT 2012
After some internal discussion and noticing that the semantics of being
able to edit any Image meant a noticeable increase in overhead on
managing listeners for an ImageView (for a port of the GUIMark2 Bitmap
test we saw a 25% drop in performance for 18K monsters, even though the
monster bitmaps were never edited), we decided to separate out writable
images from regular images. It's an important internal optimization to
know that a standard Image can never be modified. So, the API is
roughly the same, but how you get at the pixels is now slightly
different. We have:
javafx.scene.image.Image:
same PixelFormat, WritablePixelFormat as before
new interface PixelReader
- getPixelFormat()
- all of the get*() methods from the previous API
new interface PixelWriter
- getPixelFormat()
- all of the set*() methods from the previous API
- one additional setPixels(x,y,w,h,PixelReader) method
new method on Image
- PixelReader getPixelReader()
(it may return null for the same conditions that we used to specify
for Image.getPixelFormat(). Once you get a non-null PixelReader
from it, though, you are good to read forever)
new subclass
public class WritableImage extends Image {
public WritableImage(int width, int height)
public WritableImage(PixelReader, w, h)
public WritableIamge(PixelReader, x, y, w, h)
public PixelWriter getPixelWriter()
}
Note that you can still read any loaded image, but writability is
relegated to only specifically created "writable" images.
And it is easy enough to make a writable copy of any image, or create a
brand new writable image without violating the read only property of the
base images that allows us to optimize them internally. If you want to
modify the pixels of a loaded image, then you can modify them by easily
making a copy using:
new WritableImage(img.getPixelReader(),
(int) img.getWidth(),
(int) img.getHeight())
With the new arrangement of the API the performance on the 18,000
monster BitmapTest went back to its former frame rates. The
documentation is now somewhat simpler since you either get a PixelReader
or not depending on whether the image is loaded without errors, and if
it is in a supported format. There are no raw access methods on the
base Image class that might throw "Unsupported" exceptions - all of the
conditions for being able to access the pixels are focused on the one
getPixelReader() method - either you get a Reader, or you don't.
We hope to get this into a promoted build soon so that people can play
with it (still waiting for final API approval and webrev reviews for
internal code)...
...jim
More information about the openjfx-dev
mailing list