Odds and Ends

  • Today I finally grokked how the Java2D Image API could be implemented. Basically the biggest problem (to me) always has been the BufferedImage constructor, which allowed BIes of all kinds to be created. What about image formats that are not supported by the native rendering engine? How are we supposed to render into that? Well, the solution would be to have 2 buffers like:
    RE --> nBuffer  < -- > jBuffer <-- Java2D API

    where the native buffer has a format that is supported by the RE and the java buffer (I call it so, it is not required to have that in Java, could be any memory area thanks to the fine DataBuffer abstraction) holds the data in the requested ColorModel/SampleModel. Well, the obvious problem here is when to sync the data and what to sync. Fortunately (that’s what I discovered today), BufferedImage implements WritableRenderedImage, which provides a couple of methods to grab the buffer for writing and release it. This is find, as it provides very nice syncpoints.One remaining obstactle is when the RE does not support a super-format (I call it like this. For instance, ARGB8888 is a superformat of RGB565) of the requested format. For instance, when the RE only supports ARGB1888 (which is the case for one system I am currently implementing this API for) but the app requires ARGB8888. How is the RE supposed to render into that. The API is a little weak in this respect as it doesn’t allow to reject the request. The only real solution would be to have a Java only renderer do the rendering, but this is very ugly for several reasons: The rendering would be noticably different and noticably slow (well the latter isn’t that bad. what do you expect when you request something not supported by the HW). Any comments and ideas on this are very appreciated.All in all, nowadays I feel about Java2D almost like I feel about NIO: Quite confusing for the start, but once things are sorted out and have found their place in the mind-picture, it seems relativly well thought out and nice. Only problem with Java2D probably is that it carries quite some cruft from the <= AWT1.1 days, which makes it even more confusing.

  • Today a collegue pointed me to this, makes my mind boggle. I copy it into here as a riddle to solve. So please make up your mind and find out what this is supposed to do. And yes, this is legal C code compilable by GCC. πŸ™‚
    switch ( count % 8 )  /* count > 0 assumed */
    {
    case 0:        do {  *to++ = *from++;
    case 7:              *to++ = *from++;
    case 6:              *to++ = *from++;
    case 5:              *to++ = *from++;
    case 4:              *to++ = *from++;
    case 3:              *to++ = *from++;
    case 2:              *to++ = *from++;
    case 1:              *to++ = *from++;
    } while (( count -= 8 ) > 0);
    }
  • Found an interesting JSR: Application Framework for Swing Gotta have a deeper look at it ASAP.
Advertisements

7 Responses to Odds and Ends

  1. Ville Voutilainen says:

    The riddle is known as Duff’s Device, as per its inventor, Tom Duff. See http://en.wikipedia.org/wiki/Duff's_device. It’s a real classic, but actually very useful for low-level stuff. And it’s used surprisingly often.

  2. Avery Regier says:

    It took me a little while to determine what the smiley should be, but it seems to simply copy count bytes from the memory location starting at from to the memory location starting at to. It is a loop unrolling construct. I’ve got to say that I have never seen a do while loop embedded in a switch statement before. The only reason for the switch statement is to make sure you don’t copy too many times the last time through the loop.

  3. The C snippet you have posted is known as “Duff’s Device“.

  4. roman says:

    Oh funny. I shouldn’t post without at least verifying once πŸ˜‰ Three correct answers anyway, great! What’s to add? The original code had *to = *from++ because it copied into one memory mapped I/O register (yay!). It must be noted that this code snipped is rather old, the technique makes a lot of sense in assembly (heck, I remember myself doing this on C64 for speedy drawing code), but for C you would rather let the C compiler do this for you for C loops ( -funroll-loops on GCC). Here is the orginal Usenet post from Tom Duff from 1984.

  5. Dmitri Trembovetski says:

    Regarding the technique: you may find that pulling the image from vram-based hw-accelerated surface to a java-based representation will be very slow – this is especially true on AGP/PCI, less so on PCIx boards.

    Also, what to do if you’re running in a headless environment – like a server generating images (maps,etc)? You’d still need a reasonably fast fall-back mechanism.

    Dmitri

  6. roman says:

    Dmitri, well my idea is not to have a BI in HW accelerated vram, but instead in a memory area that can be supported (through whatever means) by, e.g., Cairo. Cairo supports rendering into an arbitrary memory area (so presumably it’s not actually performed by HW, but instead by an optimized software renderer), but basically only ARGB8888. In GNU Classpath we could do rendering using a Java pipeline (which actually is quite fast — I did put quite some time in it to optimize hell out of it, without any allocations, using fixed-point arithmetics and very fast algorithms). But my general feeling to having two separate renderers do the rendering was that it would result in inconsisten rendering on different surfaces. But after reading your email (kind thanks again) it seems like this is what we should probably do too.

  7. Pingback: This note’s for you » Evolution Spam Filtering, BufferedImage again

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: