[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