mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
wined3d: Do not use the IWineD3DSurface for the cursor.
This commit is contained in:
parent
0fbc1fc0df
commit
65e5ed60ae
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user