ddraw: Support using an application-provided surface pointer.
This commit is contained in:
parent
aff9f4c1ed
commit
06106e2810
|
@ -1790,13 +1790,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
|
|||
}
|
||||
}
|
||||
|
||||
/* Get the surface parameters */
|
||||
if ( pDDSD->dwFlags & DDSD_LPSURFACE)
|
||||
{
|
||||
ERR("(%p) Using a passed surface pointer is not yet supported\n", This);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* Get the correct wined3d usage */
|
||||
if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
|
||||
DDSCAPS_BACKBUFFER |
|
||||
|
@ -1995,6 +1988,16 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
|
|||
DDCKEY_SRCBLT,
|
||||
&pDDSD->ddckCKSrcBlt);
|
||||
}
|
||||
if ( pDDSD->dwFlags & DDSD_LPSURFACE)
|
||||
{
|
||||
hr = IWineD3DSurface_SetMem((*ppSurf)->WineD3DSurface, pDDSD->lpSurface);
|
||||
if(hr != WINED3D_OK)
|
||||
{
|
||||
/* No need for a trace here, wined3d does that for us */
|
||||
IDirectDrawSurface7_Release(ICOM_INTERFACE((*ppSurf), IDirectDrawSurface7));
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
|
|
@ -1933,6 +1933,15 @@ IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7 *iface,
|
|||
DDCKEY_SRCBLT,
|
||||
&DDSD->ddckCKSrcBlt);
|
||||
}
|
||||
if (DDSD->dwFlags & DDSD_LPSURFACE)
|
||||
{
|
||||
hr = IWineD3DSurface_SetMem(This->WineD3DSurface, DDSD->lpSurface);
|
||||
if(hr != WINED3D_OK)
|
||||
{
|
||||
/* No need for a trace here, wined3d does that for us */
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
This->surface_desc = *DDSD;
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
|
|||
This->dib.bitmap_data = NULL;
|
||||
This->resource.allocatedMemory = NULL;
|
||||
}
|
||||
IWineD3DSurface_SetMem(iface, NULL);
|
||||
|
||||
IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
|
||||
if(iface == device->ddraw_primary)
|
||||
|
@ -1161,6 +1162,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
|
|||
|
||||
TRACE("(%p)->(%p)\n",This,pHDC);
|
||||
|
||||
if(This->Flags & SFLAG_USERPTR) {
|
||||
ERR("Not supported on surfaces with an application-provided surfaces\n");
|
||||
return DDERR_NODC;
|
||||
}
|
||||
|
||||
/* Give more detailed info for ddraw */
|
||||
if (This->Flags & SFLAG_DCINUSE)
|
||||
return DDERR_DCALREADYCREATED;
|
||||
|
@ -2104,6 +2110,49 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORM
|
|||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
|
||||
|
||||
/* Render targets depend on their hdc, and we can't create a hdc on a user pointer */
|
||||
if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
|
||||
ERR("Not supported on render targets\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if(This->Flags & (SFLAG_LOCKED | SFLAG_DCINUSE)) {
|
||||
WARN("Surface is locked or the HDC is in use\n");
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if(Mem && Mem != This->resource.allocatedMemory) {
|
||||
|
||||
/* Do I have to copy the old surface content? */
|
||||
if(This->Flags & SFLAG_DIBSECTION) {
|
||||
/* Release the DC. No need to hold the critical section for the update
|
||||
* Thread because this thread runs only on front buffers, but this method
|
||||
* fails for render targets in the check above.
|
||||
*/
|
||||
SelectObject(This->hDC, This->dib.holdbitmap);
|
||||
DeleteDC(This->hDC);
|
||||
/* Release the DIB section */
|
||||
DeleteObject(This->dib.DIBsection);
|
||||
This->dib.bitmap_data = NULL;
|
||||
This->resource.allocatedMemory = NULL;
|
||||
This->hDC = NULL;
|
||||
This->Flags &= ~SFLAG_DIBSECTION;
|
||||
} else if(!(This->Flags & SFLAG_USERPTR)) {
|
||||
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
|
||||
}
|
||||
This->resource.allocatedMemory = Mem;
|
||||
This->Flags |= SFLAG_USERPTR;
|
||||
} else if(This->Flags & SFLAG_USERPTR) {
|
||||
/* Lockrect and GetDC will re-create the dib section and allocated memory */
|
||||
This->resource.allocatedMemory = NULL;
|
||||
This->Flags &= ~SFLAG_USERPTR;
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* TODO: replace this function with context management routines */
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_SetPBufferState(IWineD3DSurface *iface, BOOL inPBuffer, BOOL inTexture) {
|
||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||
|
@ -2975,6 +3024,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
|
|||
IWineD3DSurfaceImpl_RealizePalette,
|
||||
IWineD3DSurfaceImpl_SetColorKey,
|
||||
IWineD3DSurfaceImpl_GetPitch,
|
||||
IWineD3DSurfaceImpl_SetMem,
|
||||
/* Internal use: */
|
||||
IWineD3DSurfaceImpl_CleanDirtyRect,
|
||||
IWineD3DSurfaceImpl_AddDirtyRect,
|
||||
|
|
|
@ -178,6 +178,18 @@ IWineGDISurfaceImpl_LockRect(IWineD3DSurface *iface,
|
|||
TRACE("(%p) : rect@%p flags(%08lx), 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;
|
||||
}
|
||||
|
||||
pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
|
||||
|
||||
if (NULL == pRect)
|
||||
|
@ -1570,6 +1582,7 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
|
|||
IWineD3DSurfaceImpl_RealizePalette,
|
||||
IWineD3DSurfaceImpl_SetColorKey,
|
||||
IWineD3DSurfaceImpl_GetPitch,
|
||||
IWineD3DSurfaceImpl_SetMem,
|
||||
/* Internal use: */
|
||||
IWineD3DSurfaceImpl_CleanDirtyRect,
|
||||
IWineD3DSurfaceImpl_AddDirtyRect,
|
||||
|
|
|
@ -929,6 +929,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC);
|
|||
HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC);
|
||||
DWORD WINAPI IWineD3DSurfaceImpl_GetPitch(IWineD3DSurface *iface);
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
|
||||
HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem);
|
||||
|
||||
/* Surface flags: */
|
||||
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
|
||||
|
@ -948,7 +949,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
|
|||
#define SFLAG_GLDIRTY 0x00004000 /* The opengl texture is more up to date than the surface mem */
|
||||
#define SFLAG_LOST 0x00008000 /* Surface lost flag for DDraw */
|
||||
#define SFLAG_FORCELOAD 0x00010000 /* To force PreLoading of a scratch cursor */
|
||||
|
||||
#define SFLAG_USERPTR 0x00020000 /* The application allocated the memory for this surface */
|
||||
|
||||
/* In some conditions the surface memory must not be freed:
|
||||
* SFLAG_OVERSIZE: Not all data can be kept in GL
|
||||
|
@ -967,7 +968,8 @@ HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface);
|
|||
SFLAG_LOCKED | \
|
||||
SFLAG_ACTIVELOCK | \
|
||||
SFLAG_DYNLOCK | \
|
||||
SFLAG_DYNCHANGE )
|
||||
SFLAG_DYNCHANGE | \
|
||||
SFLAG_USERPTR)
|
||||
|
||||
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]);
|
||||
|
||||
|
|
|
@ -1130,6 +1130,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
|
|||
STDMETHOD(RealizePalette)(THIS) PURE;
|
||||
STDMETHOD(SetColorKey)(THIS_ DWORD Flags, DDCOLORKEY *CKey) PURE;
|
||||
STDMETHOD_(DWORD,GetPitch)(THIS) PURE;
|
||||
STDMETHOD(SetMem)(THIS_ void *mem) PURE;
|
||||
/* Internally used methods */
|
||||
STDMETHOD(CleanDirtyRect)(THIS) PURE;
|
||||
STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pRect) PURE;
|
||||
|
@ -1181,6 +1182,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource)
|
|||
#define IWineD3DSurface_RealizePalette(p) (p)->lpVtbl->RealizePalette(p)
|
||||
#define IWineD3DSurface_SetColorKey(p, a, b) (p)->lpVtbl->SetColorKey(p, a, b)
|
||||
#define IWineD3DSurface_GetPitch(p) (p)->lpVtbl->GetPitch(p)
|
||||
#define IWineD3DSurface_SetMem(p, a) (p)->lpVtbl->SetMem(p, a)
|
||||
/*** IWineD3DSurface (Internal, no d3d mapping) methods ***/
|
||||
#define IWineD3DSurface_CleanDirtyRect(p) (p)->lpVtbl->CleanDirtyRect(p)
|
||||
#define IWineD3DSurface_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a)
|
||||
|
|
Loading…
Reference in New Issue