[PATCH 2/5] wined3d: Merge the IWineD3DSurface::GetDC() implementations.
Henri Verbeet
hverbeet at codeweavers.com
Wed Apr 27 13:21:40 CDT 2011
---
dlls/wined3d/surface.c | 443 ++++++++++++++++++----------------------
dlls/wined3d/wined3d_private.h | 1 +
2 files changed, 200 insertions(+), 244 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 34be870..d384f6e 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -571,6 +571,72 @@ static void surface_evict_sysmem(IWineD3DSurfaceImpl *surface)
surface_modify_location(surface, SFLAG_INSYSMEM, FALSE);
}
+/* Context activation is done by the caller. */
+static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *surface,
+ const struct wined3d_gl_info *gl_info, BOOL srgb)
+{
+ IWineD3DDeviceImpl *device = surface->resource.device;
+ DWORD active_sampler;
+ GLint active_texture;
+
+ /* We don't need a specific texture unit, but after binding the texture
+ * the current unit is dirty. Read the unit back instead of switching to
+ * 0, this avoids messing around with the state manager's GL states. The
+ * current texture unit should always be a valid one.
+ *
+ * To be more specific, this is tricky because we can implicitly be
+ * called from sampler() in state.c. This means we can't touch anything
+ * other than whatever happens to be the currently active texture, or we
+ * would risk marking already applied sampler states dirty again.
+ *
+ * TODO: Track the current active texture per GL context instead of using
+ * glGet(). */
+
+ ENTER_GL();
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+ LEAVE_GL();
+ active_sampler = device->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
+
+ if (active_sampler != WINED3D_UNMAPPED_STAGE)
+ {
+ IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(active_sampler));
+ }
+ surface_bind(surface, gl_info, srgb);
+}
+
+static void surface_force_reload(IWineD3DSurfaceImpl *surface)
+{
+ surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
+}
+
+static void surface_release_client_storage(IWineD3DSurfaceImpl *surface)
+{
+ struct wined3d_context *context = context_acquire(surface->resource.device, NULL);
+
+ ENTER_GL();
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ if (surface->texture_name)
+ {
+ surface_bind_and_dirtify(surface, context->gl_info, FALSE);
+ glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
+ if (surface->texture_name_srgb)
+ {
+ surface_bind_and_dirtify(surface, context->gl_info, TRUE);
+ glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ LEAVE_GL();
+
+ context_release(context);
+
+ surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE);
+ surface_modify_location(surface, SFLAG_INTEXTURE, FALSE);
+ surface_force_reload(surface);
+}
+
static HRESULT surface_private_setup(struct IWineD3DSurfaceImpl *surface)
{
/* TODO: Check against the maximum texture sizes supported by the video card. */
@@ -934,6 +1000,43 @@ done:
surface->surface_ops->surface_draw_overlay(surface);
}
+static HRESULT surface_getdc(IWineD3DSurfaceImpl *surface)
+{
+ WINED3DLOCKED_RECT lock;
+ HRESULT hr;
+
+ TRACE("surface %p.\n", surface);
+
+ /* Create a DIB section if there isn't a dc yet. */
+ if (!surface->hDC)
+ {
+ if (surface->flags & SFLAG_CLIENT)
+ {
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ surface_release_client_storage(surface);
+ }
+ hr = surface_create_dib_section(surface);
+ if (FAILED(hr))
+ return WINED3DERR_INVALIDCALL;
+
+ /* Use the DIB section from now on if we are not using a PBO. */
+ if (!(surface->flags & SFLAG_PBO))
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+
+ /* Map the surface. */
+ hr = IWineD3DSurface_Map((IWineD3DSurface *)surface, &lock, NULL, 0);
+ if (FAILED(hr))
+ ERR("Map failed, hr %#x.\n", hr);
+
+ /* Sync the DIB with the PBO. This can't be done earlier because Map()
+ * activates the allocatedMemory. */
+ if (surface->flags & SFLAG_PBO)
+ memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory, surface->dib.bitmap_size);
+
+ return hr;
+}
+
/* Context activation is done by the caller. */
static void surface_remove_pbo(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info)
{
@@ -1046,6 +1149,7 @@ static const struct wined3d_surface_ops surface_ops =
surface_preload,
surface_map,
surface_unmap,
+ surface_getdc,
};
/*****************************************************************************
@@ -1199,6 +1303,28 @@ static void gdi_surface_unmap(IWineD3DSurfaceImpl *surface)
memset(&surface->lockedRect, 0, sizeof(RECT));
}
+static HRESULT gdi_surface_getdc(IWineD3DSurfaceImpl *surface)
+{
+ WINED3DLOCKED_RECT lock;
+ HRESULT hr;
+
+ TRACE("surface %p.\n", surface);
+
+ /* Should have a DIB section already. */
+ if (!(surface->flags & SFLAG_DIBSECTION))
+ {
+ WARN("DC not supported on this surface\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Map the surface. */
+ hr = IWineD3DSurface_Map((IWineD3DSurface *)surface, &lock, NULL, 0);
+ if (FAILED(hr))
+ ERR("Map failed, hr %#x.\n", hr);
+
+ return hr;
+}
+
static const struct wined3d_surface_ops gdi_surface_ops =
{
gdi_surface_private_setup,
@@ -1208,13 +1334,9 @@ static const struct wined3d_surface_ops gdi_surface_ops =
gdi_surface_preload,
gdi_surface_map,
gdi_surface_unmap,
+ gdi_surface_getdc,
};
-static void surface_force_reload(IWineD3DSurfaceImpl *surface)
-{
- surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
-}
-
void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint new_name, BOOL srgb)
{
GLuint *name;
@@ -1316,37 +1438,6 @@ void surface_bind(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl
}
}
-/* Context activation is done by the caller. */
-static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *surface,
- const struct wined3d_gl_info *gl_info, BOOL srgb)
-{
- IWineD3DDeviceImpl *device = surface->resource.device;
- DWORD active_sampler;
-
- /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
- * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
- * gl states. The current texture unit should always be a valid one.
- *
- * To be more specific, this is tricky because we can implicitly be called
- * from sampler() in state.c. This means we can't touch anything other than
- * whatever happens to be the currently active texture, or we would risk
- * marking already applied sampler states dirty again.
- *
- * TODO: Track the current active texture per GL context instead of using glGet
- */
- GLint active_texture;
- ENTER_GL();
- glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
- LEAVE_GL();
- active_sampler = device->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
-
- if (active_sampler != WINED3D_UNMAPPED_STAGE)
- {
- IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(active_sampler));
- }
- surface_bind(surface, gl_info, srgb);
-}
-
/* This function checks if the primary render target uses the 8bit paletted format. */
static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
{
@@ -3818,6 +3909,76 @@ static HRESULT WINAPI IWineD3DBaseSurfaceImpl_Map(IWineD3DSurface *iface,
return WINED3D_OK;
}
+static HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *dc)
+{
+ IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, dc %p.\n", iface, dc);
+
+ if (surface->flags & SFLAG_USERPTR)
+ {
+ ERR("Not supported on surfaces with application-provided memory.\n");
+ return WINEDDERR_NODC;
+ }
+
+ /* Give more detailed info for ddraw. */
+ if (surface->flags & SFLAG_DCINUSE)
+ return WINEDDERR_DCALREADYCREATED;
+
+ /* Can't GetDC if the surface is locked. */
+ if (surface->flags & SFLAG_LOCKED)
+ return WINED3DERR_INVALIDCALL;
+
+ hr = surface->surface_ops->surface_getdc(surface);
+ if (FAILED(hr))
+ return hr;
+
+ if (surface->resource.format->id == WINED3DFMT_P8_UINT
+ || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
+ {
+ /* GetDC on palettized formats is unsupported in D3D9, and the method
+ * is missing in D3D8, so this should only be used for DX <=7
+ * surfaces (with non-device palettes). */
+ const PALETTEENTRY *pal = NULL;
+
+ if (surface->palette)
+ {
+ pal = surface->palette->palents;
+ }
+ else
+ {
+ struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0];
+ IWineD3DSurfaceImpl *dds_primary = swapchain->front_buffer;
+
+ if (dds_primary && dds_primary->palette)
+ pal = dds_primary->palette->palents;
+ }
+
+ if (pal)
+ {
+ RGBQUAD col[256];
+ unsigned int i;
+
+ for (i = 0; i < 256; ++i)
+ {
+ col[i].rgbRed = pal[i].peRed;
+ col[i].rgbGreen = pal[i].peGreen;
+ col[i].rgbBlue = pal[i].peBlue;
+ col[i].rgbReserved = 0;
+ }
+ SetDIBColorTable(surface->hDC, 0, 256, col);
+ }
+ }
+
+ surface->flags |= SFLAG_DCINUSE;
+
+ *dc = surface->hDC;
+ TRACE("Returning dc %p.\n", *dc);
+
+ return WINED3D_OK;
+}
+
/* ****************************************************
IWineD3DSurface IWineD3DResource parts follow
**************************************************** */
@@ -4308,129 +4469,6 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *surface,
context_release(context);
}
-static void surface_release_client_storage(IWineD3DSurfaceImpl *surface)
-{
- struct wined3d_context *context;
-
- context = context_acquire(surface->resource.device, NULL);
-
- ENTER_GL();
- glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
- if (surface->texture_name)
- {
- surface_bind_and_dirtify(surface, context->gl_info, FALSE);
- glTexImage2D(surface->texture_target, surface->texture_level,
- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- }
- if (surface->texture_name_srgb)
- {
- surface_bind_and_dirtify(surface, context->gl_info, TRUE);
- glTexImage2D(surface->texture_target, surface->texture_level,
- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- }
- glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
-
- LEAVE_GL();
- context_release(context);
-
- surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE);
- surface_modify_location(surface, SFLAG_INTEXTURE, FALSE);
- surface_force_reload(surface);
-}
-
-static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC)
-{
- IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
- WINED3DLOCKED_RECT lock;
- HRESULT hr;
- RGBQUAD col[256];
-
- TRACE("(%p)->(%p)\n",This,pHDC);
-
- if (This->flags & SFLAG_USERPTR)
- {
- ERR("Not supported on surfaces with an application-provided surfaces\n");
- return WINEDDERR_NODC;
- }
-
- /* Give more detailed info for ddraw */
- if (This->flags & SFLAG_DCINUSE)
- return WINEDDERR_DCALREADYCREATED;
-
- /* Can't GetDC if the surface is locked */
- if (This->flags & SFLAG_LOCKED)
- return WINED3DERR_INVALIDCALL;
-
- memset(&lock, 0, sizeof(lock)); /* To be sure */
-
- /* Create a DIB section if there isn't a hdc yet */
- if (!This->hDC)
- {
- if (This->flags & SFLAG_CLIENT)
- {
- surface_load_location(This, SFLAG_INSYSMEM, NULL);
- surface_release_client_storage(This);
- }
- hr = surface_create_dib_section(This);
- if(FAILED(hr)) return WINED3DERR_INVALIDCALL;
-
- /* Use the dib section from now on if we are not using a PBO */
- if (!(This->flags & SFLAG_PBO))
- This->resource.allocatedMemory = This->dib.bitmap_data;
- }
-
- /* Map the surface */
- hr = IWineD3DSurface_Map(iface, &lock, NULL, 0);
-
- /* Sync the DIB with the PBO. This can't be done earlier because Map()
- * activates the allocatedMemory. */
- if (This->flags & SFLAG_PBO)
- memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, This->dib.bitmap_size);
-
- if (FAILED(hr))
- {
- ERR("IWineD3DSurface_Map failed, hr %#x.\n", hr);
- /* keep the dib section */
- return hr;
- }
-
- if (This->resource.format->id == WINED3DFMT_P8_UINT
- || This->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
- {
- /* GetDC on palettized formats is unsupported in D3D9, and the method is missing in
- D3D8, so this should only be used for DX <=7 surfaces (with non-device palettes) */
- unsigned int n;
- const PALETTEENTRY *pal = NULL;
-
- if(This->palette) {
- pal = This->palette->palents;
- } else {
- IWineD3DSurfaceImpl *dds_primary;
- struct wined3d_swapchain *swapchain;
- swapchain = This->resource.device->swapchains[0];
- dds_primary = swapchain->front_buffer;
- if (dds_primary && dds_primary->palette)
- pal = dds_primary->palette->palents;
- }
-
- if (pal) {
- for (n=0; n<256; n++) {
- col[n].rgbRed = pal[n].peRed;
- col[n].rgbGreen = pal[n].peGreen;
- col[n].rgbBlue = pal[n].peBlue;
- col[n].rgbReserved = 0;
- }
- SetDIBColorTable(This->hDC, 0, 256, col);
- }
- }
-
- *pHDC = This->hDC;
- TRACE("returning %p\n",*pHDC);
- This->flags |= SFLAG_DCINUSE;
-
- return WINED3D_OK;
-}
-
static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC)
{
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
@@ -6994,7 +7032,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
IWineD3DBaseSurfaceImpl_GetResource,
IWineD3DBaseSurfaceImpl_Map,
IWineD3DBaseSurfaceImpl_Unmap,
- IWineD3DSurfaceImpl_GetDC,
+ IWineD3DBaseSurfaceImpl_GetDC,
IWineD3DSurfaceImpl_ReleaseDC,
IWineD3DSurfaceImpl_Flip,
IWineD3DSurfaceImpl_Blt,
@@ -7295,89 +7333,6 @@ static HRESULT WINAPI IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
return hr;
}
-static HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *dc)
-{
- IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
- WINED3DLOCKED_RECT lock;
- HRESULT hr;
- RGBQUAD col[256];
-
- TRACE("iface %p, dc %p.\n", iface, dc);
-
- if (!(surface->flags & SFLAG_DIBSECTION))
- {
- WARN("DC not supported on this surface\n");
- return WINED3DERR_INVALIDCALL;
- }
-
- if (surface->flags & SFLAG_USERPTR)
- {
- ERR("Not supported on surfaces with application-provided memory.\n");
- return WINEDDERR_NODC;
- }
-
- /* Give more detailed info for ddraw. */
- if (surface->flags & SFLAG_DCINUSE)
- return WINEDDERR_DCALREADYCREATED;
-
- /* Can't GetDC if the surface is locked. */
- if (surface->flags & SFLAG_LOCKED)
- return WINED3DERR_INVALIDCALL;
-
- memset(&lock, 0, sizeof(lock)); /* To be sure */
-
- /* Should have a DIB section already. */
-
- /* Map the surface. */
- hr = IWineD3DSurface_Map(iface, &lock, NULL, 0);
- if (FAILED(hr))
- {
- ERR("IWineD3DSurface_Map failed, hr %#x.\n", hr);
- /* keep the dib section */
- return hr;
- }
-
- if (surface->resource.format->id == WINED3DFMT_P8_UINT
- || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
- {
- const PALETTEENTRY *pal = NULL;
-
- if (surface->palette)
- {
- pal = surface->palette->palents;
- }
- else
- {
- struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0];
- IWineD3DSurfaceImpl *dds_primary = swapchain->front_buffer;
-
- if (dds_primary && dds_primary->palette)
- pal = dds_primary->palette->palents;
- }
-
- if (pal)
- {
- unsigned int i;
-
- for (i = 0; i < 256; ++i)
- {
- col[i].rgbRed = pal[i].peRed;
- col[i].rgbGreen = pal[i].peGreen;
- col[i].rgbBlue = pal[i].peBlue;
- col[i].rgbReserved = 0;
- }
- SetDIBColorTable(surface->hDC, 0, 256, col);
- }
- }
-
- surface->flags |= SFLAG_DCINUSE;
-
- *dc = surface->hDC;
- TRACE("Returning dc %p.\n", *dc);
-
- return WINED3D_OK;
-}
-
static HRESULT WINAPI IWineGDISurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC dc)
{
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
@@ -7473,7 +7428,7 @@ static const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
IWineD3DBaseSurfaceImpl_GetResource,
IWineD3DBaseSurfaceImpl_Map,
IWineD3DBaseSurfaceImpl_Unmap,
- IWineGDISurfaceImpl_GetDC,
+ IWineD3DBaseSurfaceImpl_GetDC,
IWineGDISurfaceImpl_ReleaseDC,
IWineGDISurfaceImpl_Flip,
IWineD3DBaseSurfaceImpl_Blt,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e8208bd..6d8e973 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2027,6 +2027,7 @@ struct wined3d_surface_ops
void (*surface_preload)(struct IWineD3DSurfaceImpl *surface);
void (*surface_map)(struct IWineD3DSurfaceImpl *surface, const RECT *rect, DWORD flags);
void (*surface_unmap)(struct IWineD3DSurfaceImpl *surface);
+ HRESULT (*surface_getdc)(struct IWineD3DSurfaceImpl *surface);
};
/*****************************************************************************
--
1.7.3.4
More information about the wine-patches
mailing list