[PATCH 2/5] wined3d: Set palettes on the swapchain.
Stefan Dösinger
stefan at codeweavers.com
Thu May 15 07:33:12 CDT 2014
---
dlls/ddraw/surface.c | 7 ++--
dlls/wined3d/palette.c | 4 +-
dlls/wined3d/surface.c | 87 ++++--------------------------------------
dlls/wined3d/swapchain.c | 46 ++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 2 +-
dlls/wined3d/wined3d_private.h | 4 +-
include/wine/wined3d.h | 2 +-
7 files changed, 63 insertions(+), 89 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 3f230a2..db3e58b 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -473,9 +473,9 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD
prev->flags &= ~DDPCAPS_PRIMARYSURFACE;
if (palette_impl)
palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
- /* Update the wined3d frontbuffer if this is the primary. */
- if (surface->ddraw->wined3d_frontbuffer)
- wined3d_surface_set_palette(surface->ddraw->wined3d_frontbuffer,
+ /* Update the wined3d swapchain if this is the primary. */
+ if (surface->ddraw->wined3d_swapchain)
+ wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
palette_impl ? palette_impl->wineD3DPalette : NULL);
}
if (palette_impl)
@@ -483,7 +483,6 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD
if (prev)
IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
surface->palette = palette_impl;
- wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL);
wined3d_mutex_unlock();
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index 3f7e2ad..780f068 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -136,8 +136,8 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
if (resource->type == WINED3D_RTYPE_SURFACE)
{
struct wined3d_surface *surface = surface_from_resource(resource);
- if (surface->palette == palette)
- surface->surface_ops->surface_realize_palette(surface);
+ if (surface->swapchain && surface->swapchain->palette == palette)
+ surface->swapchain->swapchain_ops->swapchain_realize_palette(surface->swapchain);
}
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 023439d..e50cb7d 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -498,7 +498,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
/* Now allocate a DC. */
surface->hDC = CreateCompatibleDC(0);
SelectObject(surface->hDC, surface->dib.DIBsection);
- TRACE("Using wined3d palette %p.\n", surface->palette);
surface->flags |= SFLAG_DIBSECTION;
@@ -754,44 +753,6 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
return WINED3D_OK;
}
-static void surface_realize_palette(struct wined3d_surface *surface)
-{
- struct wined3d_palette *palette = surface->palette;
-
- TRACE("surface %p.\n", surface);
-
- if (!palette) return;
-
- if (surface->resource.format->id == WINED3DFMT_P8_UINT
- || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
- {
- if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
- {
- /* Make sure the texture is up to date. This call doesn't do
- * anything if the texture is already up to date. */
- surface_load_location(surface, WINED3D_LOCATION_TEXTURE_RGB);
-
- /* We want to force a palette refresh, so mark the drawable as not being up to date */
- if (!surface_is_offscreen(surface))
- surface_invalidate_location(surface, WINED3D_LOCATION_DRAWABLE);
- }
- else
- {
- if (!(surface->locations & surface->map_binding))
- {
- TRACE("Palette changed with surface that does not have an up to date system memory copy.\n");
- surface_prepare_map_memory(surface);
- surface_load_location(surface, surface->map_binding);
- }
- surface_invalidate_location(surface, ~surface->map_binding);
- }
- }
-
- /* Propagate the changes to the drawable when we have a palette. */
- if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
- surface_load_location(surface, surface->draw_binding);
-}
-
static void surface_unmap(struct wined3d_surface *surface)
{
struct wined3d_device *device = surface->resource.device;
@@ -1098,15 +1059,18 @@ static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface
DWORD color, struct wined3d_color *float_color)
{
const struct wined3d_format *format = surface->resource.format;
+ const struct wined3d_palette *palette;
switch (format->id)
{
case WINED3DFMT_P8_UINT:
- if (surface->palette)
+ palette = surface->swapchain ? surface->swapchain->palette : NULL;
+
+ if (palette)
{
- float_color->r = surface->palette->colors[color].rgbRed / 255.0f;
- float_color->g = surface->palette->colors[color].rgbGreen / 255.0f;
- float_color->b = surface->palette->colors[color].rgbBlue / 255.0f;
+ float_color->r = palette->colors[color].rgbRed / 255.0f;
+ float_color->g = palette->colors[color].rgbGreen / 255.0f;
+ float_color->b = palette->colors[color].rgbBlue / 255.0f;
}
else
{
@@ -1320,7 +1284,6 @@ static const struct wined3d_resource_ops surface_resource_ops =
static const struct wined3d_surface_ops surface_ops =
{
surface_private_setup,
- surface_realize_palette,
surface_unmap,
};
@@ -1365,24 +1328,6 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface)
return WINED3D_OK;
}
-static void gdi_surface_realize_palette(struct wined3d_surface *surface)
-{
- struct wined3d_palette *palette = surface->palette;
-
- TRACE("surface %p.\n", surface);
-
- if (!palette) return;
-
- /* Update the image because of the palette change. Some games like e.g.
- * Red Alert call SetEntries a lot to implement fading. */
- /* Tell the swapchain to update the screen. */
- if (surface->swapchain && surface == surface->swapchain->front_buffer)
- {
- wined3d_palette_apply_to_dc(palette, surface->hDC);
- x11_copy_to_screen(surface->swapchain, NULL);
- }
-}
-
static void gdi_surface_unmap(struct wined3d_surface *surface)
{
TRACE("surface %p.\n", surface);
@@ -1397,7 +1342,6 @@ static void gdi_surface_unmap(struct wined3d_surface *surface)
static const struct wined3d_surface_ops gdi_surface_ops =
{
gdi_surface_private_setup,
- gdi_surface_realize_palette,
gdi_surface_unmap,
};
@@ -2346,21 +2290,6 @@ HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface)
return WINED3D_OK;
}
-void CDECL wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette)
-{
- TRACE("surface %p, palette %p.\n", surface, palette);
-
- if (surface->palette == palette)
- {
- TRACE("Nop palette change.\n");
- return;
- }
-
- surface->palette = palette;
- if (palette)
- surface->surface_ops->surface_realize_palette(surface);
-}
-
DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
{
unsigned int alignment;
@@ -3372,7 +3301,7 @@ static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD colo
void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4])
{
- const struct wined3d_palette *pal = surface->palette;
+ const struct wined3d_palette *pal = surface->swapchain ? surface->swapchain->palette : NULL;
unsigned int i;
if (!pal)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 75e6628..f2639d9 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -258,6 +258,21 @@ HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *s
return WINED3D_OK;
}
+void CDECL wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette)
+{
+ TRACE("swapchain %p, palette %p.\n", swapchain, palette);
+
+ if (swapchain->palette == palette)
+ {
+ TRACE("Nop palette change.\n");
+ return;
+ }
+
+ swapchain->palette = palette;
+ if (palette)
+ swapchain->swapchain_ops->swapchain_realize_palette(swapchain);
+}
+
HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain,
struct wined3d_gamma_ramp *ramp)
{
@@ -603,9 +618,33 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
context_release(context);
}
+static void swapchain_gl_realize_palette(struct wined3d_swapchain *swapchain)
+{
+ /* Note that this function is only called on front buffers.
+ * Copy the front buffer to the texture and re-draw it on
+ * the actual GL front buffer.
+ *
+ * TODO: This code (like many other places) assumes that
+ * the front buffer size is smaller than the maximum texture
+ * size. We'd have to copy the front buffer to the map
+ * binding if we cannot fit it in a GL texture. This should
+ * probably be decided in some other place though. */
+ surface_load_location(swapchain->front_buffer, WINED3D_LOCATION_TEXTURE_RGB);
+ surface_invalidate_location(swapchain->front_buffer, WINED3D_LOCATION_DRAWABLE);
+ surface_load_location(swapchain->front_buffer, WINED3D_LOCATION_DRAWABLE);
+
+ /* At the time of the writing of this code P8 swapchains
+ * never had back buffers due to the ddraw shadow front
+ * buffer. Implement proper handling for back buffers if
+ * this is changed. */
+ if (swapchain->back_buffers)
+ FIXME("Handle P8 swapchains with back buffers.\n");
+}
+
static const struct wined3d_swapchain_ops swapchain_gl_ops =
{
swapchain_gl_present,
+ swapchain_gl_realize_palette,
};
/* Helper function that blits the front buffer contents to the target window. */
@@ -711,9 +750,16 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const REC
x11_copy_to_screen(swapchain, NULL);
}
+static void swapchain_gdi_realize_palette(struct wined3d_swapchain *swapchain)
+{
+ wined3d_palette_apply_to_dc(swapchain->palette, swapchain->front_buffer->hDC);
+ x11_copy_to_screen(swapchain, NULL);
+}
+
static const struct wined3d_swapchain_ops swapchain_gdi_ops =
{
swapchain_gdi_present,
+ swapchain_gdi_realize_palette,
};
void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index f1a45dd..1a41f8c 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -221,7 +221,6 @@
@ cdecl wined3d_surface_releasedc(ptr ptr)
@ cdecl wined3d_surface_restore(ptr)
@ cdecl wined3d_surface_set_overlay_position(ptr long long)
-@ cdecl wined3d_surface_set_palette(ptr ptr)
@ cdecl wined3d_surface_set_priority(ptr long)
@ cdecl wined3d_surface_unmap(ptr)
@ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long)
@@ -241,6 +240,7 @@
@ cdecl wined3d_swapchain_incref(ptr)
@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr ptr long)
@ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr)
+@ cdecl wined3d_swapchain_set_palette(ptr ptr)
@ cdecl wined3d_swapchain_set_window(ptr ptr)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9233148..eb9d135 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2210,7 +2210,6 @@ struct fbo_entry
struct wined3d_surface_ops
{
HRESULT (*surface_private_setup)(struct wined3d_surface *surface);
- void (*surface_realize_palette)(struct wined3d_surface *surface);
void (*surface_unmap)(struct wined3d_surface *surface);
};
@@ -2220,7 +2219,6 @@ struct wined3d_surface
const struct wined3d_surface_ops *surface_ops;
struct wined3d_texture *container;
struct wined3d_swapchain *swapchain;
- struct wined3d_palette *palette; /* D3D7 style palette handling */
DWORD draw_binding, map_binding;
void *user_memory;
DWORD locations;
@@ -2605,6 +2603,7 @@ 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_realize_palette)(struct wined3d_swapchain *swapchain);
};
struct wined3d_swapchain
@@ -2622,6 +2621,7 @@ struct wined3d_swapchain
struct wined3d_gamma_ramp orig_gamma;
BOOL render_to_fbo;
const struct wined3d_format *ds_format;
+ struct wined3d_palette *palette;
LONG prev_time, frames; /* Performance tracking */
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index be7ffdc..26486c8 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2413,7 +2413,6 @@ void __cdecl wined3d_surface_preload(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc);
HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
-void __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette);
DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority);
HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
@@ -2448,6 +2447,7 @@ HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
const RGNDATA *dirty_region, DWORD flags);
HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain,
DWORD flags, const struct wined3d_gamma_ramp *ramp);
+void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette);
void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
--
1.8.5.5
More information about the wine-patches
mailing list