Stefan Dösinger : wined3d: Move sysmem-> drawable copying to LoadLocation.

Alexandre Julliard julliard at winehq.org
Mon Oct 29 08:34:47 CDT 2007


Module: wine
Branch: master
Commit: 2a859706317078264fd926a0e884563dddb1bbca
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2a859706317078264fd926a0e884563dddb1bbca

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Sep 21 19:55:06 2007 +0200

wined3d: Move sysmem->drawable copying to LoadLocation.

---

 dlls/wined3d/surface.c |  138 ++++++++++++++++++++----------------------------
 1 files changed, 58 insertions(+), 80 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 20e95aa..ff821e0 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1072,57 +1072,11 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
     return;
 }
 
-static void flush_to_framebuffer_texture(IWineD3DSurfaceImpl *This) {
-    float glTexCoord[4];
-
-    glTexCoord[0] = (float) This->lockedRect.left   / (float) This->pow2Width; /* left */
-    glTexCoord[1] = (float) This->lockedRect.right  / (float) This->pow2Width; /* right */
-    glTexCoord[2] = (float) This->lockedRect.top    / (float) This->pow2Height; /* top */
-    glTexCoord[3] = (float) This->lockedRect.bottom / (float) This->pow2Height; /* bottom */
-
-    IWineD3DSurface_PreLoad((IWineD3DSurface *) This);
-
-    ENTER_GL();
-
-    glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
-    checkGLcall("glEnable glBindTexture");
-
-    /* No filtering for blts */
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    checkGLcall("glTexParameteri");
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    checkGLcall("glTexParameteri");
-
-    /* Start drawing a quad */
-    glBegin(GL_QUADS);
-
-    glColor3d(1.0f, 1.0f, 1.0f);
-    glTexCoord2f(glTexCoord[0], glTexCoord[2]);
-    glVertex3f(This->lockedRect.left, This->lockedRect.top, 0.0);
-
-    glTexCoord2f(glTexCoord[0], glTexCoord[3]);
-    glVertex3f(This->lockedRect.left, This->lockedRect.bottom, 0.0);
-
-    glTexCoord2f(glTexCoord[1], glTexCoord[3]);
-    glVertex3d(This->lockedRect.right, This->lockedRect.bottom, 0.0);
-
-    glTexCoord2f(glTexCoord[1], glTexCoord[2]);
-    glVertex3f(This->lockedRect.right, This->lockedRect.top, 0.0);
-
-    glEnd();
-    checkGLcall("glEnd");
-
-    /* Unbind the texture */
-    glBindTexture(GL_TEXTURE_2D, 0);
-    checkGLcall("glEnable glBindTexture");
-
-    LEAVE_GL();
-}
-
 static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
     IWineD3DSwapChainImpl *swapchain = NULL;
+    BOOL fullsurface;
 
     if (!(This->Flags & SFLAG_LOCKED)) {
         WARN("trying to Unlock an unlocked surf@%p\n", This);
@@ -1160,53 +1114,47 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
             goto unlock_end;
         }
 
-        /* Activate the correct context for the render target */
-        ActivateContext(myDevice, iface, CTXUSAGE_BLIT);
-        ENTER_GL();
-
-        if(!swapchain) {
-            /* Primary offscreen render target */
-            TRACE("Offscreen render target\n");
-            glDrawBuffer(myDevice->offscreenBuffer);
-            checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
+        if(This->dirtyRect.left   == 0 &&
+           This->dirtyRect.top    == 0 &&
+           This->dirtyRect.right  == This->currentDesc.Width &&
+           This->dirtyRect.bottom == This->currentDesc.Height) {
+            fullsurface = TRUE;
         } else {
-            GLenum buffer = surface_get_gl_buffer(iface, (IWineD3DSwapChain *)swapchain);
-            TRACE("Unlocking %#x buffer\n", buffer);
-            glDrawBuffer(buffer);
-            checkGLcall("glDrawBuffer");
-
-            IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+            /* TODO: Proper partial rectangle tracking */
+            fullsurface = FALSE;
+            This->Flags |= SFLAG_INSYSMEM;
         }
 
         switch(wined3d_settings.rendertargetlock_mode) {
+            case RTL_READTEX:
+            case RTL_TEXTEX:
+                /* drop through */
+                FIXME("Render target unlocking using textures temporarily disabled\n");
+#if 0
+                IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */);
+#endif
             case RTL_AUTO:
             case RTL_READDRAW:
             case RTL_TEXDRAW:
-                flush_to_framebuffer_drawpixels(This);
-                break;
-
-            case RTL_READTEX:
-            case RTL_TEXTEX:
-                flush_to_framebuffer_texture(This);
+                IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, fullsurface ? NULL : &This->dirtyRect);
                 break;
         }
-        if(!swapchain) {
-            glDrawBuffer(myDevice->offscreenBuffer);
-            checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
-        } else if(swapchain->backBuffer) {
-            glDrawBuffer(GL_BACK);
-            checkGLcall("glDrawBuffer(GL_BACK)");
-        } else {
-            glDrawBuffer(GL_FRONT);
-            checkGLcall("glDrawBuffer(GL_FRONT)");
+
+        if(!fullsurface) {
+            /* Partial rectangle tracking is not commonly implemented, it is only done for render targets. Overwrite
+             * the flags to bring them back into a sane state. INSYSMEM was set before to tell LoadLocation where
+             * to read the rectangle from. Indrawable is set because all modifications from the partial sysmem copy
+             * are written back to the drawable, thus the surface is merged again in the drawable. The sysmem copy is
+             * not fully up to date because only a subrectangle was read in LockRect.
+             */
+            This->Flags &= ~SFLAG_INSYSMEM;
+            This->Flags |= SFLAG_INDRAWABLE;
         }
-        LEAVE_GL();
 
         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 {
@@ -3632,7 +3580,37 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
         if(This->Flags & SFLAG_INTEXTURE) {
             /* Blit texture to drawable */
         } else {
-            /* Load drawable from sysmem */
+            /* Activate the correct context for the render target */
+            ActivateContext(myDevice, iface, CTXUSAGE_BLIT);
+            ENTER_GL();
+
+            IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
+            if(!swapchain) {
+                /* Primary offscreen render target */
+                TRACE("Offscreen render target\n");
+                glDrawBuffer(myDevice->offscreenBuffer);
+                checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
+            } else {
+                GLenum buffer = surface_get_gl_buffer(iface, (IWineD3DSwapChain *)swapchain);
+                TRACE("Unlocking %#x buffer\n", buffer);
+                glDrawBuffer(buffer);
+                checkGLcall("glDrawBuffer");
+
+                IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+            }
+
+            flush_to_framebuffer_drawpixels(This);
+            if(!swapchain) {
+                glDrawBuffer(myDevice->offscreenBuffer);
+                checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
+            } else if(swapchain->backBuffer) {
+                glDrawBuffer(GL_BACK);
+                checkGLcall("glDrawBuffer(GL_BACK)");
+            } else {
+                glDrawBuffer(GL_FRONT);
+                checkGLcall("glDrawBuffer(GL_FRONT)");
+            }
+            LEAVE_GL();
         }
     } else /* if(flag == SFLAG_INTEXTURE) */ {
         if(This->Flags & SFLAG_INDRAWABLE) {




More information about the wine-cvs mailing list