Stefan Dösinger : ddraw: Palette refcounting fixes + tests.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 19 03:35:27 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 01273e7eb67a7bd918a246e0d76f36fd628f6a34
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=01273e7eb67a7bd918a246e0d76f36fd628f6a34
Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date: Sat Jun 17 15:47:52 2006 +0200
ddraw: Palette refcounting fixes + tests.
---
dlls/ddraw/ddraw.c | 21 +++++-
dlls/ddraw/palette.c | 1
dlls/ddraw/surface.c | 4 +
dlls/ddraw/tests/.gitignore | 1
dlls/ddraw/tests/Makefile.in | 3 +
dlls/ddraw/tests/refcount.c | 147 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 174 insertions(+), 3 deletions(-)
create mode 100644 dlls/ddraw/tests/refcount.c
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index cdf4d46..5fad1cd 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2950,13 +2950,29 @@ IDirectDrawImpl_CreatePalette(IDirectDra
HRESULT hr = DDERR_GENERIC;
TRACE("(%p)->(%lx,%p,%p,%p)\n", This, Flags, ColorTable, Palette, pUnkOuter);
- if(pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */
+ if(pUnkOuter != NULL)
+ {
+ WARN("pUnkOuter is %p, returning CLASS_E_NOAGGREGATION\n", pUnkOuter);
+ return CLASS_E_NOAGGREGATION;
+ }
+
+ /* The refcount test shows that a cooplevel is required for this */
+ if(!This->cooperative_level)
+ {
+ WARN("No cooperative level set, returning DDERR_NOCOOPERATIVELEVELSET\n");
+ return DDERR_NOCOOPERATIVELEVELSET;
+ }
object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
- if(!object) return E_OUTOFMEMORY;
+ if(!object)
+ {
+ ERR("Out of memory when allocating memory for a palette implementation\n");
+ return E_OUTOFMEMORY;
+ }
ICOM_INIT_INTERFACE(object, IDirectDrawPalette, IDirectDrawPalette_Vtbl);
object->ref = 1;
+ object->ddraw_owner = This;
hr = IWineD3DDevice_CreatePalette(This->wineD3DDevice, Flags, ColorTable, &object->wineD3DPalette, (IUnknown *) ICOM_INTERFACE(object, IDirectDrawPalette) );
if(hr != DD_OK)
@@ -2965,6 +2981,7 @@ IDirectDrawImpl_CreatePalette(IDirectDra
return hr;
}
+ IDirectDraw7_AddRef(iface);
*Palette = ICOM_INTERFACE(object, IDirectDrawPalette);
return DD_OK;
}
diff --git a/dlls/ddraw/palette.c b/dlls/ddraw/palette.c
index 66b8844..97a9ef4 100644
--- a/dlls/ddraw/palette.c
+++ b/dlls/ddraw/palette.c
@@ -104,6 +104,7 @@ IDirectDrawPaletteImpl_Release(IDirectDr
if (ref == 0)
{
IWineD3DPalette_Release(This->wineD3DPalette);
+ IDirectDraw7_Release(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7));
HeapFree(GetProcessHeap(), 0, This);
}
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 212b9b3..5590c80 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -360,6 +360,10 @@ IDirectDrawSurfaceImpl_Release(IDirectDr
}
}
+ /* The refcount test shows that the palette is detached when the surface is destroyed */
+ IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(This, IDirectDrawSurface7),
+ NULL);
+
/* Loop through all complex attached surfaces,
* and destroy them
*/
diff --git a/dlls/ddraw/tests/.gitignore b/dlls/ddraw/tests/.gitignore
index 7daa343..348040a 100644
--- a/dlls/ddraw/tests/.gitignore
+++ b/dlls/ddraw/tests/.gitignore
@@ -2,4 +2,5 @@ Makefile
d3d.ok
ddrawmodes.ok
dsurface.ok
+refcount.ok
testlist.c
diff --git a/dlls/ddraw/tests/Makefile.in b/dlls/ddraw/tests/Makefile.in
index d6fc8b1..ec8488f 100644
--- a/dlls/ddraw/tests/Makefile.in
+++ b/dlls/ddraw/tests/Makefile.in
@@ -9,7 +9,8 @@ EXTRALIBS = -ldxguid
CTESTS = \
d3d.c \
ddrawmodes.c \
- dsurface.c
+ dsurface.c \
+ refcount.c
@MAKE_TEST_RULES@
diff --git a/dlls/ddraw/tests/refcount.c b/dlls/ddraw/tests/refcount.c
new file mode 100644
index 0000000..466868e
--- /dev/null
+++ b/dlls/ddraw/tests/refcount.c
@@ -0,0 +1,147 @@
+/*
+ * Some unit tests for ddraw reference counting
+ *
+ * Copyright (C) 2006 Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#define COBJMACROS
+
+#include <assert.h>
+#include "wine/test.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "unknwn.h"
+
+static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
+
+static void init_function_pointers(void)
+{
+ HMODULE hmod = GetModuleHandleA("ddraw.dll");
+
+ if(hmod)
+ {
+ pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
+ }
+}
+
+unsigned long getRefcount(IUnknown *iface)
+{
+ IUnknown_AddRef(iface);
+ return IUnknown_Release(iface);
+}
+
+static void test_ddraw(void)
+{
+ HRESULT hr;
+ unsigned long ref;
+ IDirectDraw7 *DDraw;
+ IDirectDrawPalette *palette;
+ IDirectDrawSurface7 *surface;
+ PALETTEENTRY Table[256];
+ DDSURFACEDESC2 ddsd;
+
+ hr = pDirectDrawCreateEx(NULL, (void **) &DDraw, &IID_IDirectDraw7, NULL);
+ ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", hr);
+ if(!DDraw)
+ {
+ trace("Couldn't create DDraw interface, skipping tests\n");
+ return;
+ }
+
+ ref = getRefcount( (IUnknown *) DDraw);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ /* Fails without a cooplevel */
+ hr = IDirectDraw7_CreatePalette(DDraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
+ ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08lx\n", hr);
+
+ /* This check is before the cooplevel check */
+ hr = IDirectDraw7_CreatePalette(DDraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
+ ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08lx\n", hr);
+
+ hr = IDirectDraw7_SetCooperativeLevel(DDraw, 0, DDSCL_NORMAL);
+ ok(hr == DD_OK, "SetCooperativeLevel failed with %08lx\n", hr);
+
+ memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+ ddsd.dwWidth = 64;
+ ddsd.dwHeight = 64;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
+ ddsd.ddpfPixelFormat.dwRGBBitCount = 8;
+
+ hr = IDirectDraw7_CreateSurface(DDraw, &ddsd, &surface, NULL);
+ ok(hr == DD_OK, "CreateSurface failed with %08lx\n", hr);
+
+ /* DDraw refcount increased by 1 */
+ ref = getRefcount( (IUnknown *) DDraw);
+ ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
+
+ /* Surface refcount starts with 1 */
+ ref = getRefcount( (IUnknown *) surface);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ hr = IDirectDraw7_CreatePalette(DDraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
+ ok(hr == DD_OK, "CreatePalette returned %08lx\n", hr);
+
+ /* DDraw refcount increased by 1 */
+ ref = getRefcount( (IUnknown *) DDraw);
+ ok(ref == 3, "Got refcount %ld, expected 3\n", ref);
+
+ /* Palette starts with 1 */
+ ref = getRefcount( (IUnknown *) palette);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ /* Test attaching a palette to a surface */
+ hr = IDirectDrawSurface7_SetPalette(surface, palette);
+ ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08lx\n", hr);
+
+ /* Palette refcount increased, surface stays the same */
+ ref = getRefcount( (IUnknown *) palette);
+ ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
+ ref = getRefcount( (IUnknown *) surface);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ IDirectDrawSurface7_Release(surface);
+ /* Incresed before - decrease now */
+ ref = getRefcount( (IUnknown *) DDraw);
+ ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
+
+ /* Releasing the surface detaches the palette */
+ ref = getRefcount( (IUnknown *) palette);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ IDirectDrawPalette_Release(palette);
+
+ /* Incresed before - decrease now */
+ ref = getRefcount( (IUnknown *) DDraw);
+ ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
+
+ IDirectDraw7_Release(DDraw);
+}
+
+START_TEST(refcount)
+{
+ init_function_pointers();
+ if(!pDirectDrawCreateEx)
+ {
+ trace("function DirectDrawCreateEx not available, skipping tests\n");
+ return;
+ }
+ test_ddraw();
+}
More information about the wine-cvs
mailing list