Stefan Dösinger : wined3d: A function for checking if a surface is offscreen.

Alexandre Julliard julliard at winehq.org
Mon Dec 7 10:26:18 CST 2009


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Dec  6 15:45:46 2009 +0100

wined3d: A function for checking if a surface is offscreen.

---

 dlls/wined3d/device.c          |    8 +++---
 dlls/wined3d/surface.c         |   58 ++++++++++++++++++++++++----------------
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6ac60f1..12003d6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5676,7 +5676,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
     IWineD3DSwapChain *swapchain;
 
     swapchain = get_swapchain(surface);
-    if (swapchain) {
+    if (!surface_is_offscreen(surface)) {
         GLenum buffer;
 
         TRACE("Surface %p is onscreen\n", surface);
@@ -5699,7 +5699,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
     if (rect) {
         glEnable(GL_SCISSOR_TEST);
-        if(!swapchain) {
+        if(surface_is_offscreen(surface)) {
             glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1);
         } else {
             glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2,
@@ -6088,7 +6088,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
 
     gl_info = context->gl_info;
 
-    if (src_swapchain) {
+    if (!surface_is_offscreen(src_surface)) {
         GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
 
         TRACE("Source surface %p is onscreen\n", src_surface);
@@ -6126,7 +6126,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     LEAVE_GL();
 
     /* Attach dst surface to dst fbo */
-    if (dst_swapchain) {
+    if (!surface_is_offscreen(dst_surface)) {
         GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
 
         TRACE("Destination surface %p is onscreen\n", dst_surface);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 1463dd4..7c4551b 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -923,7 +923,6 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
 
 /* Read the framebuffer back into the surface */
 static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) {
-    IWineD3DSwapChainImpl *swapchain;
     IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
     struct wined3d_context *context;
     BYTE *mem;
@@ -959,16 +958,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
      * There is no need to keep track of the current read buffer or reset it, every part of the code
      * that reads sets the read buffer as desired.
      */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    if (surface_is_offscreen((IWineD3DSurface *) This))
     {
-        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain);
-        TRACE("Locking %#x buffer\n", buffer);
-        glReadBuffer(buffer);
-        checkGLcall("glReadBuffer");
-
-        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
-        srcIsUpsideDown = FALSE;
-    } else {
         /* Locking the primary render target which is not on a swapchain(=offscreen render target).
          * Read from the back buffer
          */
@@ -976,6 +967,15 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
         glReadBuffer(myDevice->offscreenBuffer);
         srcIsUpsideDown = TRUE;
     }
+    else
+    {
+        /* Onscreen surfaces are always part of a swapchain */
+        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *) This->container);
+        TRACE("Locking %#x buffer\n", buffer);
+        glReadBuffer(buffer);
+        checkGLcall("glReadBuffer");
+        srcIsUpsideDown = FALSE;
+    }
 
     /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */
     if(!rect) {
@@ -1770,7 +1770,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
         *internal = glDesc->glGammaInternal;
     }
     else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET
-            && !(This->Flags & SFLAG_SWAPCHAIN))
+            && surface_is_offscreen((IWineD3DSurface *) This))
     {
         *internal = glDesc->rtInternal;
     } else {
@@ -3102,7 +3102,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
     /* Bind the target texture */
     glBindTexture(This->texture_target, This->texture_name);
     checkGLcall("glBindTexture");
-    if(!swapchain) {
+    if(surface_is_offscreen(SrcSurface)) {
         TRACE("Reading from an offscreen target\n");
         upsidedown = !upsidedown;
         glReadBuffer(myDevice->offscreenBuffer);
@@ -3241,12 +3241,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
         Src->Flags &= ~SFLAG_INTEXTURE;
     }
 
-    if(swapchain) {
-        glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain));
-    } else {
+    if(surface_is_offscreen(SrcSurface)) {
         TRACE("Reading from an offscreen target\n");
         upsidedown = !upsidedown;
         glReadBuffer(myDevice->offscreenBuffer);
+    } else {
+        glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain));
     }
 
     /* TODO: Only back up the part that will be overwritten */
@@ -4562,13 +4562,15 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
           persistent ? "TRUE" : "FALSE");
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-        if (This->Flags & SFLAG_SWAPCHAIN)
+        if (surface_is_offscreen(iface))
         {
-            TRACE("Surface %p is an onscreen surface\n", iface);
-        } else {
             /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
             if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
         }
+        else
+        {
+            TRACE("Surface %p is an onscreen surface\n", iface);
+        }
     }
 
     if(persistent) {
@@ -4829,16 +4831,20 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
     int width, pitch, outpitch;
     BYTE *mem;
     BOOL drawable_read_ok = TRUE;
+    BOOL in_fbo = FALSE;
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-        if (This->Flags & SFLAG_SWAPCHAIN)
+        if (surface_is_offscreen(iface))
         {
-            TRACE("Surface %p is an onscreen surface\n", iface);
-        } else {
             /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
              * Prefer SFLAG_INTEXTURE. */
             if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE;
             drawable_read_ok = FALSE;
+            in_fbo = TRUE;
+        }
+        else
+        {
+            TRACE("Surface %p is an onscreen surface\n", iface);
         }
     }
 
@@ -5063,8 +5069,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
         This->Flags |= flag;
     }
 
-    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN)
-            && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) {
+    if (in_fbo && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) {
         /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
         This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
     }
@@ -5121,6 +5126,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) {
     return hr;
 }
 
+BOOL surface_is_offscreen(IWineD3DSurface *iface)
+{
+    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
+
+    return !(This->Flags & SFLAG_SWAPCHAIN);
+}
+
 const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
 {
     /* IUnknown */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index bd8e58f..4fb556c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1727,6 +1727,7 @@ typedef struct IWineD3DBaseTextureClass
 
 void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
 BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
+BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
 
 typedef struct IWineD3DBaseTextureImpl
 {




More information about the wine-cvs mailing list