Stefan Dösinger : wined3d: Do not use the IWineD3DSurface for the cursor.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jul 28 07:15:06 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 65e5ed60ae02f01015222a4317770a0444d36549
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=65e5ed60ae02f01015222a4317770a0444d36549
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Thu Jul 27 17:39:03 2006 +0200
wined3d: Do not use the IWineD3DSurface for the cursor.
---
dlls/wined3d/device.c | 30 +++++++++++++++++++++++++-----
dlls/wined3d/swapchain.c | 35 +++++++++++++++++++++++++++++------
dlls/wined3d/wined3d_private.h | 3 ++-
3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 83754c2..651d134 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2115,6 +2115,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl
if(!This->d3d_initialized) return WINED3DERR_INVALIDCALL;
+ /* Delete the mouse cursor texture */
+ if(This->cursorTexture) {
+ ENTER_GL();
+ glDeleteTextures(1, &This->cursorTexture);
+ LEAVE_GL();
+ This->cursorTexture = 0;
+ }
+
for(sampler = 0; sampler < GL_LIMITS(sampler_stages); ++sampler) {
IWineD3DDevice_SetTexture(iface, sampler, NULL);
}
@@ -7471,6 +7479,13 @@ static HRESULT WINAPI IWineD3DDeviceIm
TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
/* some basic validation checks */
+ if(This->cursorTexture) {
+ ENTER_GL();
+ glDeleteTextures(1, &This->cursorTexture);
+ LEAVE_GL();
+ This->cursorTexture = 0;
+ }
+
if(pCursorBitmap) {
/* MSDN: Cursor must be A8R8G8B8 */
if (WINED3DFMT_A8R8G8B8 != pSur->resource.format) {
@@ -7486,19 +7501,24 @@ static HRESULT WINAPI IWineD3DDeviceIm
}
/* TODO: MSDN: Cursor sizes must be a power of 2 */
- if(This->mouseCursor) {
- ((IWineD3DSurfaceImpl *) This->mouseCursor)->Flags &= ~SFLAG_FORCELOAD;
- }
/* This is to tell our texture code to load a SCRATCH surface. This allows us to use out
* Texture and Blitting code to draw the cursor
*/
pSur->Flags |= SFLAG_FORCELOAD;
+ IWineD3DSurface_PreLoad(pCursorBitmap);
+ pSur->Flags &= ~SFLAG_FORCELOAD;
+ /* Do not store the surface's pointer because the application may release
+ * it after setting the cursor image. Windows doesn't addref the set surface, so we can't
+ * do this either without creating circular refcount dependencies. Copy out the gl texture instead.
+ */
+ This->cursorTexture = pSur->glDescription.textureName;
+ This->cursorWidth = pSur->currentDesc.Width;
+ This->cursorHeight = pSur->currentDesc.Height;
+ pSur->glDescription.textureName = 0; /* Prevent the texture from beeing changed or deleted */
}
This->xHotSpot = XHotSpot;
This->yHotSpot = YHotSpot;
-
- This->mouseCursor = pCursorBitmap;
return WINED3D_OK;
}
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 9dde987..f0b3033 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -142,17 +142,40 @@ static HRESULT WINAPI IWineD3DSwapChainI
ENTER_GL();
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
- if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->mouseCursor) {
- IWineD3DSurfaceImpl *cursor = (IWineD3DSurfaceImpl *) This->wineD3DDevice->mouseCursor;
+ if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) {
+ IWineD3DSurfaceImpl cursor;
RECT destRect = {This->wineD3DDevice->xScreenSpace - This->wineD3DDevice->xHotSpot,
This->wineD3DDevice->yScreenSpace - This->wineD3DDevice->yHotSpot,
- This->wineD3DDevice->xScreenSpace + cursor->currentDesc.Width - This->wineD3DDevice->xHotSpot,
- This->wineD3DDevice->yScreenSpace + cursor->currentDesc.Height - This->wineD3DDevice->yHotSpot};
- TRACE("Rendering the cursor\n");
+ This->wineD3DDevice->xScreenSpace + This->wineD3DDevice->cursorWidth - This->wineD3DDevice->xHotSpot,
+ This->wineD3DDevice->yScreenSpace + This->wineD3DDevice->cursorHeight - This->wineD3DDevice->yHotSpot};
+ TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor);
+ /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
+ * the application because we are only supposed to copy the information out. Using a fake surface
+ * allows to use the Blitting engine and avoid copying the whole texture -> render target blitting code.
+ */
+ memset(&cursor, 0, sizeof(cursor));
+ cursor.lpVtbl = &IWineD3DSurface_Vtbl;
+ cursor.resource.ref = 1;
+ cursor.resource.wineD3DDevice = This->wineD3DDevice;
+ cursor.resource.pool = WINED3DPOOL_SCRATCH;
+ cursor.resource.format = WINED3DFMT_A8R8G8B8;
+ cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
+ cursor.glDescription.textureName = This->wineD3DDevice->cursorTexture;
+ cursor.glDescription.target = GL_TEXTURE_2D;
+ cursor.glDescription.level = 0;
+ cursor.currentDesc.Width = This->wineD3DDevice->cursorWidth;
+ cursor.currentDesc.Height = This->wineD3DDevice->cursorHeight;
+ cursor.glRect.left = 0;
+ cursor.glRect.top = 0;
+ cursor.glRect.right = cursor.currentDesc.Width;
+ cursor.glRect.bottom = cursor.currentDesc.Height;
+ /* The cursor must have pow2 sizes */
+ cursor.pow2Width = cursor.currentDesc.Width;
+ cursor.pow2Height = cursor.currentDesc.Height;
/* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
* which is exactly what we want :-)
*/
- IWineD3DSurface_Blt(This->backBuffer[0], &destRect, This->wineD3DDevice->mouseCursor, NULL, DDBLT_KEYSRC, NULL);
+ IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, DDBLT_KEYSRC, NULL);
}
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f4ae19d..5329e42 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -540,7 +540,8 @@ #define NEEDS_DI
UINT yHotSpot;
UINT xScreenSpace;
UINT yScreenSpace;
- IWineD3DSurface *mouseCursor;
+ UINT cursorWidth, cursorHeight;
+ GLuint cursorTexture;
/* Textures for when no other textures are mapped */
UINT dummyTextureName[MAX_TEXTURES];
More information about the wine-cvs
mailing list