[PATCH 4/5] wined3d: Use wined3d_texture_get_dc() in device_load_logo().

Henri Verbeet hverbeet at codeweavers.com
Mon Feb 1 11:42:11 CST 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/device.c          | 10 ++---
 dlls/wined3d/surface.c         | 96 +-----------------------------------------
 dlls/wined3d/texture.c         | 87 +++++++++++++++++++++++++++++++++++++-
 dlls/wined3d/wined3d_private.h |  3 +-
 4 files changed, 93 insertions(+), 103 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7059e21..802a6dd 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -599,7 +599,6 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
 {
     struct wined3d_color_key color_key;
     struct wined3d_resource_desc desc;
-    struct wined3d_surface *surface;
     HBITMAP hbm;
     BITMAP bm;
     HRESULT hr;
@@ -639,14 +638,13 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
         ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr);
         goto out;
     }
-    surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0));
 
     if (dcb)
     {
-        if (FAILED(hr = wined3d_surface_getdc(surface, &dcs)))
+        if (FAILED(hr = wined3d_texture_get_dc(device->logo_texture, 0, &dcs)))
             goto out;
         BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY);
-        wined3d_surface_releasedc(surface, dcs);
+        wined3d_texture_release_dc(device->logo_texture, 0, dcs);
 
         color_key.color_space_low_value = 0;
         color_key.color_space_high_value = 0;
@@ -654,10 +652,12 @@ static void device_load_logo(struct wined3d_device *device, const char *filename
     }
     else
     {
-        const RECT rect = {0, 0, surface->resource.width, surface->resource.height};
         const struct wined3d_color c = {1.0f, 1.0f, 1.0f, 1.0f};
+        const RECT rect = {0, 0, desc.width, desc.height};
+        struct wined3d_surface *surface;
 
         /* Fill the surface with a white color to show that wined3d is there */
+        surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0));
         surface_color_fill(surface, &rect, &c);
     }
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 57ab90c..2698d09 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -356,7 +356,7 @@ static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
     masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset;
 }
 
-static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
+HRESULT surface_create_dib_section(struct wined3d_surface *surface)
 {
     const struct wined3d_format *format = surface->resource.format;
     unsigned int format_flags = surface->container->resource.format_flags;
@@ -2580,98 +2580,6 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
     return WINED3D_OK;
 }
 
-HRESULT wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
-{
-    HRESULT hr;
-    struct wined3d_device *device = surface->resource.device;
-    struct wined3d_context *context = NULL;
-
-    TRACE("surface %p, dc %p.\n", surface, dc);
-
-    /* Give more detailed info for ddraw. */
-    if (surface->flags & SFLAG_DCINUSE)
-        return WINEDDERR_DCALREADYCREATED;
-
-    /* Can't GetDC if the surface is locked. */
-    if (surface->resource.map_count)
-        return WINED3DERR_INVALIDCALL;
-
-    if (device->d3d_initialized)
-        context = context_acquire(surface->resource.device, NULL);
-
-    /* Create a DIB section if there isn't a dc yet. */
-    if (!surface->hDC)
-    {
-        if (FAILED(hr = surface_create_dib_section(surface)))
-        {
-            if (context)
-                context_release(context);
-             return WINED3DERR_INVALIDCALL;
-        }
-        if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
-                || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
-                || surface->pbo))
-            surface->resource.map_binding = WINED3D_LOCATION_DIB;
-    }
-
-    surface_load_location(surface, context, WINED3D_LOCATION_DIB);
-    surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB);
-
-    if (context)
-        context_release(context);
-
-    surface->flags |= SFLAG_DCINUSE;
-    surface->resource.map_count++;
-
-    *dc = surface->hDC;
-    TRACE("Returning dc %p.\n", *dc);
-
-    return WINED3D_OK;
-}
-
-HRESULT wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
-{
-    TRACE("surface %p, dc %p.\n", surface, dc);
-
-    if (!(surface->flags & SFLAG_DCINUSE))
-        return WINEDDERR_NODC;
-
-    if (surface->hDC != dc)
-    {
-        WARN("Application tries to release invalid DC %p, surface DC is %p.\n",
-                dc, surface->hDC);
-        return WINEDDERR_NODC;
-    }
-
-    surface->resource.map_count--;
-    surface->flags &= ~SFLAG_DCINUSE;
-
-    if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
-            || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
-            && surface->resource.map_binding != WINED3D_LOCATION_DIB))
-    {
-        /* The game Salammbo modifies the surface contents without mapping the surface between
-         * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active
-         * copy and is copied to the screen, this update, which draws the mouse pointer, is lost.
-         * Do not only copy the DIB to the map location, but also make sure the map location is
-         * copied back to the DIB in the next getdc call.
-         *
-         * The same consideration applies to user memory surfaces. */
-        struct wined3d_device *device = surface->resource.device;
-        struct wined3d_context *context = NULL;
-
-        if (device->d3d_initialized)
-            context = context_acquire(device, NULL);
-
-        surface_load_location(surface, context, surface->resource.map_binding);
-        surface_invalidate_location(surface, WINED3D_LOCATION_DIB);
-        if (context)
-            context_release(context);
-    }
-
-    return WINED3D_OK;
-}
-
 static void read_from_framebuffer(struct wined3d_surface *surface,
         struct wined3d_context *old_ctx, DWORD dst_location)
 {
@@ -5411,7 +5319,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
 
     /* Similar to lockable rendertargets above, creating the DIB section
      * during surface initialization prevents the sysmem pointer from changing
-     * after a wined3d_surface_getdc() call. */
+     * after a wined3d_texture_get_dc() call. */
     if ((desc->usage & WINED3DUSAGE_OWNDC) && !surface->hDC
             && SUCCEEDED(surface_create_dib_section(surface)))
         surface->resource.map_binding = WINED3D_LOCATION_DIB;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index fa948ff..ee2d17e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1514,7 +1514,11 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
 
 HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc)
 {
+    struct wined3d_device *device = texture->resource.device;
+    struct wined3d_context *context = NULL;
     struct wined3d_resource *sub_resource;
+    struct wined3d_surface *surface;
+    HRESULT hr;
 
     TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
 
@@ -1527,12 +1531,55 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i
         return WINED3DERR_INVALIDCALL;
     }
 
