Hi,
I would like participate to the Google Summer Of Code with Wine by implementing a DIB Engine. I've searched a lot of informations about the DIB Engine but i still got one question : for you, how important is a DIB Engine in Wine ?
Ben.
___________________________________________________________________________ Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son interface révolutionnaire. http://fr.mail.yahoo.com
Am Donnerstag 01 März 2007 14:03 schrieb Benoit Pradelle:
Hi,
I would like participate to the Google Summer Of Code with Wine by implementing a DIB Engine. I've searched a lot of informations about the DIB Engine but i still got one question : for you, how important is a DIB Engine in Wine ?
Hard to say, it depends on what applications are needed.
If I said now "the most important thing" that would be obviously wrong, otherwise someone would have implemented it already. I'd say it is one of the top ranked items, but it requires a lot of work and a LOT of knowledge by the programmer. From the importance vs work required it is rather low.
The DIB engine would help applications which operate on DIB sections with both direct access and GDI commands. For example DirectX games which use IDirect*Surface?::GetDC regularly, or other applications(I think MS powerpoint is one of them). It will not help Direct3D applications which do not use GetDC.
It would also allow is a X-Server / <Apple something> independent GDI implementation. Right now our GDI implementation can only do what the X server can do - not more.
Another question is if the existing implementation using the X server can't be optimized. One inefficient thing is that always the full DIB section is converted and copied over. That is technically not necessary when a small letter is drawn to the top left corner. Of course optimizations tend to be tricky, and maybe do not compare with the cost/usability of a real DIB engine. Maybe DirectDraw can be optimized too, by moving the depth conversion from GetDC calls to surface locking. This would only shift the problem, but if DDraw can read the state of the DIB section it could choose the most efficient solution depending on the behavior of the game.
Another thing that should be checked before starting is if a fluent transition is possible. For example, when a new dibsection DC is created, create a classic dib section and a DC using the server. If the app does something the new code can't do yet, load the data into the server and use the existing X-Server GDI code. This way a fluent transition is possible, with implementing the important calls first, then adding rare things while still keeping full functionality.
Just some thoughts from my side. If you want this as a SOC project you will need some menthor, and I think Alexandre is the only one who can do that for implementing a DIB engine :-)
First thank you for your very complete answer,
I'm not really familiar with Wine (and the Windows API) and I don't understand why do you think that it will be such an hard work. For me, the work will consist in redirect the GDI calls from the X11 pseudo-driver to some new functions which will draw circles, lines, etc.. over DIBs. Do I misunderstand the work to do or under evaluate it ?
And I've understand by reading this mail-list how important are regression tests and fluent transitions in functionalities for Wine.
Stefan Dösinger a écrit :
Am Donnerstag 01 März 2007 14:03 schrieb Benoit Pradelle:
Hi,
I would like participate to the Google Summer Of Code with Wine by implementing a DIB Engine. I've searched a lot of informations about the DIB Engine but i still got one question : for you, how important is a DIB Engine in Wine ?
Hard to say, it depends on what applications are needed.
If I said now "the most important thing" that would be obviously wrong, otherwise someone would have implemented it already. I'd say it is one of the top ranked items, but it requires a lot of work and a LOT of knowledge by the programmer. From the importance vs work required it is rather low.
The DIB engine would help applications which operate on DIB sections with both direct access and GDI commands. For example DirectX games which use IDirect*Surface?::GetDC regularly, or other applications(I think MS powerpoint is one of them). It will not help Direct3D applications which do not use GetDC.
It would also allow is a X-Server / <Apple something> independent GDI implementation. Right now our GDI implementation can only do what the X server can do - not more.
Another question is if the existing implementation using the X server can't be optimized. One inefficient thing is that always the full DIB section is converted and copied over. That is technically not necessary when a small letter is drawn to the top left corner. Of course optimizations tend to be tricky, and maybe do not compare with the cost/usability of a real DIB engine. Maybe DirectDraw can be optimized too, by moving the depth conversion from GetDC calls to surface locking. This would only shift the problem, but if DDraw can read the state of the DIB section it could choose the most efficient solution depending on the behavior of the game.
Another thing that should be checked before starting is if a fluent transition is possible. For example, when a new dibsection DC is created, create a classic dib section and a DC using the server. If the app does something the new code can't do yet, load the data into the server and use the existing X-Server GDI code. This way a fluent transition is possible, with implementing the important calls first, then adding rare things while still keeping full functionality.
Just some thoughts from my side. If you want this as a SOC project you will need some menthor, and I think Alexandre is the only one who can do that for implementing a DIB engine :-)
___________________________________________________________________________ Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son interface révolutionnaire. http://fr.mail.yahoo.com
Benoit Pradelle [mailto:ze_real_neo@yahoo.fr] wrote:
I'm not really familiar with Wine (and the Windows API) and I don't
understand
why do you think that it will be such an hard work. For me, the work will
consist
in redirect the GDI calls from the X11 pseudo-driver to some new functions which will draw circles, lines, etc.. over DIBs. Do I misunderstand the work to do or under evaluate it ?
Well, technically a DIB engine is not necessarily that complicated and directly integrating it into GDI is also doable. It will probably require somewhat modified GDI internal data structures and even a few changes to the display driver interface.
The tricky part is to do it in such a way that the current implementation does never really break. And I think it is clear that one can not do it by applying one giant patch that transitions from the current sitution to a full blown DIB engine. This can't really work anyhow as you do not want to have to implement every single DIB operation right away.
So after you have done the design and architeccture of a somewhat working implementation, a large part of the work will be about making small incremental patches that can be applied to the Wine source without breaking Wine in between the patches.
And as Stefan already mentioned I think it would be important to discuss everything with Alexandre first. He is probably the best person for this as he understands that part very well and you also will have to get your patches past him. Without some good talk it is unlikely that you can create patches that he feels confident enough to apply.
And I've understand by reading this mail-list how important are regression
tests
and fluent transitions in functionalities for Wine.
That is very good, however automatic regression testing for display issues is not always possible so to some extend it is also about running all kinds of graphic intense packages and finding problems or differences to how it was before.
Rolf Kalbermatter
Benoit Pradelle [mailto:ze_real_neo@yahoo.fr] wrote:
I'm not really familiar with Wine (and the Windows API) and I don't
understand
why do you think that it will be such an hard work. For me, the work will
consist
in redirect the GDI calls from the X11 pseudo-driver to some new functions which will draw circles, lines, etc.. over DIBs. Do I misunderstand the work to do or under evaluate it ?
I think you underestimate it, or I overestimate it :-)
I hardly know GDI, but from the little bit I used it, and from the huge amount of literature I have seem about it, I think it is as complex as for example Direct3D10 or maybe even more complex.
But I think if you can do a fluent transition, then the huge amount of work will be cutable into small, doable chunks of work, and if you stop after doing half of the work for some reason the existing things are still of use.
On Fri, 2 Mar 2007, Stefan Dösinger wrote: [...]
But I think if you can do a fluent transition, then the huge amount of work will be cutable into small, doable chunks of work, and if you stop after doing half of the work for some reason the existing things are still of use.
It depends what you mean exactly by 'half the work', but I would go further and say that if the SOC project gets the basic infrastructure committed into Wine and implements just GetPixel() and PutPixel() it will already have made a huge contribution. Everything else is just a small matter of programming that can be tackled one function at a time.
On 3/1/07, Benoit Pradelle ze_real_neo@yahoo.fr wrote:
First thank you for your very complete answer,
I'm not really familiar with Wine (and the Windows API) and I don't understand why do you think that it will be such an hard work.
Read some code in dlls/winex11.drv in the wine tree, you will quickly understand :-).
The other thing is that there are many aspects of GDI drawing, you have to take into account region clipping, pens, brushes, line thickness, line style, fill style, and other wonders, and make them work in 1, 4, 8, 16, 24 and 32 bit colour depth pixel-for-pixel exact with the way Windows does them.
For me, the work will consist in redirect the GDI calls from the X11 pseudo-driver to some new functions which will draw circles, lines, etc.. over DIBs. Do I misunderstand the work to do or under evaluate it ?
There are probably several ways to do a DIB engine.
The way I would do it, is the way that Transgaming did it in that patch a number of years back, ie. where wine does:
X11DRV_LockDIBSection(..., DIB_Status_GdiMod, ...); // draw with the X server X11DRV_UnlockDIBSection(..., ...);
change it to do:
status = X11DRV_LockDIBSection(..., DIB_Status_None, ...); if (status == DIB_Status_AppMod) // draw with the DIB engine else { X11DRV_DIB_Coerce(..., DIB_Status_GdiMod, ...); // draw with the X server } X11DRV_UnlockDIBSection(..., ...);
But I asked Alexandre about this, and he said the whole point of the DIB engine is that you shouldn't need the locking. How that would work is beyond me, after all, if you only draw on the client-side, you still have to upload the image to the X server when you want it to become visible, but what about images that aren't double-buffered, and what about mixed drawing with OpenGL?
And I've understand by reading this mail-list how important are regression tests and fluent transitions in functionalities for Wine.
Stefan Dösinger a écrit :
Am Donnerstag 01 März 2007 14:03 schrieb Benoit Pradelle:
The other thing is that there are many aspects of GDI drawing, you have to take into account region clipping, pens, brushes, line thickness, line style, fill style, and other wonders, and make them work in 1, 4, 8, 16, 24 and 32 bit colour depth pixel-for-pixel exact with the way Windows does them.
I see. Effectively the number of parameters to take in account will be a difficulty and the GDI API is huge. Moreover implementing it in a fluent way won't be easy as said Stefan and Rolf.
But I asked Alexandre about this, and he said the whole point of the DIB engine is that you shouldn't need the locking. How that would work is beyond me, after all, if you only draw on the client-side, you still have to upload the image to the X server when you want it to become visible, but what about images that aren't double-buffered, and what about mixed drawing with OpenGL?
Perhaps should we draw everything asked in memory and just send it to X when the application calls EndPaint, this way we limit the interaction with the X server (and locks).
"Benoit Pradelle" ze_real_neo@yahoo.fr wrote:
Perhaps should we draw everything asked in memory and just send it to X when the application calls EndPaint, this way we limit the interaction with the X server (and locks).
You seem to not realize that painting also happens outside of the WM_PAINT handler, moreover some apps do not call EndPaint in WM_PAINT, or call it before they paint anything.
You seem to not realize that painting also happens outside of the WM_PAINT handler, moreover some apps do not call EndPaint in WM_PAINT, or call it before they paint anything.
Yep effectively I realized it after sending my mail. Anyway, Alexandre think that this project is not a good choice for a GSoC project so I'll perhaps think about another project at least for the moment. However thanks to all for your help and your answers.
Ben.
Hi,
On 3/2/07, Damjan Jovanovic damjan.jov@gmail.com wrote:
The other thing is that there are many aspects of GDI drawing, you have to take into account region clipping, pens, brushes, line thickness, line style, fill style, and other wonders, and make them work in 1, 4, 8, 16, 24 and 32 bit colour depth pixel-for-pixel exact with the way Windows does them.
I don't really know anything about the DIB engine or the engineering problem in getting it accepted except that it is going to be a massive beast and almost impossible to implement in small changes.
If I understand it correctly, there was an idea floating around that Ge van Geldorp had which was to auto generate the needed DIB engine code for certain color depths and functions so you would not have to implement the whole thing at once. if I remember correctly he did a proof of concept implementation for ReactOS by first creating the generic interfaces that were needed and then generating the code for the more simple color depths so as not to break all the existing hacks they had. Maybe I am off base here and Ge will comment as he lurks on wine-devel and I have cc'd him on this email.
Due to the lack of clean room engineering in ReactOS I doubt Alexandre would want to use that code. I know Ge developed it in clean manner so we might still be able to use his concept to develop our DIB engine even if we can't use that code directly.
Thanks
If I understand it correctly, there was an idea floating around that Ge van Geldorp had which was to auto generate the needed DIB engine code for certain color depths and functions so you would not have to implement the whole thing at once. if I remember correctly he did a proof of concept implementation for ReactOS by first creating the generic interfaces that were needed and then generating the code for the more simple color depths so as not to break all the existing hacks they had. Maybe I am off base here and Ge will comment as he lurks on wine-devel and I have cc'd him on this email.
This was specifically for BitBlt'ing. You have (potentially) 3 surfaces involved in a BitBlt, the source surface, the destination surface and a brush surface. For DIBs, the source and destination surface can be either 1, 4, 8, 16, 24 or 32 bits deep plus source and destination can have different depths. The brush can be either a solid brush or a patterned brush. There are 256 different ways to combine the surfaces (Raster Ops or ROPs). All of these variables mean that although it's possible to write generic code to handle everything that code is going to be littered with if's. Meaning that generic code is going to be slow for simple operations like filling a rectangle with a solid color. So you want to special-case the most-often used cases and make them fast, while using the slow, generic code as a fallback.
If you want to get the best performance, you need to write a lot of almost-identical-but-slightly-different code. For example, in the innermost loop you'll need to actually perform the ROP. But with 256 possible ROPs that can be quite a number of if's to execute. And you're doing that inside the innermost loop. To speed up things, I moved the ROP determination to the outermost level. Based on the ROP one of 256 possible subroutines is called, which in its innermost loop can just combine the bits in a way hardcoded for that specific ROP (i.e. no more if's there's just e.g. "*Dest = *Src ^ *Dest" there). Actually, in the end I didn't use 256 subroutines but only used subroutines for the most common ROPs (those with a symbol like PATCOPY) and used a catch-all generic subroutine for the lesser used ROPs. All these subroutines are almost the same, it's just the actual ROP code that's different between them. And for some ROPs there's no source surface involved, so for those ROPs you don't need to advance pointers into the source surface when you're moving from row to row etc. (meaning you can't just use a preprocessor macro, the changes between the subroutines are a bit too complicated for that).
That's where the code generator came in. It generated all those slightly different subroutines for the standard ROPs and a generic routine for the rest. For an example, see http://oss.gse.nl/wine/dib8gen.c which contains the generated bitblt routines for a 8-bit destination surface. Compare for example the DIB_8BPP_BitBlt_Generic() routine near the top (the catch-all one) with DIB_8BPP_BitBlt_PATCOPY() further down. The last one has very tight inner loops (especially when BltInfo->PatternSurface is NULL, meaning you're filling the destination rectangle with a solid color) compared to the first one.
Of course, at the time I did measure performance to see if all this optimization stuff indeed improved performance. And it did, dramatically even. It's been a while, so I don't recall most of the performance numbers anymore, but I do remember that I benchmarked some of the DIB BitBlt operations and found that the generated code in ReactOS was about 3 times as fast as the DIB code in Windows XP (on the same hardware of course).
I was actually quite proud of that code generator and the code it produced. The DIB code generator is absolutely clean, MS doesn't ship anything like it so it's simply impossible that it was created using reverse engineering. I put the code generator under the LGPL, specifically so it could be used by Wine if so desired. Note that the scope of this is limited to BitBlt's though, it won't help when you need to draw a 3-pixel wide dash-dotted ellips on your DIB surface...
Gé van Geldorp.
On 3/2/07, Steven Edwards winehacker@gmail.com wrote:
I don't really know anything about the DIB engine or the engineering problem in getting it accepted except that it is going to be a massive beast and almost impossible to implement in small changes.
Yup, I'm dumb about it too.
My $.02: with our fancy new git system, could we branch Wine and start developing a separate tree with a new DIB engine? Apply patches to both trees. There probably won't be too many merge conflicts because there's not a ton of work on GDI and x11drv these days.
Or maybe we could release a Wine 1.0 and start a development branch with that as one of the goals.
-Brian
On 3/10/07, Brian Vincent brian.vincent@gmail.com wrote:
On 3/2/07, Steven Edwards winehacker@gmail.com wrote:
I don't really know anything about the DIB engine or the engineering problem in getting it accepted except that it is going to be a massive beast and almost impossible to implement in small changes.
Yup, I'm dumb about it too.
My $.02: with our fancy new git system, could we branch Wine and start developing a separate tree with a new DIB engine? Apply patches to both trees. There probably won't be too many merge conflicts because there's not a ton of work on GDI and x11drv these days.
Or maybe we could release a Wine 1.0 and start a development branch with that as one of the goals.
-Brian
That is what I would have suggested doing if I applied for the DIB project this year. But with so much talk about it, I've shyed away from it. I wouldn't mind working on it with a team, and divide up the work though.
Jesse
Damjan Jovanovic [mailto:damjan.jov@gmail.com] wrote:
There are probably several ways to do a DIB engine.
The way I would do it, is the way that Transgaming did it in that patch a
number
of years back, ie. where wine does:
Actually better would be IMO to place it all in GDI. A lot of the Eng.. API functions that win32k.sys exports (which is basically just the GDI engine put into the kernel Space, and GDI32.DLL exports them actually too by forwarding to win32k.sys) deal with just this stuff among other things. Basically a W2K display driver can hook certain DIB operations to do itself and in case he only implements certain features such as bit depths he can forward the rest to those Eng.. functions too. If a driver did not hook the particular DIB operation (or maybe even if it failed it) win32k.sys will also call this Eng.. functions.
The problem I see with this is that implementing those Eng.. Functions that are documented in the DDK would make most sense by using the same prototypes but this Eng.. API is much more modelled around the w2k display driver interface that has by far not the direct 1:1 function mapping to the actual GDI functions as what the Wine display driver currently uses. Even the functions that are functionally similar use quite different parameter types.
But I asked Alexandre about this, and he said the whole point of the DIB
engine is
that you shouldn't need the locking. How that would work is beyond me,
after all,
if you only draw on the client-side, you still have to upload the image to
the X server
when you want it to become visible, but what about images that aren't
double-buffered,
and what about mixed drawing with OpenGL?
The idea is that once DIBs are entirely handled in the DIB engine, no locking is required anymore. Basically locking (and synchronization) is necessary since a DIB can be either handled through GDI functions or through direct memory access through its bitmap pointer. So for direct memory access whenever the DIB is in server mode it needs to be converted back to local mode before allowing access to the memory and when a display driver function is called to operate on a DIB the opposite needs to be done.
The only synchronisation for DIBs when having a fully working DIB engine would be when the DIB is blitted to the display. There is possibly a complication with OpenGL and Direct3D here but I'm not sure about the details for that.
Ge van Geldorp [ge@gse.nl] wrote:
I was actually quite proud of that code generator and the code it produced. The DIB code generator is absolutely clean, MS doesn't ship anything like
it
so it's simply impossible that it was created using reverse engineering. I
put
the code generator under the LGPL, specifically so it could be used by Wine if so desired. Note that the scope of this is limited to BitBlt's though,
it
won't help when you need to draw a 3-pixel wide dash-dotted ellips on your DIB surface...
Thanks Ge for this lengthy and good explanation. As to the drawing optimization I don't think that is a real trouble, certainly not to start with. Wine wants first something working correct and then one can decide if some fancy optimization for (dashed) lines, ellipses etc are at its place.
Rolf Kalbermatter