wined3d: Rework surface dirtification.

Previously the surfaces stored a flag if the system memory copy was
ahead of the gl copy(SFLAG_DIRTY) or the gl copy is
ahead(SFLAG_GLDIRTY). The pbuffer copy was 'managed' differently using
SFLAG_INPBUFFER and SFLAG_INTEXTURE.

This patch replaces them with 3 flags, INSYSMEM, INPBUFFER and
INTEXTURE which specify which copy contains the most up to date
copy. It is perfectly valid to have more than one of those flags
set. One must be set at least (except at init, when no content is in
the surface yet). When one copy is modified, the flags for the others
are removed.
This commit is contained in:
Stefan Dösinger 2007-03-06 21:47:45 +01:00 committed by Alexandre Julliard
parent ebe274feed
commit c54a0fc2cf
9 changed files with 124 additions and 81 deletions

View file

@ -709,12 +709,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
/* Do that before switching the context:
* Read the back buffer of the old drawable into the destination texture
*/
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags |= SFLAG_INPBUFFER;
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INTEXTURE;
IWineD3DSurface_AddDirtyRect(This->lastActiveRenderTarget, NULL);
IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INPBUFFER;
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INTEXTURE;
}
This->lastActiveRenderTarget = target;
if(oldRenderOffscreen != This->render_offscreen && This->depth_copy_state != WINED3D_DCS_NO_COPY) {

View file

@ -4233,7 +4233,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun
/* Dirtify the target surface for now. If the surface is locked regularily, and an up to date sysmem copy exists,
* it is most likely more efficient to perform a clear on the sysmem copy too isntead of downloading it
*/
((IWineD3DSurfaceImpl *)This->render_targets[0])->Flags |= SFLAG_GLDIRTY;
if(This->render_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
((IWineD3DSurfaceImpl *)This->render_targets[0])->Flags |= SFLAG_INTEXTURE;
((IWineD3DSurfaceImpl *)This->render_targets[0])->Flags &= ~SFLAG_INSYSMEM;
} else {
((IWineD3DSurfaceImpl *)This->render_targets[0])->Flags |= SFLAG_INDRAWABLE;
((IWineD3DSurfaceImpl *)This->render_targets[0])->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INSYSMEM);
}
return WINED3D_OK;
}
@ -4827,7 +4833,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
LEAVE_GL();
((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags |= SFLAG_GLDIRTY;
((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags &= ~SFLAG_INSYSMEM;
((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags |= SFLAG_INTEXTURE;
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(0));
return WINED3D_OK;

View file

@ -1002,6 +1002,9 @@ void drawPrimitive(IWineD3DDevice *iface,
int minIndex) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSwapChain *swapchain;
IWineD3DBaseTexture *texture = NULL;
IWineD3DSurfaceImpl *target;
int i;
/* Signals other modules that a drawing is in progress and the stateblock finalized */
@ -1009,8 +1012,41 @@ void drawPrimitive(IWineD3DDevice *iface,
/* Invalidate the back buffer memory so LockRect will read it the next time */
for(i = 0; i < GL_LIMITS(buffers); i++) {
if(This->render_targets[i]) {
((IWineD3DSurfaceImpl *) This->render_targets[i])->Flags |= SFLAG_GLDIRTY;
target = (IWineD3DSurfaceImpl *) This->render_targets[i];
/* TODO: Only do all that if we're going to change anything
* Texture container dirtification does not work quite right yet
*/
if(target /*&& target->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)*/) {
swapchain = NULL;
texture = NULL;
if(i == 0) {
IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DSwapChain, (void **)&swapchain);
if(swapchain) {
/* Onscreen target. Invalidate system memory copy and texture copy */
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
IWineD3DSwapChain_Release(swapchain);
} else if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
/* Non-FBO target: Invalidate system copy, texture copy and dirtify the container */
IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DBaseTexture, (void **)&texture);
if(texture) {
IWineD3DBaseTexture_SetDirty(texture, TRUE);
IWineD3DTexture_Release(texture);
}
target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE);
target->Flags |= SFLAG_INDRAWABLE;
} else {
/* FBO offscreen target. Invalidate system memory copy */
target->Flags &= ~SFLAG_INSYSMEM;
}
} else {
/* Must be an fbo render target */
target->Flags &= ~SFLAG_INSYSMEM;
target->Flags |= SFLAG_INTEXTURE;
}
}
}

View file

@ -446,7 +446,7 @@ void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT te
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
TRACE("(%p) : setting textureName %u, target %i\n", This, textureName, target);
if (This->glDescription.textureName == 0 && textureName != 0) {
This->Flags |= SFLAG_DIRTY;
This->Flags &= ~SFLAG_INTEXTURE;
IWineD3DSurface_AddDirtyRect(iface, NULL);
}
This->glDescription.textureName = textureName;
@ -598,7 +598,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
/* Whatever surface we have, make sure that there is memory allocated for the downloaded copy */
if(!This->resource.allocatedMemory) {
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + 4);
This->Flags |= SFLAG_GLDIRTY; /* This is the marker that surface data has to be downloaded */
This->Flags &= ~SFLAG_INSYSMEM; /* This is the marker that surface data has to be downloaded */
}
/* Calculate the correct start address to report */
@ -651,7 +651,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
}
}
if((Flags & WINED3DLOCK_DISCARD) || !(This->Flags & SFLAG_GLDIRTY) ) {
if((Flags & WINED3DLOCK_DISCARD) || (This->Flags & SFLAG_INSYSMEM)) {
TRACE("WINED3DLOCK_DISCARD flag passed, or local copy is up to date, not downloading data\n");
goto lock_end;
}
@ -731,7 +731,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
This->lockedRect.top == 0 &&
This->lockedRect.right == This->currentDesc.Width &&
This->lockedRect.bottom == This->currentDesc.Height) {
This->Flags &= ~SFLAG_GLDIRTY;
This->Flags |= SFLAG_INSYSMEM;
}
} else if(iface == myDevice->stencilBufferTarget) {
/** the depth stencil in openGL has a format of GL_FLOAT
@ -750,7 +750,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
* (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
*
* Depth Stencil surfaces which are not the current depth stencil target should have their data in a
* gl texture(next path), or in local memory(early return because of missing SFLAG_GLDIRTY above). If
* gl texture(next path), or in local memory(early return because of set SFLAG_INSYSMEM above). If
* none of that is the case the problem is not in this function :-)
********************************************/
FIXME("Depth stencil locking not supported yet\n");
@ -779,7 +779,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
}
/* The local copy is now up to date to the opengl one because a full download was done */
This->Flags &= ~SFLAG_GLDIRTY;
This->Flags |= SFLAG_INSYSMEM;
}
lock_end:
@ -803,7 +803,8 @@ lock_end:
}
}
TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch, This->Flags & SFLAG_DIRTY ? 0 : 1);
TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch,
This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
return WINED3D_OK;
}
@ -1061,9 +1062,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
return WINED3DERR_INVALIDCALL;
}
TRACE("(%p) : dirtyfied(%d)\n", This, This->Flags & SFLAG_DIRTY ? 1 : 0);
TRACE("(%p) : dirtyfied(%d)\n", This, This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
if (!(This->Flags & SFLAG_DIRTY)) {
if (This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE)) {
TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This);
goto unlock_end;
}
@ -1130,8 +1131,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
}
LEAVE_GL();
/** restore clean dirty state */
IWineD3DSurface_CleanDirtyRect(iface);
This->dirtyRect.left = This->currentDesc.Width;
This->dirtyRect.top = This->currentDesc.Height;
This->dirtyRect.right = 0;
This->dirtyRect.bottom = 0;
This->Flags |= SFLAG_INDRAWABLE;
} else if(iface == myDevice->stencilBufferTarget) {
FIXME("Depth Stencil buffer locking is not implemented\n");
} else {
@ -1293,7 +1297,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
} else {
/* This is to make LockRect read the gl Texture although memory is allocated */
This->Flags |= SFLAG_GLDIRTY;
This->Flags &= ~SFLAG_INSYSMEM;
}
HeapFree(GetProcessHeap(), 0, b_info);
@ -1687,11 +1691,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
int width, pitch, outpitch;
BYTE *mem;
if (This->Flags & SFLAG_INTEXTURE) {
TRACE("Surface already in texture\n");
return WINED3D_OK;
}
if (This->Flags & SFLAG_DIRTY) {
if (!(This->Flags & SFLAG_INTEXTURE)) {
TRACE("Reloading because surface is dirty\n");
} else if(/* Reload: gl texture has ck, now no ckey is set OR */
((This->Flags & SFLAG_GLCKEY) && (!(This->CKeyFlags & DDSD_CKSRCBLT))) ||
@ -1705,11 +1705,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
} else if(palette9_changed(This)) {
TRACE("Reloading surface because the d3d8/9 palette was changed\n");
} else {
TRACE("surface isn't dirty\n");
TRACE("surface is already in texture\n");
return WINED3D_OK;
}
This->Flags &= ~SFLAG_DIRTY;
This->Flags |= SFLAG_INTEXTURE;
/* Resources are placed in system RAM and do not need to be recreated when a device is lost.
* These resources are not bound by device size or format restrictions. Because of this,
@ -1722,7 +1722,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
return WINED3DERR_INVALIDCALL;
}
if (This->Flags & SFLAG_INPBUFFER) {
if (This->Flags & SFLAG_INDRAWABLE) {
if (This->glDescription.level != 0)
FIXME("Surface in texture is only supported for level 0\n");
else if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8 ||
@ -1734,7 +1734,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
GLint prevRead;
ENTER_GL();
glGetIntegerv(GL_READ_BUFFER, &prevRead);
vcheckGLcall("glGetIntegerv");
glReadBuffer(This->resource.wineD3DDevice->offscreenBuffer);
@ -1755,11 +1754,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
LEAVE_GL();
TRACE("Updating target %d\n", This->glDescription.target);
This->Flags |= SFLAG_INTEXTURE;
TRACE("Updated target %d\n", This->glDescription.target);
}
return WINED3D_OK;
}
/* Otherwise: System memory copy must be most up to date */
if(This->CKeyFlags & DDSD_CKSRCBLT) {
This->Flags |= SFLAG_GLCKEY;
@ -1841,6 +1840,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
if (!(This->Flags & SFLAG_DONOTFREE)) {
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL;
This->Flags &= ~SFLAG_INSYSMEM;
}
return WINED3D_OK;
@ -1876,11 +1876,14 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const ch
/* check to see if were a 'virtual' texture e.g. were not a pbuffer of texture were a back buffer*/
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapChain);
if (swapChain || (This->Flags & SFLAG_INPBUFFER)) { /* if were not a real texture then read the back buffer into a real texture*/
/* we don't want to interfere with the back buffer so read the data into a temporary texture and then save the data out of the temporary texture */
if (This->Flags & SFLAG_INDRAWABLE && !(This->Flags & SFLAG_INTEXTURE)) {
/* if were not a real texture then read the back buffer into a real texture */
/* we don't want to interfere with the back buffer so read the data into a temporary
* texture and then save the data out of the temporary texture
*/
GLint prevRead;
ENTER_GL();
FIXME("(%p) This surface needs to be locked before a snapshot can be taken\n", This);
TRACE("(%p) Reading render target into texture\n", This);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tmpTexture);
@ -1913,7 +1916,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const ch
glReadBuffer(prevRead);
LEAVE_GL();
} else { /* bind the real texture */
} else { /* bind the real texture, and make sure it up to date */
IWineD3DSurface_PreLoad(iface);
}
allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4);
@ -1988,25 +1991,13 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const ch
return WINED3D_OK;
}
HRESULT WINAPI IWineD3DSurfaceImpl_CleanDirtyRect(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
This->Flags &= ~SFLAG_DIRTY;
This->dirtyRect.left = This->currentDesc.Width;
This->dirtyRect.top = This->currentDesc.Height;
This->dirtyRect.right = 0;
This->dirtyRect.bottom = 0;
TRACE("(%p) : Dirty?%d, Rect:(%d,%d,%d,%d)\n", This, This->Flags & SFLAG_DIRTY ? 1 : 0, This->dirtyRect.left,
This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
return WINED3D_OK;
}
/**
* Slightly inefficient way to handle multiple dirty rects but it works :)
*/
extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DBaseTexture *baseTexture = NULL;
This->Flags |= SFLAG_DIRTY;
This->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
if (NULL != pDirtyRect) {
This->dirtyRect.left = min(This->dirtyRect.left, pDirtyRect->left);
This->dirtyRect.top = min(This->dirtyRect.top, pDirtyRect->top);
@ -2018,7 +2009,7 @@ extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, C
This->dirtyRect.right = This->currentDesc.Width;
This->dirtyRect.bottom = This->currentDesc.Height;
}
TRACE("(%p) : Dirty?%d, Rect:(%d,%d,%d,%d)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left,
TRACE("(%p) : Dirty: yes, Rect:(%d,%d,%d,%d)\n", This, This->dirtyRect.left,
This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
/* if the container is a basetexture then mark it dirty. */
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
@ -2275,6 +2266,9 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
}
glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName);
checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
/* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
Src->Flags &= ~SFLAG_INTEXTURE;
}
glReadBuffer(GL_BACK);
@ -2601,8 +2595,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL;
} else {
This->Flags |= SFLAG_GLDIRTY;
This->Flags &= ~SFLAG_INSYSMEM;
}
/* The texture is now most up to date - If the surface is a render target and has a drawable, this
* path is never entered
*/
This->Flags |= SFLAG_INTEXTURE;
return WINED3D_OK;
} else if(Src) {
@ -2739,7 +2737,16 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
LEAVE_GL();
/* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
This->Flags |= SFLAG_GLDIRTY;
This->Flags &= ~SFLAG_INSYSMEM;
/* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
* is outdated now
*/
if(dstSwapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
This->Flags |= SFLAG_INDRAWABLE;
This->Flags &= ~SFLAG_INTEXTURE;
} else {
This->Flags |= SFLAG_INTEXTURE;
}
return WINED3D_OK;
} else {
@ -2972,8 +2979,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) {
if(This->resource.format == WINED3DFMT_P8 ||
This->resource.format == WINED3DFMT_A8P8)
{
if(!This->Flags & SFLAG_INSYSMEM) {
FIXME("Palette changed with surface that does not have an up to date system memory copy\n");
}
TRACE("Dirtifying surface\n");
This->Flags |= SFLAG_DIRTY;
This->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
}
if(This->Flags & SFLAG_DIBSECTION) {
@ -3237,7 +3247,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
IWineD3DSurfaceImpl_UpdateOverlayZOrder,
IWineD3DSurfaceImpl_UpdateOverlay,
/* Internal use: */
IWineD3DSurfaceImpl_CleanDirtyRect,
IWineD3DSurfaceImpl_AddDirtyRect,
IWineD3DSurfaceImpl_LoadTexture,
IWineD3DSurfaceImpl_SaveSnapshot,

View file

@ -1600,7 +1600,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
IWineD3DSurfaceImpl_UpdateOverlayZOrder,
IWineD3DSurfaceImpl_UpdateOverlay,
/* Internal use: */
IWineD3DSurfaceImpl_CleanDirtyRect,
IWineD3DSurfaceImpl_AddDirtyRect,
IWineGDISurfaceImpl_LoadTexture,
IWineGDISurfaceImpl_SaveSnapshot,

View file

@ -177,6 +177,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
/* The cursor must have pow2 sizes */
cursor.pow2Width = cursor.currentDesc.Width;
cursor.pow2Height = cursor.currentDesc.Height;
/* The surface is in the texture */
cursor.Flags |= SFLAG_INTEXTURE;
/* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
* which is exactly what we want :-)
*/
@ -299,13 +301,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, WINED3DCLEAR_STENCIL|WINED3DCLEAR_ZBUFFER, 0x00, 1.0, 0);
}
if(!(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_GLDIRTY) ||
!(((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_GLDIRTY) ) {
if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM ||
((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) {
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */
IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
BOOL frontdirty = front->Flags & SFLAG_GLDIRTY;
BOOL backdirty = back->Flags & SFLAG_GLDIRTY;
BOOL frontuptodate = front->Flags & SFLAG_INSYSMEM;
BOOL backuptodate = back->Flags & SFLAG_INSYSMEM;
/* Flip the DC */
{
@ -349,10 +351,10 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
front->dib.client_memory = back->dib.client_memory;
back->dib.client_memory = tmp;
}
if(frontdirty) back->Flags |= SFLAG_GLDIRTY;
else back->Flags &= ~SFLAG_GLDIRTY;
if(backdirty) front->Flags |= SFLAG_GLDIRTY;
else front->Flags &= ~SFLAG_GLDIRTY;
if(frontuptodate) back->Flags |= SFLAG_INSYSMEM;
else back->Flags &= ~SFLAG_INSYSMEM;
if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
else front->Flags &= ~SFLAG_INSYSMEM;
}
TRACE("returning\n");

View file

@ -2508,7 +2508,7 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
* If the texture is dirty, or the part can't be used,
* re-position the part to load
*/
if(!(This->Flags & SFLAG_DIRTY)) {
if(This->Flags & SFLAG_INTEXTURE) {
if(This->glRect.left <= x1 && This->glRect.right >= x2 &&
This->glRect.top <= y1 && This->glRect.bottom >= x2 ) {
/* Ok, the rectangle is ok, re-use it */
@ -2516,12 +2516,12 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
} else {
/* Rectangle is not ok, dirtify the texture to reload it */
TRACE("Dirtifying texture to force reload\n");
This->Flags |= SFLAG_DIRTY;
This->Flags &= ~SFLAG_INTEXTURE;
}
}
/* Now if we are dirty(no else if!) */
if(This->Flags & SFLAG_DIRTY) {
if(!(This->Flags & SFLAG_INTEXTURE)) {
/* Set the new rectangle. Use the following strategy:
* 1) Use as big textures as possible.
* 2) Place the texture part in the way that the requested

View file

@ -1103,27 +1103,25 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *S
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
#define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for getdc */
#define SFLAG_DIRTY 0x00000008 /* Surface was locked by the app */
#define SFLAG_LOCKABLE 0x00000010 /* Surface can be locked */
#define SFLAG_DISCARD 0x00000020 /* ??? */
#define SFLAG_LOCKED 0x00000040 /* Surface is locked atm */
#define SFLAG_INTEXTURE 0x00000080 /* ??? */
#define SFLAG_INPBUFFER 0x00000100 /* ??? */
#define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */
#define SFLAG_DISCARD 0x00000010 /* ??? */
#define SFLAG_LOCKED 0x00000020 /* Surface is locked atm */
#define SFLAG_INTEXTURE 0x00000040 /* The GL texture contains the newest surface content */
#define SFLAG_INDRAWABLE 0x00000080 /* The gl drawable contains the most up to date data */
#define SFLAG_INSYSMEM 0x00000100 /* The system memory copy is most up to date */
#define SFLAG_NONPOW2 0x00000200 /* Surface sizes are not a power of 2 */
#define SFLAG_DYNLOCK 0x00000400 /* Surface is often locked by the app */
#define SFLAG_DYNCHANGE 0x00000C00 /* Surface contents are changed very often, implies DYNLOCK */
#define SFLAG_DCINUSE 0x00001000 /* Set between GetDC and ReleaseDC calls */
#define SFLAG_GLDIRTY 0x00002000 /* The opengl texture is more up to date than the surface mem */
#define SFLAG_LOST 0x00004000 /* Surface lost flag for DDraw */
#define SFLAG_FORCELOAD 0x00008000 /* To force PreLoading of a scratch cursor */
#define SFLAG_USERPTR 0x00010000 /* The application allocated the memory for this surface */
#define SFLAG_GLCKEY 0x00020000 /* The gl texture was created with a color key */
#define SFLAG_LOST 0x00002000 /* Surface lost flag for DDraw */
#define SFLAG_FORCELOAD 0x00004000 /* To force PreLoading of a scratch cursor */
#define SFLAG_USERPTR 0x00008000 /* The application allocated the memory for this surface */
#define SFLAG_GLCKEY 0x00010000 /* The gl texture was created with a color key */
/* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL
* SFLAG_CONVERTED: Converting the data back would take too long
* SFLAG_DIBSECTION: The dib code manages the memory
* SFLAG_DIRTY: GL surface isn't up to date
* SFLAG_LOCKED: The app requires access to the surface data
* SFLAG_DYNLOCK: Avoid freeing the data for performance
* SFLAG_DYNCHANGE: Same reason as DYNLOCK
@ -1131,7 +1129,6 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *S
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
SFLAG_CONVERTED | \
SFLAG_DIBSECTION | \
SFLAG_DIRTY | \
SFLAG_LOCKED | \
SFLAG_DYNLOCK | \
SFLAG_DYNCHANGE | \

View file

@ -1108,7 +1108,6 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD Flags, IWineD3DSurface *Ref) PURE;
STDMETHOD(UpdateOverlay)(THIS_ RECT *SrcRect, IWineD3DSurface *DstSurface, RECT *DstRect, DWORD Flags, WINEDDOVERLAYFX *FX);
/* Internally used methods */
STDMETHOD(CleanDirtyRect)(THIS) PURE;
STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pRect) PURE;
STDMETHOD(LoadTexture)(THIS) PURE;
STDMETHOD(SaveSnapshot)(THIS_ const char *filename) PURE;
@ -1162,7 +1161,6 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
#define IWineD3DSurface_UpdateOverlayZOrder(p, a, b) (p)->lpVtbl->UpdateOverlayZOrder(p, a, b)
#define IWineD3DSurface_UpdateOverlay(p, a, b, c, d, e) (p)->lpVtbl->UpdateOverlay(p, a, b, c, d, e)
/*** IWineD3DSurface (Internal, no d3d mapping) methods ***/
#define IWineD3DSurface_CleanDirtyRect(p) (p)->lpVtbl->CleanDirtyRect(p)
#define IWineD3DSurface_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a)
#define IWineD3DSurface_LoadTexture(p) (p)->lpVtbl->LoadTexture(p)
#define IWineD3DSurface_SaveSnapshot(p,a) (p)->lpVtbl->SaveSnapshot(p,a)