=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: wined3d: Pass a context to read_from_framebuffer.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Oct 15 10:28:00 CDT 2015


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon Oct 12 22:34:39 2015 +0200

wined3d: Pass a context to read_from_framebuffer.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/context.c         | 14 ++++++++++++++
 dlls/wined3d/surface.c         | 18 +++++++++++++-----
 dlls/wined3d/wined3d_private.h |  1 +
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3e2a804..dc4199a 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1194,6 +1194,20 @@ void context_release(struct wined3d_context *context)
     }
 }
 
+/* This is used when a context for render target A is active, but a separate context is
+ * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt
+ * A to avoid breaking caller code. */
+void context_restore(struct wined3d_context *context, struct wined3d_surface *restore)
+{
+    if (context->current_rt != restore)
+    {
+        context_release(context);
+        context = context_acquire(restore->resource.device, restore);
+    }
+
+    context_release(context);
+}
+
 static void context_enter(struct wined3d_context *context)
 {
     TRACE("Entering context %p, level %u.\n", context, context->level + 1);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index c911d35..7101bc4 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2681,11 +2681,13 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
     return WINED3D_OK;
 }
 
-static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_location)
+static void read_from_framebuffer(struct wined3d_surface *surface,
+        struct wined3d_context *old_ctx, DWORD dst_location)
 {
     struct wined3d_device *device = surface->resource.device;
     const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
+    struct wined3d_context *context = old_ctx;
+    struct wined3d_surface *restore_rt = NULL;
     BYTE *mem;
     BYTE *row, *top, *bottom;
     int i;
@@ -2694,7 +2696,12 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
 
     surface_get_memory(surface, &data, dst_location);
 
-    context = context_acquire(device, surface);
+    if (surface != old_ctx->current_rt)
+    {
+        restore_rt = old_ctx->current_rt;
+        context = context_acquire(device, surface);
+    }
+
     context_apply_blit_state(context, device);
     gl_info = context->gl_info;
 
@@ -2781,7 +2788,8 @@ error:
         checkGLcall("glBindBuffer");
     }
 
-    context_release(context);
+    if (restore_rt)
+        context_restore(context, restore_rt);
 }
 
 /* Read the framebuffer contents into a texture. Note that this function
@@ -3824,7 +3832,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
 
     if (surface->locations & WINED3D_LOCATION_DRAWABLE)
     {
-        read_from_framebuffer(surface, dst_location);
+        read_from_framebuffer(surface, context, dst_location);
         return;
     }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 70a8db8..75c16ef 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1423,6 +1423,7 @@ void context_resource_released(const struct wined3d_device *device,
         struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
 void context_resource_unloaded(const struct wined3d_device *device,
         struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
+void context_restore(struct wined3d_context *context, struct wined3d_surface *restore) DECLSPEC_HIDDEN;
 BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
 void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
 void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list