This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Explanation of Shadow Framebuffer Test 7 vs. (old) Offscreen Test 7


Ah, a very good question.

I made the comment that there would not be a framebuffer based X server for
Windows 95/98/Me before I knew about the shadow framebuffer code.

Shadow framebuffer was written by Keith Packard and is located in the
XFree86 CVS tree under xc/programs/Xserver/miext/shadow/.

To use shadow framebuffer you allocate an offscreen (shadow) framebuffer and
tell your painting code, be it fb, mfb, or one of the cfbs, to paint to the
offscreen framebuffer.  Then you initialize the shadow framebuffer code.
Shadow framebuffer steps in and wraps all of your previous painting
functions with functions that keep track of the area updated by each
graphics call.  Shadow framebuffer also installs its own BlockHandler that
calls a shadowUpdateProc (), supplied by you, that transfers the group of
updated areas to the screen.

You can use any feasible method in your shadowUpdateProc to transfer the
updated regions to the screen.

Engine 1 uses a Graphics Device Interface (GDI) Device Independent Bitmap
(DIB) as the shadow framebuffer; we get a pointer to the memory used by the
DIB by creating it with Win32's CreateDIBSection ().  Before you start
thinking that DIBs must be slow, you should be informed that DIBs are, I
believe, the foundation of DirectDraw.  Engine 1's shadowUpdateProc () uses
the GDI Blt function to transfer the updated (damaged) regions of the shadow
DIB to the screen.

Engine 2 uses a DirectDraw offscreen surface as the shadow framebuffer; we
get a pointer to the memory used by the surface by calling
IDirectDrawSurface_Lock ().  Engine 2's shadowUpdateProc () uses
DirectDraw's IDirectDrawSurface_Blt () to transfer the damaged regions of
the shadow framebuffer to the screen.  However, before each call to
IDirectDrawSurface_Blt () we must call IDirectDrawSurface_Unlock (), as you
cannot blit from a locked surface.  Consequently, after each call to
IDirectDrawSurface_Blt () we must call IDirectDrawSurface_Lock () to
reobtain a pointer to the memory of our surface.  All of the locking and
unlocking adds up, thus Engine 3.

Engine 3 uses a DirectDraw offscreen surface with client allocated memory as
the shadow framebuffer.  Client allocated memory means that we allocate a
block of memory large enough for the DirectDraw surface, then we tell
DirectDraw to treat that memory as a surface.  We can then call
IDirectDrawSurface_Blt () without having to unlock and relock the surface.
Therefore, Engine 3 has some pretty amazing performance.  Apparently this
technique only works with DirectX 6 or higher, thus it will work on Windows
95/98/Me/2000, but it will not work on NT 4.0.

Back to your question.  When I made my comment I had briefly thought about
writing something similar to the shadow framebuffer code, but I knew that I
didn't know enough about update regions and X servers in general to pull it
off.  I also doubted that the performance would be that great.  I started
writing a native GDI X server instead.  There was a big discussion when I
asked questions on the XFree86 devel list related to my native GDI server;
the debate primarily centered around whether translating X graphics calls
into GDI calls would be faster than using the shadow framebuffer code.  I
asked what the shadow framebuffer was, and that is how we got here.

My old offscreen test 7 did all drawing to an offscreen surface, in a manner
similar to how the shadow framebuffer works.  However, I had no way to keep
track of which, if any, regions of the offscreen framebuffer had been
updated.  Therefore I decided that fifteen times per second I would transfer
the entire offscreen framebuffer to the screen, regardless of whether any of
the offscreen framebuffer had been changed.  Offscreen test 7 was clearly
not ideal; to make it ideal would be to reimplement the shadow framebuffer
code.

So, that is difference between the old offscreen test 7 and the new shadow
framebuffer test 7, and I made my remark because I didn't know of a feasible
method of writing a framebuffer based server for Windows 95/98/Me at the
time :)

I will continue to work on the native GDI server, as there is only one way
to answer the performance debate once and for all :)

Thanks for your interest in the project,

Harold Hunt


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]