From ceed7fb12e24d85bc317417adefe267c77249df8 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 6 Mar 2016 22:08:50 +0100
Subject: Revert "wined3d: Get rid of wined3d_surface_ops.surface_unmap()."

This reverts commit a7316e1927a847e65494caa9fc892e724b81f48b.
---
 dlls/wined3d/surface.c         | 101 ++++++++++++++++++++++++++---------------
 dlls/wined3d/swapchain.c       |  30 +++---------
 dlls/wined3d/wined3d_private.h |   4 +-
 3 files changed, 75 insertions(+), 60 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 01095e9..1acc3b6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -672,6 +672,55 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
     return WINED3D_OK;
 }
 
+static void surface_unmap(struct wined3d_surface *surface)
+{
+    struct wined3d_device *device = surface->resource.device;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+    struct wined3d_texture *texture;
+
+    TRACE("surface %p.\n", surface);
+
+    switch (surface->resource.map_binding)
+    {
+        case WINED3D_LOCATION_SYSMEM:
+        case WINED3D_LOCATION_USER_MEMORY:
+        case WINED3D_LOCATION_DIB:
+            break;
+
+        case WINED3D_LOCATION_BUFFER:
+            context = context_acquire(device, NULL);
+            gl_info = context->gl_info;
+
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
+            GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+            checkGLcall("glUnmapBuffer");
+            context_release(context);
+            break;
+
+        default:
+            ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding));
+    }
+
+    if (surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB))
+    {
+        TRACE("Not dirtified, nothing to do.\n");
+        return;
+    }
+
+    texture = surface->container;
+    if (texture->swapchain && texture->swapchain->front_buffer == texture)
+    {
+        context = context_acquire(device, surface);
+        surface_load_location(surface, context, texture->resource.draw_binding);
+        context_release(context);
+        memset(&texture->swapchain->front_buffer_update, 0, sizeof(texture->swapchain->front_buffer_update));
+    }
+    else if (texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+        FIXME("Depth / stencil buffer locking is not implemented.\n");
+}
+
 static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
 {
     if ((r->left && r->right) || abs(r->right - r->left) != surface->resource.width)
@@ -1166,6 +1215,7 @@ static const struct wined3d_resource_ops surface_resource_ops =
 static const struct wined3d_surface_ops surface_ops =
 {
     surface_private_setup,
+    surface_unmap,
 };
 
 /*****************************************************************************
@@ -1209,9 +1259,23 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface)
     return WINED3D_OK;
 }
 
+static void gdi_surface_unmap(struct wined3d_surface *surface)
+{
+    struct wined3d_texture *texture = surface->container;
+
+    TRACE("surface %p.\n", surface);
+
+    /* Tell the swapchain to update the screen. */
+    if (texture->swapchain && texture == texture->swapchain->front_buffer)
+        x11_copy_to_screen(texture->swapchain, &texture->swapchain->front_buffer_update);
+
+    memset(&texture->swapchain->front_buffer_update, 0, sizeof(texture->swapchain->front_buffer_update));
+}
+
 static const struct wined3d_surface_ops gdi_surface_ops =
 {
     gdi_surface_private_setup,
+    gdi_surface_unmap,
 };
 
 /* This call just downloads data, the caller is responsible for binding the
@@ -2175,11 +2239,6 @@ do { \
 
 HRESULT wined3d_surface_unmap(struct wined3d_surface *surface)
 {
-    struct wined3d_device *device = surface->resource.device;
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
-    struct wined3d_texture *texture;
-
     TRACE("surface %p.\n", surface);
 
     if (!surface->resource.map_count)
@@ -2189,37 +2248,7 @@ HRESULT wined3d_surface_unmap(struct wined3d_surface *surface)
     }
     --surface->resource.map_count;
 
-    switch (surface->resource.map_binding)
-    {
-        case WINED3D_LOCATION_SYSMEM:
-        case WINED3D_LOCATION_USER_MEMORY:
-        case WINED3D_LOCATION_DIB:
-            break;
-
-        case WINED3D_LOCATION_BUFFER:
-            context = context_acquire(device, NULL);
-            gl_info = context->gl_info;
-
-            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo));
-            GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
-            GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
-            checkGLcall("glUnmapBuffer");
-            context_release(context);
-            break;
-
-        default:
-            ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding));
-            break;
-    }
-
-    if (!(surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
-    {
-        texture = surface->container;
-        if (texture->swapchain && texture->swapchain->front_buffer == texture)
-            texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain);
-        else if (texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
-            FIXME("Depth / stencil buffer locking is not implemented.\n");
-    }
+    surface->surface_ops->surface_unmap(surface);
 
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 9b8d04c..becad97 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -647,25 +647,13 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
     context_release(context);
 }
 
-static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain)
-{
-    struct wined3d_surface *surface;
-    struct wined3d_context *context;
-
-    surface = surface_from_resource(swapchain->front_buffer->sub_resources[0].resource);
-    context = context_acquire(swapchain->device, surface);
-    surface_load_location(surface, context, surface->container->resource.draw_binding);
-    context_release(context);
-    SetRectEmpty(&swapchain->front_buffer_update);
-}
-
 static const struct wined3d_swapchain_ops swapchain_gl_ops =
 {
     swapchain_gl_present,
-    swapchain_gl_frontbuffer_updated,
 };
 
-static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain)
+/* Helper function that blits the front buffer contents to the target window. */
+void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect)
 {
     struct wined3d_surface *front;
     POINT offset = {0, 0};
@@ -673,7 +661,7 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai
     RECT draw_rect;
     HWND window;
 
-    TRACE("swapchain %p.\n", swapchain);
+    TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect));
 
     front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
     if (swapchain->palette)
@@ -701,14 +689,14 @@ static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchai
     draw_rect.right = front->resource.width;
     draw_rect.top = 0;
     draw_rect.bottom = front->resource.height;
-    IntersectRect(&draw_rect, &draw_rect, &swapchain->front_buffer_update);
+
+    if (rect)
+        IntersectRect(&draw_rect, &draw_rect, rect);
 
     BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y,
             draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top,
             src_dc, draw_rect.left, draw_rect.top, SRCCOPY);
     ReleaseDC(window, dst_dc);
-
-    SetRectEmpty(&swapchain->front_buffer_update);
 }
 
 static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in,
@@ -767,16 +755,12 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const REC
         }
     }
 
-    SetRect(&swapchain->front_buffer_update, 0, 0,
-            swapchain->front_buffer->resource.width,
-            swapchain->front_buffer->resource.height);
-    swapchain_gdi_frontbuffer_updated(swapchain);
+    x11_copy_to_screen(swapchain, NULL);
 }
 
 static const struct wined3d_swapchain_ops swapchain_gdi_ops =
 {
     swapchain_gdi_present,
-    swapchain_gdi_frontbuffer_updated,
 };
 
 static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ce2f196..4066c79 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2500,6 +2500,7 @@ struct fbo_entry
 struct wined3d_surface_ops
 {
     HRESULT (*surface_private_setup)(struct wined3d_surface *surface);
+    void (*surface_unmap)(struct wined3d_surface *surface);
 };
 
 struct wined3d_surface
@@ -2915,7 +2916,6 @@ struct wined3d_swapchain_ops
 {
     void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect,
             const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags);
-    void (*swapchain_frontbuffer_updated)(struct wined3d_swapchain *swaphchain);
 };
 
 struct wined3d_swapchain
@@ -2948,6 +2948,8 @@ struct wined3d_swapchain
     HWND backup_wnd;
 };
 
+void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN;
+
 void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN;
 struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-- 
2.7.1

