Hi,
I have a patch which fixes the performance problems introduced with
c0782603d09807c6ca506948bb4a814a73430184 . I am sure that the patch is
correct, but I have the bad feeling that it brings up a few other bugs, so I
send it to wine-devel for testing first.
It only reallocates surfaces when they are either new or the description was
changed.
Thanks,
Stefan
------------------------------------------------------------------------
From 1b63bacd9e38ab514917aaa61c3abf0a2eca0896 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <[EMAIL PROTECTED]>
Date: Sun, 22 Apr 2007 02:02:29 +0200
Subject: [PATCH] WineD3D: Do not allocate surfaces unless needed
---
dlls/wined3d/surface.c | 20 ++++++++++++++++----
dlls/wined3d/wined3d_private.h | 1 +
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 4067ac8..909ee84 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -236,6 +236,8 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl
*This, GLenum internal,
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
}
LEAVE_GL();
+
+ This->Flags |= SFLAG_ALLOCATED;
}
/* In D3D the depth stencil dimensions have to be greater than or equal to the
@@ -556,6 +558,7 @@ void WINAPI
IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT te
}
This->glDescription.textureName = textureName;
This->glDescription.target = target;
+ This->Flags &= ~SFLAG_ALLOCATED;
}
void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription) {
@@ -1903,8 +1906,10 @@ static HRESULT WINAPI
IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
glReadBuffer(This->resource.wineD3DDevice->offscreenBuffer);
vcheckGLcall("glReadBuffer");
- surface_allocate_surface(This, internal, This->pow2Width,
- This->pow2Height, format, type);
+ if(!(This->Flags & SFLAG_ALLOCATED)) {
+ surface_allocate_surface(This, internal, This->pow2Width,
+ This->pow2Height, format, type);
+ }
glCopyTexSubImage2D(This->glDescription.target,
This->glDescription.level,
@@ -1969,7 +1974,9 @@ static HRESULT WINAPI
IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
TRACE("non power of two support\n");
- surface_allocate_surface(This, internal, This->pow2Width,
This->pow2Height, format, type);
+ if(!(This->Flags & SFLAG_ALLOCATED)) {
+ surface_allocate_surface(This, internal, This->pow2Width,
This->pow2Height, format, type);
+ }
if (mem) {
surface_upload_data(This, This->currentDesc.Width,
This->currentDesc.Height, format, type, mem);
}
@@ -1977,7 +1984,9 @@ static HRESULT WINAPI
IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
/* When making the realloc conditional, keep in mind that
GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory
* changed. So also keep track of memory changes. In this case the
texture has to be reallocated
*/
- surface_allocate_surface(This, internal, This->glRect.right -
This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
+ if(!(This->Flags & SFLAG_ALLOCATED)) {
+ surface_allocate_surface(This, internal, This->glRect.right -
This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
+ }
if (mem) {
surface_upload_data(This, This->glRect.right - This->glRect.left,
This->glRect.bottom - This->glRect.top, format, type, mem);
}
@@ -2241,6 +2250,7 @@ HRESULT WINAPI
IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORM
}
This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;
+ This->Flags &= ~SFLAG_ALLOCATED;
This->resource.format = format;
@@ -2291,6 +2301,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
/* For client textures opengl has to be notified */
if(This->Flags & SFLAG_CLIENT) {
+ This->Flags &= ~SFLAG_ALLOCATED;
IWineD3DSurface_PreLoad(iface);
/* And hope that the app behaves correctly and did not free the
old surface memory before setting a new pointer */
}
@@ -2303,6 +2314,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface
*iface, void *Mem) {
This->Flags &= ~SFLAG_USERPTR;
if(This->Flags & SFLAG_CLIENT) {
+ This->Flags &= ~SFLAG_ALLOCATED;
/* This respecifies an empty texture and opengl knows that the old
memory is gone */
IWineD3DSurface_PreLoad(iface);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3de938a..835a7ec 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1131,6 +1131,7 @@ HRESULT WINAPI
IWineD3DSurfaceImpl_UpdateOverlay(IWineD3DSurface *iface, RECT *S
#define SFLAG_USERPTR 0x00004000 /* The application allocated the memory
for this surface */
#define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a
color key */
#define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on
that texture */
+#define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this
surface */
/* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL
------------------------------------------------------------------------