ddraw: Keep a reference to the palette in the surface.

This commit is contained in:
Henri Verbeet 2013-12-12 10:23:30 +01:00 committed by Alexandre Julliard
parent 27dc41d0dc
commit 1f0bb534ec
7 changed files with 40 additions and 95 deletions

View File

@ -178,6 +178,7 @@ struct ddraw_surface
/* Clipper objects */ /* Clipper objects */
struct ddraw_clipper *clipper; struct ddraw_clipper *clipper;
struct ddraw_palette *palette;
/* For the ddraw surface list */ /* For the ddraw surface list */
struct list surface_list_entry; struct list surface_list_entry;

View File

@ -258,9 +258,7 @@ HRESULT ddraw_palette_init(struct ddraw_palette *palette,
palette->IDirectDrawPalette_iface.lpVtbl = &ddraw_palette_vtbl; palette->IDirectDrawPalette_iface.lpVtbl = &ddraw_palette_vtbl;
palette->ref = 1; palette->ref = 1;
hr = wined3d_palette_create(ddraw->wined3d_device, flags, if (FAILED(hr = wined3d_palette_create(ddraw->wined3d_device, flags, entries, &palette->wineD3DPalette)))
entries, palette, &palette->wineD3DPalette);
if (FAILED(hr))
{ {
WARN("Failed to create wined3d palette, hr %#x.\n", hr); WARN("Failed to create wined3d palette, hr %#x.\n", hr);
return hr; return hr;

View File

@ -4463,46 +4463,28 @@ static HRESULT WINAPI ddraw_surface3_SetSurfaceDesc(IDirectDrawSurface3 *iface,
surface_desc ? &surface_desc2 : NULL, flags); surface_desc ? &surface_desc2 : NULL, flags);
} }
/***************************************************************************** static HRESULT WINAPI ddraw_surface7_GetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette **palette)
* IDirectDrawSurface7::GetPalette
*
* Returns the IDirectDrawPalette interface of the palette currently assigned
* to the surface
*
* Params:
* Pal: Address to write the interface pointer to
*
* Returns:
* DD_OK on success
* DDERR_INVALIDPARAMS if Pal is NULL
*
*****************************************************************************/
static HRESULT WINAPI ddraw_surface7_GetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette **Pal)
{ {
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
struct wined3d_palette *wined3d_palette;
struct ddraw_palette *palette_impl; struct ddraw_palette *palette_impl;
HRESULT hr = DD_OK; HRESULT hr = DD_OK;
TRACE("iface %p, palette %p.\n", iface, Pal); TRACE("iface %p, palette %p.\n", iface, palette);
if(!Pal) if (!palette)
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
wined3d_mutex_lock(); wined3d_mutex_lock();
wined3d_palette = wined3d_surface_get_palette(surface->wined3d_surface); if ((palette_impl = surface->palette))
if (wined3d_palette)
{ {
palette_impl = wined3d_palette_get_parent(wined3d_palette); *palette = &palette_impl->IDirectDrawPalette_iface;
*Pal = &palette_impl->IDirectDrawPalette_iface; IDirectDrawPalette_AddRef(*palette);
IDirectDrawPalette_AddRef(*Pal);
} }
else else
{ {
*Pal = NULL; *palette = NULL;
hr = DDERR_NOPALETTEATTACHED; hr = DDERR_NOPALETTEATTACHED;
} }
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return hr; return hr;
@ -4708,86 +4690,61 @@ static HRESULT WINAPI ddraw_surface1_SetColorKey(IDirectDrawSurface *iface, DWOR
return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key); return ddraw_surface7_SetColorKey(&surface->IDirectDrawSurface7_iface, flags, color_key);
} }
/***************************************************************************** static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette *palette)
* IDirectDrawSurface7::SetPalette
*
* Assigns a DirectDrawPalette object to the surface
*
* Params:
* Pal: Interface to the palette to set
*
* Returns:
* DD_OK on success
*
*****************************************************************************/
static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette *Pal)
{ {
struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
struct ddraw_palette *palette_impl = unsafe_impl_from_IDirectDrawPalette(Pal); struct ddraw_palette *palette_impl = unsafe_impl_from_IDirectDrawPalette(palette);
IDirectDrawPalette *oldPal; struct ddraw_palette *prev;
struct ddraw_surface *surf;
HRESULT hr; HRESULT hr;
TRACE("iface %p, palette %p.\n", iface, Pal); TRACE("iface %p, palette %p.\n", iface, palette);
if (!(This->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | if (!(surface->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) { | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8)))
return DDERR_INVALIDPIXELFORMAT; return DDERR_INVALIDPIXELFORMAT;
}
if (This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) if (surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
{
return DDERR_NOTONMIPMAPSUBLEVEL; return DDERR_NOTONMIPMAPSUBLEVEL;
}
/* Find the old palette */
wined3d_mutex_lock(); wined3d_mutex_lock();
hr = IDirectDrawSurface_GetPalette(iface, &oldPal);
if(hr != DD_OK && hr != DDERR_NOPALETTEATTACHED)
{
wined3d_mutex_unlock();
return hr;
}
if(oldPal) IDirectDrawPalette_Release(oldPal); /* For the GetPalette */
/* Set the new Palette */ prev = surface->palette;
wined3d_surface_set_palette(This->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL); if (palette_impl)
/* AddRef the Palette */ IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
if(Pal) IDirectDrawPalette_AddRef(Pal); if (prev)
IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
/* Release the old palette */ surface->palette = palette_impl;
if(oldPal) IDirectDrawPalette_Release(oldPal); wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL);
/* Update the wined3d frontbuffer if this is the primary. */ /* Update the wined3d frontbuffer if this is the primary. */
if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_frontbuffer) if ((surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && surface->ddraw->wined3d_frontbuffer)
wined3d_surface_set_palette(This->ddraw->wined3d_frontbuffer, wined3d_surface_set_palette(surface->ddraw->wined3d_frontbuffer,
palette_impl ? palette_impl->wineD3DPalette : NULL); palette_impl ? palette_impl->wineD3DPalette : NULL);
/* If this is a front buffer, also update the back buffers /* If this is a front buffer, also update the back buffers
* TODO: How do things work for palettized cube textures? * TODO: How do things work for palettized cube textures? */
*/ if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
{ {
/* For primary surfaces the tree is just a list, so the simpler scheme fits too */ /* For primary surfaces the tree is just a list, so the simpler scheme fits too */
DDSCAPS2 caps2 = { DDSCAPS_FLIP, 0, 0, 0 }; DDSCAPS2 caps2 = { DDSCAPS_FLIP, 0, 0, 0 };
struct ddraw_surface *current = surface;
surf = This;
for (;;) for (;;)
{ {
IDirectDrawSurface7 *attach; IDirectDrawSurface7 *attach;
if (FAILED(hr = ddraw_surface7_GetAttachedSurface(&surf->IDirectDrawSurface7_iface, &caps2, &attach))) if (FAILED(hr = ddraw_surface7_GetAttachedSurface(&current->IDirectDrawSurface7_iface, &caps2, &attach)))
break; break;
surf = impl_from_IDirectDrawSurface7(attach); current = impl_from_IDirectDrawSurface7(attach);
if (surf == This) if (current == surface)
{ {
ddraw_surface7_Release(attach); ddraw_surface7_Release(attach);
break; break;
} }
TRACE("Setting palette on %p.\n", attach); TRACE("Setting palette on %p.\n", attach);
ddraw_surface7_SetPalette(attach, Pal); ddraw_surface7_SetPalette(attach, palette);
ddraw_surface7_Release(attach); ddraw_surface7_Release(attach);
} }
} }

View File

@ -152,20 +152,12 @@ DWORD CDECL wined3d_palette_get_flags(const struct wined3d_palette *palette)
return palette->flags; return palette->flags;
} }
void * CDECL wined3d_palette_get_parent(const struct wined3d_palette *palette)
{
TRACE("palette %p.\n", palette);
return palette->parent;
}
static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device, static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device,
DWORD flags, const PALETTEENTRY *entries, void *parent) DWORD flags, const PALETTEENTRY *entries)
{ {
HRESULT hr; HRESULT hr;
palette->ref = 1; palette->ref = 1;
palette->parent = parent;
palette->device = device; palette->device = device;
palette->flags = flags; palette->flags = flags;
@ -189,19 +181,19 @@ static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wine
} }
HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags, HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags,
const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette) const PALETTEENTRY *entries, struct wined3d_palette **palette)
{ {
struct wined3d_palette *object; struct wined3d_palette *object;
HRESULT hr; HRESULT hr;
TRACE("device %p, flags %#x, entries %p, palette %p, parent %p.\n", TRACE("device %p, flags %#x, entries %p, palette %p.\n",
device, flags, entries, palette, parent); device, flags, entries, palette);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object) if (!object)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
hr = wined3d_palette_init(object, device, flags, entries, parent); hr = wined3d_palette_init(object, device, flags, entries);
if (FAILED(hr)) if (FAILED(hr))
{ {
WARN("Failed to initialize palette, hr %#x.\n", hr); WARN("Failed to initialize palette, hr %#x.\n", hr);

View File

@ -156,11 +156,10 @@
@ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_update_texture(ptr ptr ptr)
@ cdecl wined3d_device_validate_device(ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr)
@ cdecl wined3d_palette_create(ptr long ptr ptr ptr) @ cdecl wined3d_palette_create(ptr long ptr ptr)
@ cdecl wined3d_palette_decref(ptr) @ cdecl wined3d_palette_decref(ptr)
@ cdecl wined3d_palette_get_entries(ptr long long long ptr) @ cdecl wined3d_palette_get_entries(ptr long long long ptr)
@ cdecl wined3d_palette_get_flags(ptr) @ cdecl wined3d_palette_get_flags(ptr)
@ cdecl wined3d_palette_get_parent(ptr)
@ cdecl wined3d_palette_incref(ptr) @ cdecl wined3d_palette_incref(ptr)
@ cdecl wined3d_palette_set_entries(ptr long long long ptr) @ cdecl wined3d_palette_set_entries(ptr long long long ptr)

View File

@ -2944,7 +2944,6 @@ struct ps_np2fixup_info {
struct wined3d_palette struct wined3d_palette
{ {
LONG ref; LONG ref;
void *parent;
struct wined3d_device *device; struct wined3d_device *device;
HPALETTE hpal; HPALETTE hpal;

View File

@ -2235,12 +2235,11 @@ HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device,
HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes);
HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags, HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags,
const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette); const PALETTEENTRY *entries, struct wined3d_palette **palette);
ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette); ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette);
HRESULT __cdecl wined3d_palette_get_entries(const struct wined3d_palette *palette, HRESULT __cdecl wined3d_palette_get_entries(const struct wined3d_palette *palette,
DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries); DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries);
DWORD __cdecl wined3d_palette_get_flags(const struct wined3d_palette *palette); DWORD __cdecl wined3d_palette_get_flags(const struct wined3d_palette *palette);
void * __cdecl wined3d_palette_get_parent(const struct wined3d_palette *palette);
ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette); ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette);
HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette, HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette,
DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries); DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries);