wined3d: Do not use the IWineD3DSurface for the cursor.

This commit is contained in:
Stefan Dösinger 2006-07-27 17:39:03 +02:00 committed by Alexandre Julliard
parent 0fbc1fc0df
commit 65e5ed60ae
3 changed files with 56 additions and 12 deletions

View File

@ -2115,6 +2115,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface) {
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 IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
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 IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
}
/* 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;
}

View File

@ -142,17 +142,40 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
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);

View File

@ -540,7 +540,8 @@ typedef struct IWineD3DDeviceImpl
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];