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