saturday, 5 may 2007

posted at 14:23

Since fat.handler reached a pretty significant milestone I felt like I needed a break before getting into the excitement that is refactoring all the lock code (sigh), so I've just finished picking off an item on my todo list - faster bitmap scaling.

Regular readers may remember that last month I found my old port of JJFFE. I released the code and Kalamatee added code that allowed the tiny window to be resized. This worked nicely on native, but on hosted things went from a pleasant smooth-scrolling full-speed affair to a glacial one frame every few seconds - completely unusable.

At the time I did some digging and found what I believed to be the cause. The bitmap scaling code in graphics.hidd did its work by copying into the underlying hardware (or X11) driver a pixel at a time. For most of the hardware drivers, this merely poked values into the hardware framebuffer, and so worked quite quickly. The BitMap::DrawPixel method in x11gfx.hidd is incredibly slow for multiple uses though, having to lock, then plot, then flush the image, then unlock. This was happening for every one of the thousands of pixels in the image, and FFE was trying to do it every frame. Naturally, this is suboptimal.

So, I spent some time yesterday and today nutting out a fix. There may be a problem with the speed of DrawPixel on X11, but it made more sense to me to try and reduce the number of calls that the basic BitMap::BitMapScale method was making into the underlying hardware driver. The solution I decided on was to scale the image in memory and then push the new image to the hardware in one hit.

It took me ages as I know virtually nothing about the AROS graphics system, but I managed to get something working. It uses the same naive scaling algorithm as before, but now it calls BitMap::GetImage on the source bitmap to get a raw byte array, creates a second raw byte array, copies and scales the image into it, then calls BitMap::PutImage on the destination to write it out. As far as I can tell, its working perfectly.

I won't commit the patch yet because I'm quite unsure of myself and I want to get a couple of people (particularly on native) to poke at it and make sure its sane. Nonetheless I'm still quite proud of it. Unfortunately the scaling it produces looks quite ugly, particularly on FFE, so if I get into hacking on FFE some more I'll probably start looking into to smarter scaling algorithms.

Update 8/5/05: This patch is now in the nightlies. Kal reports that Wanderer with a scaled background now starts instantly rather than with a brief pause, and FFE has gone from 8 to 20 frames per second on his native build. Awesome!