diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c index 5685fed103c..2293f7d404f 100644 --- a/dlls/wined3d/palette.c +++ b/dlls/wined3d/palette.c @@ -163,10 +163,11 @@ static HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, LIST_FOR_EACH_ENTRY(res, &This->device->resources, IWineD3DResourceImpl, resource.resource_list_entry) { - if(IWineD3DResource_GetType((IWineD3DResource *) res) == WINED3DRTYPE_SURFACE) { - IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res; - if(impl->palette == This) - IWineD3DSurface_RealizePalette((IWineD3DSurface *) res); + if (IWineD3DResource_GetType((IWineD3DResource *)res) == WINED3DRTYPE_SURFACE) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)res; + if (surface->palette == This) + surface->surface_ops->surface_realize_palette(surface); } } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 2e97985a55a..658e3fcf459 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -333,6 +333,64 @@ void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, } } +static void surface_realize_palette(IWineD3DSurfaceImpl *surface) +{ + IWineD3DPaletteImpl *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, SFLAG_INTEXTURE, NULL); + + /* We want to force a palette refresh, so mark the drawable as not being up to date */ + surface_modify_location(surface, SFLAG_INDRAWABLE, FALSE); + } + else + { + if (!(surface->flags & SFLAG_INSYSMEM)) + { + TRACE("Palette changed with surface that does not have an up to date system memory copy.\n"); + surface_load_location(surface, SFLAG_INSYSMEM, NULL); + } + surface_modify_location(surface, SFLAG_INSYSMEM, TRUE); + } + } + + if (surface->flags & SFLAG_DIBSECTION) + { + RGBQUAD col[256]; + unsigned int i; + + TRACE("Updating the DC's palette.\n"); + + for (i = 0; i < 256; ++i) + { + col[i].rgbRed = palette->palents[i].peRed; + col[i].rgbGreen = palette->palents[i].peGreen; + col[i].rgbBlue = palette->palents[i].peBlue; + col[i].rgbReserved = 0; + } + SetDIBColorTable(surface->hDC, 0, 256, col); + } + + /* Propagate the changes to the drawable when we have a palette. */ + if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET) + surface_load_location(surface, SFLAG_INDRAWABLE, NULL); +} + +static const struct wined3d_surface_ops surface_ops = +{ + surface_realize_palette, +}; + HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment, UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, enum wined3d_format_id format_id, @@ -3896,65 +3954,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD return IWineD3DBaseSurfaceImpl_BltFast(iface, dstx, dsty, src_surface, rsrc, trans); } -static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) -{ - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - RGBQUAD col[256]; - IWineD3DPaletteImpl *pal = This->palette; - unsigned int n; - TRACE("(%p)\n", This); - - if (!pal) return WINED3D_OK; - - if (This->resource.format->id == WINED3DFMT_P8_UINT - || This->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM) - { - if (This->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(This, SFLAG_INTEXTURE, NULL); - - /* We want to force a palette refresh, so mark the drawable as not being up to date */ - surface_modify_location(This, SFLAG_INDRAWABLE, FALSE); - } - else - { - if (!(This->flags & SFLAG_INSYSMEM)) - { - TRACE("Palette changed with surface that does not have an up to date system memory copy.\n"); - surface_load_location(This, SFLAG_INSYSMEM, NULL); - } - TRACE("Dirtifying surface\n"); - surface_modify_location(This, SFLAG_INSYSMEM, TRUE); - } - } - - if (This->flags & SFLAG_DIBSECTION) - { - TRACE("(%p): Updating the hdc's palette\n", This); - for (n=0; n<256; n++) { - col[n].rgbRed = pal->palents[n].peRed; - col[n].rgbGreen = pal->palents[n].peGreen; - col[n].rgbBlue = pal->palents[n].peBlue; - col[n].rgbReserved = 0; - } - SetDIBColorTable(This->hDC, 0, 256, col); - } - - /* Propagate the changes to the drawable when we have a palette. */ - if (This->resource.usage & WINED3DUSAGE_RENDERTARGET) - surface_load_location(This, SFLAG_INDRAWABLE, NULL); - - return WINED3D_OK; -} - static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { /** Check against the maximum texture sizes supported by the video card **/ IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; unsigned int pow2Width, pow2Height; + This->surface_ops = &surface_ops; + This->texture_name = 0; This->texture_target = GL_TEXTURE_2D; @@ -4701,7 +4708,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_BltFast, IWineD3DBaseSurfaceImpl_GetPalette, IWineD3DBaseSurfaceImpl_SetPalette, - IWineD3DSurfaceImpl_RealizePalette, IWineD3DBaseSurfaceImpl_SetColorKey, IWineD3DBaseSurfaceImpl_GetPitch, IWineD3DSurfaceImpl_SetMem, diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c index 21c81a25a1f..cad2caf9463 100644 --- a/dlls/wined3d/surface_base.c +++ b/dlls/wined3d/surface_base.c @@ -237,9 +237,10 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD if (This->resource.usage & WINED3DUSAGE_RENDERTARGET) PalImpl->flags |= WINEDDPCAPS_PRIMARYSURFACE; - return IWineD3DSurface_RealizePalette(iface); + This->surface_ops->surface_realize_palette(This); } - else return WINED3D_OK; + + return WINED3D_OK; } HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD flags, const WINEDDCOLORKEY *CKey) diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index dff1c358fa0..c5642852793 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -57,6 +57,49 @@ void surface_gdi_cleanup(IWineD3DSurfaceImpl *This) resource_cleanup((IWineD3DResourceImpl *)This); } +static void gdi_surface_realize_palette(IWineD3DSurfaceImpl *surface) +{ + IWineD3DPaletteImpl *palette = surface->palette; + + TRACE("surface %p.\n", surface); + + if (!palette) return; + + if (surface->flags & SFLAG_DIBSECTION) + { + RGBQUAD col[256]; + unsigned int i; + + TRACE("Updating the DC's palette.\n"); + + for (i = 0; i < 256; ++i) + { + col[i].rgbRed = palette->palents[i].peRed; + col[i].rgbGreen = palette->palents[i].peGreen; + col[i].rgbBlue = palette->palents[i].peBlue; + col[i].rgbReserved = 0; + } + SetDIBColorTable(surface->hDC, 0, 256, col); + } + + /* 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->container.type == WINED3D_CONTAINER_SWAPCHAIN) + { + IWineD3DSwapChainImpl *swapchain = surface->container.u.swapchain; + if (surface == swapchain->front_buffer) + { + x11_copy_to_screen(swapchain, NULL); + } + } +} + +static const struct wined3d_surface_ops gdi_surface_ops = +{ + gdi_surface_realize_palette, +}; + /***************************************************************************** * IWineD3DSurface::Release, GDI version * @@ -290,42 +333,6 @@ static HRESULT WINAPI IWineGDISurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC return WINED3D_OK; } -static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - RGBQUAD col[256]; - IWineD3DPaletteImpl *pal = This->palette; - unsigned int n; - TRACE("(%p)\n", This); - - if (!pal) return WINED3D_OK; - - if (This->flags & SFLAG_DIBSECTION) - { - TRACE("(%p): Updating the hdc's palette\n", This); - for (n=0; n<256; n++) { - col[n].rgbRed = pal->palents[n].peRed; - col[n].rgbGreen = pal->palents[n].peGreen; - col[n].rgbBlue = pal->palents[n].peBlue; - col[n].rgbReserved = 0; - } - SetDIBColorTable(This->hDC, 0, 256, col); - } - - /* 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 (This->container.type == WINED3D_CONTAINER_SWAPCHAIN) - { - IWineD3DSwapChainImpl *swapchain = This->container.u.swapchain; - if (This == swapchain->front_buffer) - { - x11_copy_to_screen(swapchain, NULL); - } - } - - return WINED3D_OK; -} - /***************************************************************************** * IWineD3DSurface::PrivateSetup, GDI version * @@ -349,6 +356,8 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3DSurface *iface) IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; HRESULT hr; + This->surface_ops = &gdi_surface_ops; + if(This->resource.usage & WINED3DUSAGE_OVERLAY) { ERR("(%p) Overlays not yet supported by GDI surfaces\n", This); @@ -469,7 +478,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl = IWineD3DBaseSurfaceImpl_BltFast, IWineD3DBaseSurfaceImpl_GetPalette, IWineD3DBaseSurfaceImpl_SetPalette, - IWineGDISurfaceImpl_RealizePalette, IWineD3DBaseSurfaceImpl_SetColorKey, IWineD3DBaseSurfaceImpl_GetPitch, IWineGDISurfaceImpl_SetMem, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 66532e6c4aa..68e4734f67e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2088,6 +2088,11 @@ struct wined3d_subresource_container } u; }; +struct wined3d_surface_ops +{ + void (*surface_realize_palette)(struct IWineD3DSurfaceImpl *surface); +}; + /***************************************************************************** * IWineD3DSurface implementation structure */ @@ -2098,6 +2103,7 @@ struct IWineD3DSurfaceImpl IWineD3DResourceClass resource; /* IWineD3DSurface fields */ + const struct wined3d_surface_ops *surface_ops; struct wined3d_subresource_container container; WINED3DSURFACET_DESC currentDesc; IWineD3DPaletteImpl *palette; /* D3D7 style palette handling */ diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index 585932b6bcf..b99fb4d8158 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -2426,8 +2426,6 @@ interface IWineD3DSurface : IWineD3DResource HRESULT SetPalette( [in] IWineD3DPalette *palette ); - HRESULT RealizePalette( - ); HRESULT SetColorKey( [in] DWORD flags, [in] const WINEDDCOLORKEY *color_key