monday, 17 september 2007

posted at 22:27
  • mood: wtf

Read this comic. Go on, I'll wait.

There's something the comic doesn't tell you. The process that makes photosynthesis happen is exactly the same process was that used to design and implement the graphics hidd interface.

SDL work continues. I have it at the point where its creating both on and off-screen bitmaps, though there's a third type ("non-displayable") that I haven't done yet. I can see calls being made to my bitmap PutPixel() methods, so I know that something semi-correct is happening. As yet though, drawing isn't implemented, and AROS still crashes on boot because I haven't written everything yet.

The development process for this has pretty much been:

  • Stub some functions/methods.
  • Run AROS in the debugger.
  • When it crashes, find out where, and go and look up the corresponding source file.
  • Break my head against the poorly structured and mostly uncommented code within.
  • Look at the existing hidds to figure out how to implement it, but give up because all the native hidds are based on vga.hidd and the only non-native hidd, x11gfx.hidd has piles of cruft left over from the days before layers.library, where every AROS window had its own X11 window.
  • Get a vague sense of what's going on.
  • Implement enough of the function to stop the crash happening, even though the code itself is probably incorrect.
  • Rinse, repeat.

So things are moving at a glacial pace, but at least they're moving, which is something.

The hidd interface works well enough, but is really weird in some places. For example, when graphics.library wants to create a new bitmap (which is the lowest-level structure in the graphics system), it calls Gfx::NewBitMap(). Confusingly, this method doesn't create and return a bitmap, but rather returns a reference to a bitmap class that can handle the type of bitmap the caller requests (displayable, hardware, etc). The caller then instantiates that class to get its bitmap. This is rather peculiar from an OO standpoint.

Oh, I've just had an epiphany about the bitmap classes. All the existing hidds implement an "on-screen" and an "off-screen" bitmap, which are basically the same but with slightly different initialisation. Most of the common functions are in a single bitmap_common.c file which is #include'd into the class source (a horrible idea no matter where you see it or what the justification).

The on-screen bitmap constructors typically make the bitmap appear on the screen as well, which has really been confusing me as there's also a Gfx::Show() method that gets passed a bitmap to display. This wasn't making sense. What if two on-screen bitmaps were created? Would their constructors cause them both to be displayed? What if an off-screen bitmap is passed to Show()? What if steak knives were actually made of cheese?

Anyway its just now clicked. The distinction between on-screen and off-screen bitmaps is entirely internal to the hidd. One of these types is chosen based on the values of the Displayable and Framebuffer bitmap attributes. For SDL though, they're pretty much all the same. I don't need a seperate class for each. So all thats needed is to create a bunch of bitmaps, and when Gfx::Show() is called just arrange for that one to be shown.

That last point is slightly more complex. Under SDL, you have a single on-screen surface, and then as man off-screen surfaces as you like, which you can blit to the screen. You can't choose to display an off-screen surface on a whim, you have to blit it. So what this means is that when Gfx::Show() is called on a bitmap, I have to make sure that the current surface matches the bitmap's resolution, and recreate it if not. Then we make a note inside the bitmap object that it is currently on-screen.

When something makes a change to a bitmap, this flag is checked. If the on-screen bitmap is being written to, then the update must be followed with a blit to the current surface. I haven't tested this yet, but I think the idea is sound.

I estimate another four hours of code before I have some graphics displaying. One day, when all this is finished, I'd like to write a "how to write a graphics driver" doc, and/or fix the damn interface. Yeah, right.