I've gone a bit further with my DIB Engine, mostly on gdi32 side, in
order to solve the last problems, at least as seen in my favorite app,
Autocad 2005.
Previous version had a bug related to the *only* .net part of that app
(which was obviously written by a 5 years old child, imho), the layer
manager.
On this one, a bitblt operation is done reading some screen part into a
DIB when painting the dialog on screen.
Worse than that, there are *many* small bitblt ops (like 40x1 pixels) on
*large* source/destination bitmaps (like some hundred kB - MB of pixel data.
Well, that stuff showed to me the big limit of the approach taken, the
"mixed driver" one with different driver pointers on same DC.
That's the approach taken by earlier intents of Jesse Allen and Huw Davies.
So I decided to make a break, examining the problems so far and maybe
discussing a bit about it.
1) Maintain DCs and bitmaps in sync with correct driver.
That problem is fully solved, requiring some small hacks on many parts
of gdi32, in detail in bitmap.c, dib.c and dc.c.
Well, not really hacks, even if the code isn't as clean as I'd like.
Difficulty here was mostly due to bmp funcs that should be identical to
DC on which it's selected, on DIB creation and on BITMAP_SetOwnerDC()
part. In short, that part should be quite good by now.
2) Now the big (and slow) problem : the "mixed" operations, those which
uses both DIBs and DDB; BitBlt(), StretchBlt and so on.
On those we can't simply use one driver because it can't handle other
driver's bitmap. Well, X11 driver could do it, in theory, but having the
DIB created by DIB engine makes it impossible (missing X11 physDev and
related pixmap).
So the problem, as correctly pointed by Jesse Allen, is to "uniformize"
the DCs *before* the BlitBlt operation, *or* to make DIB engine able to
deal with DDB stuffs.
I discarded latter approach for obvious reasons, the engine would become
a copy of X11 driver with added DIB stuffs, which would vanify the
(simpler) approach taken. BTW, I'm still convinced that the "right"
approach would be to rewrite X11 driver withe the engine embedded, OR to
embed the engine on gdi32 taking it off X11 driver.
Well, back to first approach, Jesse's one. It means to make a copy of
the source bitmap *before* blitting converting it on same format of
destination one. That approach is slower because it means to make a copy
/conversion of the source bitmap which can be time expensive.
Jesse's solution was to make a conversion of the *full* source bitmap
which showed it's first limit on my Autocad testings (the layer manager
part) on whith very small parts of a big image are Blitted. That means
sometimes hundreds of copy/conversions of a MB sized bitmap just to
transfer some 40 pixels a time..... not a real speed gain :-)
So I decided to limit the copy of the needed lines of source bitmap,
with help of GedDIBits/SetDIBits stuffs. Not perfect, but quite
faster..... *if* working.
SetDIBits seems to have some sort of bug when "startscan" and
"scanlines" don't use the full bitmap's size. I'm not able to test the
SetDIBits X11 code, so if somebody can check it that would be of great
help to me. GetDIBits works good with those parameters selecting a
stripe of full bitmap.
Now, the second problem on that approach, which emerged testing the same
autocad part. When blitting *from* screen device, there's no real BMP
selected onto DC, so the GetDIBits approach is useless. The only way to
cope with the problem is to make a (third) intermediate conversion, so
DEVICE DC ---bitblt (X11 side)--->memory DC (DDB)---GetDIBits---> DIB
That means 3 data transfers to make a BitBlt operation from display to a
DIB destination bitmap....
Anyways, even with those bottlenecks, autocad application shows great
speed improvements on TT fonts (from unusable to about the same windows
xp speed) with no visible slow downs.
Ciao
Max