This is the mail archive of the
cygwin-xfree@cygwin.com
mailing list for the Cygwin XFree86 project.
Re: On a side note - display resolution changes now handled
Harold L Hunt II wrote:
Well, actually yes :p. I did some canoeing last Friday and I haven't
recovered yet. :)
Are you talking about canoeing, or ``canoeing''. When we went
``canoeing'' it involved a cooler full of beer and as the day progressed
the cooler full of beer was spotted more and more often floating down
the river next to a coule of upside down canoes and a bunch of guys
trying to get the cooler back into a righted canoe before the precious
contents were lost. But I digress... :)
Sounds nice :).
But this was a "social event" from my company so no alcohol.
Moreover, I don't drink alcohol. I don't trust myself to stop when I
have too much :p.
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.
There was one question I didn't get the answer but it doesn't apply
anymore. I thought we could already have a different depth between the
visual and the screen (-depth option) but the option is ignore (at least
in windowed mode, didn't try in fullscreen).
I have another one though but maybe it doesn't apply in our case. I know
that in 3D games, you can have 16bit texture with a 32bit display and
vice versa. So maybe DirectDraw does support the conversion. As for the
performance issue, it may not be that much. DirectX usually uses
hardware acceleration (except on very old cards).
Hmmm... After a quick read of MSDN, I got two different answers:
- One says that surfaces can be converted:
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/filter/overview/AboutTransformsandDXSurfaces.asp
- One says that there DirectDraw doesn't provide format conversion.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndxgen/html/dxfaq2.asp
(Does DirectDraw convert between pixel formats while blitting?)
And they say later on (How do I perform alpha blending?) that Direct3D
should be used for any "fancy" transformation.
Well, anyway, it's not as if the user keeps changing color depth. So a
simple popup dialog would be ok I guess... There is still a test that
need to be done: on dual screen systems, what happens if one screen is
16bit while the other is 32bit? Is it even possible?
Jehan