wined3d: Use wined3d_texture_get_dc() in device_load_logo().

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2016-02-01 18:42:11 +01:00 committed by Alexandre Julliard
parent 7e57924d32
commit 9bdab23bf7
4 changed files with 93 additions and 103 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;