wined3d: Move a part of LockRect to the base class.
This commit is contained in:
parent
2a09716c75
commit
a175e7b68e
|
@ -690,41 +690,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||
|
||||
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
||||
|
||||
/* This is also done in the base class, but we have to verify this before loading any data from
|
||||
* gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag
|
||||
* may interfere, and all other bad things may happen
|
||||
*/
|
||||
if (This->Flags & SFLAG_LOCKED) {
|
||||
WARN("Surface is already locked, returning D3DERR_INVALIDCALL\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
if (!(This->Flags & SFLAG_LOCKABLE)) {
|
||||
/* Note: UpdateTextures calls CopyRects which calls this routine to populate the
|
||||
texture regions, and since the destination is an unlockable region we need
|
||||
to tolerate this */
|
||||
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
||||
/*return WINED3DERR_INVALIDCALL; */
|
||||
}
|
||||
|
||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
||||
|
||||
/* Mark the surface locked */
|
||||
This->Flags |= SFLAG_LOCKED;
|
||||
|
||||
/* Calculate the correct start address to report */
|
||||
if (NULL == pRect) {
|
||||
This->lockedRect.left = 0;
|
||||
This->lockedRect.top = 0;
|
||||
This->lockedRect.right = This->currentDesc.Width;
|
||||
This->lockedRect.bottom = This->currentDesc.Height;
|
||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n", &This->lockedRect, This->lockedRect.left, This->lockedRect.top, This->lockedRect.right, This->lockedRect.bottom);
|
||||
} else {
|
||||
This->lockedRect.left = pRect->left;
|
||||
This->lockedRect.top = pRect->top;
|
||||
This->lockedRect.right = pRect->right;
|
||||
This->lockedRect.bottom = pRect->bottom;
|
||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
||||
}
|
||||
|
||||
if (This->Flags & SFLAG_NONPOW2) {
|
||||
TRACE("Locking non-power 2 texture\n");
|
||||
}
|
||||
|
||||
if (Flags & WINED3DLOCK_DISCARD) {
|
||||
/* Set SFLAG_INSYSMEM, so we'll never try to download the data from the texture. */
|
||||
|
@ -744,15 +717,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||
*/
|
||||
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
|
||||
if(swapchain || iface == myDevice->render_targets[0]) {
|
||||
RECT *read_rect;
|
||||
const RECT *pass_rect = pRect;
|
||||
|
||||
if(This->lockedRect.left == 0 &&
|
||||
This->lockedRect.top == 0 &&
|
||||
This->lockedRect.right == This->currentDesc.Width &&
|
||||
This->lockedRect.bottom == This->currentDesc.Height) {
|
||||
read_rect = NULL;
|
||||
} else {
|
||||
read_rect = &This->lockedRect;
|
||||
/* IWineD3DSurface_LoadLocation does not check if the rectangle specifies the full surfaces
|
||||
* because most caller functions do not need that. So do that here
|
||||
*/
|
||||
if(pRect &&
|
||||
pRect->top == 0 &&
|
||||
pRect->left == 0 &&
|
||||
pRect->right == This->currentDesc.Width &&
|
||||
pRect->bottom == This->currentDesc.Height) {
|
||||
pass_rect = NULL;
|
||||
}
|
||||
|
||||
switch(wined3d_settings.rendertargetlock_mode) {
|
||||
|
@ -771,7 +746,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
|||
case RTL_AUTO:
|
||||
case RTL_READDRAW:
|
||||
case RTL_READTEX:
|
||||
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, read_rect);
|
||||
IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pRect);
|
||||
break;
|
||||
|
||||
case RTL_DISABLE:
|
||||
|
@ -828,27 +803,6 @@ lock_end:
|
|||
LEAVE_GL();
|
||||
}
|
||||
|
||||
/* Calculate the correct start address to report */
|
||||
if (NULL == pRect) {
|
||||
pLockedRect->pBits = This->resource.allocatedMemory;
|
||||
} else {
|
||||
/* DXTn textures are based on compressed blocks of 4x4 pixels, each
|
||||
* 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
|
||||
* slightly different meaning compared to regular textures. For DXTn
|
||||
* textures Pitch is the size of a row of blocks, 4 high and "width"
|
||||
* long. The x offset is calculated differently as well, since moving 4
|
||||
* pixels to the right actually moves an entire 4x4 block to right, ie
|
||||
* 16 bytes (8 in case of DXT1). */
|
||||
if (This->resource.format == WINED3DFMT_DXT1) {
|
||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
|
||||
} else if (This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3
|
||||
|| This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) {
|
||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
|
||||
} else {
|
||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
|
||||
/* Don't dirtify */
|
||||
} else {
|
||||
|
@ -869,9 +823,7 @@ lock_end:
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch,
|
||||
This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
|
||||
return WINED3D_OK;
|
||||
return IWineD3DBaseSurfaceImpl_LockRect(iface, pLockedRect, pRect, Flags);
|
||||
}
|
||||
|
||||
static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
|
||||
|
|
|
@ -1568,3 +1568,80 @@ error:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags)
|
||||
{
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||
|
||||
/* Already locked? */
|
||||
if(This->Flags & SFLAG_LOCKED)
|
||||
{
|
||||
ERR("(%p) Surface already locked\n", This);
|
||||
/* What should I return here? */
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (!(This->Flags & SFLAG_LOCKABLE))
|
||||
{
|
||||
/* This is some GL specific thing, see the OpenGL version of
|
||||
* this method, but check for the flag and write a trace
|
||||
*/
|
||||
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
||||
}
|
||||
|
||||
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n",
|
||||
This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
||||
|
||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
||||
|
||||
if (NULL == pRect)
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory;
|
||||
This->lockedRect.left = 0;
|
||||
This->lockedRect.top = 0;
|
||||
This->lockedRect.right = This->currentDesc.Width;
|
||||
This->lockedRect.bottom = This->currentDesc.Height;
|
||||
|
||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||
&This->lockedRect, This->lockedRect.left, This->lockedRect.top,
|
||||
This->lockedRect.right, This->lockedRect.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||
pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
||||
|
||||
/* DXTn textures are based on compressed blocks of 4x4 pixels, each
|
||||
* 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
|
||||
* slightly different meaning compared to regular textures. For DXTn
|
||||
* textures Pitch is the size of a row of blocks, 4 high and "width"
|
||||
* long. The x offset is calculated differently as well, since moving 4
|
||||
* pixels to the right actually moves an entire 4x4 block to right, ie
|
||||
* 16 bytes (8 in case of DXT1). */
|
||||
if (This->resource.format == WINED3DFMT_DXT1)
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
|
||||
}
|
||||
else if (This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
|
||||
This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5)
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory +
|
||||
(pLockedRect->Pitch * pRect->top) +
|
||||
(pRect->left * This->bytesPerPixel);
|
||||
}
|
||||
This->lockedRect.left = pRect->left;
|
||||
This->lockedRect.top = pRect->top;
|
||||
This->lockedRect.right = pRect->right;
|
||||
This->lockedRect.bottom = pRect->bottom;
|
||||
}
|
||||
|
||||
/* No dirtifying is needed for this surface implementation */
|
||||
TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
|
||||
|
||||
This->Flags |= SFLAG_LOCKED;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
|
|
@ -205,80 +205,15 @@ IWineGDISurfaceImpl_LockRect(IWineD3DSurface *iface,
|
|||
{
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||
|
||||
/* Already locked? */
|
||||
if(This->Flags & SFLAG_LOCKED)
|
||||
{
|
||||
ERR("(%p) Surface already locked\n", This);
|
||||
/* What should I return here? */
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (!(This->Flags & SFLAG_LOCKABLE))
|
||||
{
|
||||
/* This is some GL specific thing, see the OpenGL version of
|
||||
* this method, but check for the flag and write a trace
|
||||
*/
|
||||
TRACE("Warning: trying to lock unlockable surf@%p\n", This);
|
||||
}
|
||||
|
||||
TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n",
|
||||
This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
|
||||
|
||||
if(!This->resource.allocatedMemory) {
|
||||
HDC hdc;
|
||||
HRESULT hr;
|
||||
/* This happens on gdi surfaces if the application set a user pointer and resets it.
|
||||
* Recreate the DIB section
|
||||
*/
|
||||
hr = IWineD3DSurface_GetDC(iface, &hdc); /* will recursively call lockrect, do not set the LOCKED flag to this line */
|
||||
if(hr != WINED3D_OK) return hr;
|
||||
hr = IWineD3DSurface_ReleaseDC(iface, hdc);
|
||||
if(hr != WINED3D_OK) return hr;
|
||||
IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
|
||||
This->resource.allocatedMemory = This->dib.bitmap_data;
|
||||
}
|
||||
|
||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
||||
|
||||
if (NULL == pRect)
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory;
|
||||
This->lockedRect.left = 0;
|
||||
This->lockedRect.top = 0;
|
||||
This->lockedRect.right = This->currentDesc.Width;
|
||||
This->lockedRect.bottom = This->currentDesc.Height;
|
||||
|
||||
TRACE("Locked Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||
&This->lockedRect, This->lockedRect.left, This->lockedRect.top,
|
||||
This->lockedRect.right, This->lockedRect.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
|
||||
pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
|
||||
|
||||
if (This->resource.format == WINED3DFMT_DXT1)
|
||||
{
|
||||
/* DXT1 is half byte per pixel */
|
||||
pLockedRect->pBits = This->resource.allocatedMemory +
|
||||
(pLockedRect->Pitch * pRect->top) +
|
||||
((pRect->left * This->bytesPerPixel / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
pLockedRect->pBits = This->resource.allocatedMemory +
|
||||
(pLockedRect->Pitch * pRect->top) +
|
||||
(pRect->left * This->bytesPerPixel);
|
||||
}
|
||||
This->lockedRect.left = pRect->left;
|
||||
This->lockedRect.top = pRect->top;
|
||||
This->lockedRect.right = pRect->right;
|
||||
This->lockedRect.bottom = pRect->bottom;
|
||||
}
|
||||
|
||||
/* No dirtifying is needed for this surface implementation */
|
||||
TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
|
||||
|
||||
This->Flags |= SFLAG_LOCKED;
|
||||
return WINED3D_OK;
|
||||
return IWineD3DBaseSurfaceImpl_LockRect(iface, pLockedRect, pRect, Flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
@ -1163,10 +1163,10 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D
|
|||
HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface);
|
||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter);
|
||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans);
|
||||
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
|
||||
|
||||
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface);
|
||||
|
||||
|
||||
/* Surface flags: */
|
||||
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
|
||||
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */
|
||||
|
|
Loading…
Reference in New Issue