If we create a new offscreen surface (which I was not
talking about doing, I only said we have to recreate the primary
(onscreen)
surface) with a different depth/format/etc than the original offscreen
surface, then we have effectively changed the X graphics mode and we
would
need to use some sort of X extension to notify clients that all
pixmaps and
visuals have been reset. If there is such an extension, I am not
aware of
it.
I'm not familiar with DirectX nor the internal of X so maybe I used
the wrong words. I'm not actually talking of changing what the X
server think the screen resolution/depth is. But we can already have
a different resolution/depth for the visual than for the monitor,
which means that there is a conversion at some point when the depth
doesn't match. So why can't you just throw away everything that is
after the conversion? I would think that, at worst, if the conversion
happens when drawing into the offscreen surface, all the buffers
would have to be recreated and that X would just have to ask all X
windows to redraw their content in the new offscreen buffer.
I think I see where you are confused.
I said previously that we can handle screen resolution changes because
we essentially just enable scrollbars, if necessary, to allow the
extra area to be viewed. With the Shadow GDI engine, that is all that
has to be done.
However, with the Shadow DirectDraw and Shadow DirectDraw Non-Locking
engines we must release and recreate the primary surface using the
same size as it had before. This is really just a technicality. You
see, DirectDraw allows a surface to be larger than the screen size.
But, when you change the screen resolution, DirectDraw requires that
you release the primary surface and create again. DirectDraw doesn't
care if you recreate the primary surface using the exact same
parameters; rather, it just wants you to recreate it. Yes, this is
silly, but that is what DirectDraw requires.
====
I also said previously that screen depth changes were much more
disruptive than screen resolution changes.
First, a little background on surfaces. We create an offscreen
surface and we provide the X graphics layers with a pointer into the
memory used to represent the pixels on that surface. All X graphics
operations (fb, shadow, mi, etc.) are done by calculating offsets of
various pixels in this ``framebuffer'' and applying various
transformations to those pixels. Thus, a horizontal blue line would
be drawn by offsetting to the start of that line, then flipping the
value for the next x pixels to blue. The ``shadow'' layer in X allows
graphics to be drawn to an offscreen framebuffer. Shadow keeps track
of the regions in the offscreen fraembuffer that have been updated,
and it occasionally calls a ``shadow update'' function that tells us
to transfer those regions to the screen. DirectDraw has something
called a ``primary surface'' that represents what is being displayed
on the screen. When we want to display the updated bits of the
offscreen framebuffer, we do a ``bit block transfer'' from the
offscreen surface to the primary surface.
The offscreen surface and the primary surface usually have the same
format (that is, they have the same pixel format that specifies how
many bits for red, green, and blue and how many bits are used per
pixel value in the framebuffer).
If the offscreen surface and the primary surface have the same format,
then a bit block transfer between them is essentially a memory copy
from the system memory to the video memory (with lots of fun synching
issues that Windows takes care of for us). Imagine for a second that
the offscreen surface was allowed to have a different format than the
primary surface. Then a bit block transfer from the offscreen surface
to the primary surface now must examine *every single pixel* and
transform the color values from, say, 16 bits per pixel to 32 bits per
pixel. That is a hell of a lot more complex than doing a simple
memory transfer.
DirectDraw is primarily concerned with enabling high-performance.
Therefore, I think that allowing the offscreen surface to have a
different depth than the primary surface would be contradictory to the
purpose of DirectDraw.
I have not checked the DirectDraw documentation to see whether
offscreen surfaces must have the same depth as primary surfaces. I
did say that I did not think it likely that DirectDraw would allow
different depths for the two surfaces. You could verify this, but I
am willing to bet that different depths are not allowed.
Notice that we never change the format of the offscreen framebuffer.
Thus, the structure of the framebuffer that X draws to us unchanged.
X does not support screen depth changes while running, so changing the
format of our offscreen framebuffer would causes all graphics
operations to draw incorrectly and it would possibly cause a
segmentation fault if the depth of the offscreen framebuffer was
decreased (because the total memory region would then be smaller than
X was expecting).
====
With the Shadow GDI engine, Windows will transform *every single
pixel* whenever we do a bit block transfer from a DIB to the screen
and the depth of the two differs. Thus, we are allowed to have a
different depth for the X visual than for the Windows screen, but
doing so causes a huge performance penalty. However, I think that
allowing this and providing a popup warning about the performance
penalty is better than just ceasing to display graphics at all.
====
With the DirectDraw engines I do not think that we can have a differnt
depth for the two surfaces, so I fear that our only option in that
case is to cease transferring the updated regions of the offscreen
surface until such a time as the Windows screen depth has been
returned to its original value.
====
Does that answer your questions?
Wow, what an answer. I was expecting that. Thanks.