-    return wined3d_surface_getdc(surface_from_resource(sub_resource), dc);
+    surface = surface_from_resource(sub_resource);
+
+    /* Give more detailed info for ddraw. */
+    if (surface->flags & SFLAG_DCINUSE)
+        return WINEDDERR_DCALREADYCREATED;
+
+    /* Can't GetDC if the surface is locked. */
+    if (surface->resource.map_count)
+        return WINED3DERR_INVALIDCALL;
+
+    if (device->d3d_initialized)
+        context = context_acquire(device, NULL);
+
+    /* Create a DIB section if there isn't a dc yet. */
+    if (!surface->hDC)
+    {
+        if (FAILED(hr = surface_create_dib_section(surface)))
+        {
+            if (context)
+                context_release(context);
+             return WINED3DERR_INVALIDCALL;
+        }
+        if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
+                || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
+                || surface->pbo))
+            surface->resource.map_binding = WINED3D_LOCATION_DIB;
+    }
+
+    surface_load_location(surface, context, WINED3D_LOCATION_DIB);
+    surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB);
+
+    if (context)
+        context_release(context);
+
+    surface->flags |= SFLAG_DCINUSE;
+    surface->resource.map_count++;
+
+    *dc = surface->hDC;
+    TRACE("Returning dc %p.\n", *dc);
+
+    return WINED3D_OK;
 }
 
 HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
 {
+    struct wined3d_device *device = texture->resource.device;
+    struct wined3d_context *context = NULL;
     struct wined3d_resource *sub_resource;
+    struct wined3d_surface *surface;
 
     TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
 
@@ -1545,5 +1592,41 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign
         return WINED3DERR_INVALIDCALL;
     }
 
-    return wined3d_surface_releasedc(surface_from_resource(sub_resource), dc);
+    surface = surface_from_resource(sub_resource);
+
+    if (!(surface->flags & SFLAG_DCINUSE))
+        return WINEDDERR_NODC;
+
+    if (surface->hDC != dc)
+    {
+        WARN("Application tries to release invalid DC %p, surface DC is %p.\n",
+                dc, surface->hDC);
+        return WINEDDERR_NODC;
+    }
+
+    surface->resource.map_count--;
+    surface->flags &= ~SFLAG_DCINUSE;
+
+    if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY
+            || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM
+            && surface->resource.map_binding != WINED3D_LOCATION_DIB))
+    {
+        /* The game Salammbo modifies the surface contents without mapping the surface between
+         * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active
+         * copy and is copied to the screen, this update, which draws the mouse pointer, is lost.
+         * Do not only copy the DIB to the map location, but also make sure the map location is
+         * copied back to the DIB in the next getdc call.
+         *
+         * The same consideration applies to user memory surfaces. */
+
+        if (device->d3d_initialized)
+            context = context_acquire(device, NULL);
+
+        surface_load_location(surface, context, surface->resource.map_binding);
+        surface_invalidate_location(surface, WINED3D_LOCATION_DIB);
+        if (context)
+            context_release(context);
+    }
+
+    return WINED3D_OK;
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5474c7f..7ab2ae8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2506,8 +2506,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
 void surface_set_dirty(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 HRESULT surface_color_fill(struct wined3d_surface *s,
         const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
+HRESULT surface_create_dib_section(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
-HRESULT wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) DECLSPEC_HIDDEN;
 void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context,
         unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN;
 void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN;
@@ -2521,7 +2521,6 @@ HRESULT surface_load_location(struct wined3d_surface *surface,
 void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
 void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context,
         DWORD location) DECLSPEC_HIDDEN;
-HRESULT wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) DECLSPEC_HIDDEN;
 void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
         const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
 void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN;
-- 
2.1.4




More information about the wine-patches mailing list