[PATCH 3/5] ddraw/tests: Handle a backbuffer palette misbehavior on Windows 8.

Stefan Dösinger stefan at codeweavers.com
Mon Apr 28 08:21:56 CDT 2014


The Windows 8 testbot machines have plenty of bugs when handling P8
primaries. The most obvious among them is that the palette is assigned
to the backbuffer as well, but when digging deeper more serious
refcounting bugs show up. Unfortunately I don't have a non-tb Win8
machine to compare to. Calling backbuffer->SetPalette(NULL) unsets it
from the frontbuffer as well.

I originally thought this behavior occurred only on the testbot and not
real machines. This was a misunderstanding of the test.winehq.org info.
fg-acer64-w8* doesn't properly run the tests because it refuses to set
8 bpp display modes.

I checked that ddraw1 and 2 do not silently AddRef ddraw4 and/or 7. This
part of the refcounting works, but the surface refcount is still too
high.
---
 dlls/ddraw/tests/ddraw1.c | 28 ++++++++++++++++++++++++++--
 dlls/ddraw/tests/ddraw2.c | 28 ++++++++++++++++++++++++++--
 dlls/ddraw/tests/ddraw4.c | 28 ++++++++++++++++++++++++++--
 dlls/ddraw/tests/ddraw7.c | 28 ++++++++++++++++++++++++++--
 4 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index b62d351..65f56c2 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -3987,6 +3987,32 @@ static void test_primary_palette(void)
 
     hr = IDirectDrawSurface_SetPalette(primary, palette);
     ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+
+    hr = IDirectDrawSurface_GetPalette(backbuffer, &tmp);
+    ok(hr == DDERR_NOPALETTEATTACHED || broken(SUCCEEDED(hr)), "Got unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        /* Windows 8 attaches the palette to the backbuffer. Earlier Windows versions do not.
+         * The same windows version has more issues: The GetPalette call after stealing the
+         * reference crashes. The primary has an extra reference after creation call, making
+         * it tricky to destroy. Unlike its counterparts in ddraw4 and ddraw7, this version
+         * does not add and forget to release extra references to the ddraw interface. */
+        win_skip("SetPalette badness detected, skipping test.\n");
+
+        IDirectDrawPalette_Release(tmp);
+        hr = IDirectDrawSurface_SetPalette(primary, NULL);
+        ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+        refcount = IDirectDrawPalette_Release(palette);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+        IDirectDrawSurface_Release(backbuffer);
+        while (IDirectDrawSurface_Release(primary));
+        refcount = IDirectDraw_Release(ddraw);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+        DestroyWindow(window);
+        return;
+    }
+
     refcount = get_refcount((IUnknown *)palette);
     ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
@@ -4013,8 +4039,6 @@ static void test_primary_palette(void)
     ok(SUCCEEDED(hr), "Failed to get palette, hr %#x.\n", hr);
     ok(tmp == palette, "Got unexpected palette %p, expected %p.\n", tmp, palette);
     IDirectDrawPalette_Release(tmp);
-    hr = IDirectDrawSurface_GetPalette(backbuffer, &tmp);
-    ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr);
 
     refcount = IDirectDrawPalette_Release(palette);
     ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index ce3be71..4129de0 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -5092,6 +5092,32 @@ static void test_primary_palette(void)
 
     hr = IDirectDrawSurface_SetPalette(primary, palette);
     ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+
+    hr = IDirectDrawSurface_GetPalette(backbuffer, &tmp);
+    ok(hr == DDERR_NOPALETTEATTACHED || broken(SUCCEEDED(hr)), "Got unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        /* Windows 8 attaches the palette to the backbuffer. Earlier Windows versions do not.
+         * The same windows version has more issues: The GetPalette call after stealing the
+         * reference crashes. The primary has an extra reference after creation call, making
+         * it tricky to destroy. Unlike its counterparts in ddraw4 and ddraw7, this version
+         * does not add and forget to release extra references to the ddraw interface. */
+        win_skip("SetPalette badness detected, skipping test.\n");
+
+        IDirectDrawPalette_Release(tmp);
+        hr = IDirectDrawSurface_SetPalette(primary, NULL);
+        ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+        refcount = IDirectDrawPalette_Release(palette);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+        IDirectDrawSurface_Release(backbuffer);
+        while (IDirectDrawSurface_Release(primary));
+        refcount = IDirectDraw2_Release(ddraw);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+        DestroyWindow(window);
+        return;
+    }
+
     refcount = get_refcount((IUnknown *)palette);
     ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
@@ -5118,8 +5144,6 @@ static void test_primary_palette(void)
     ok(SUCCEEDED(hr), "Failed to get palette, hr %#x.\n", hr);
     ok(tmp == palette, "Got unexpected palette %p, expected %p.\n", tmp, palette);
     IDirectDrawPalette_Release(tmp);
-    hr = IDirectDrawSurface_GetPalette(backbuffer, &tmp);
-    ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr);
 
     refcount = IDirectDrawPalette_Release(palette);
     ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 68f32ee..205fb57 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -5752,6 +5752,32 @@ static void test_primary_palette(void)
 
     hr = IDirectDrawSurface4_SetPalette(primary, palette);
     ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+
+    hr = IDirectDrawSurface4_GetPalette(backbuffer, &tmp);
+    ok(hr == DDERR_NOPALETTEATTACHED || broken(SUCCEEDED(hr)), "Got unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        /* Windows 8 attaches the palette to the backbuffer. Earlier Windows versions do not.
+         * The same windows version has more issues: The GetPalette call after stealing the
+         * reference crashes. The primary has an extra reference after creation call, making
+         * it tricky to destroy. Creating the primary adds 5 references to the ddraw interface,
+         * 4 of which are not properly released. Under these circumstances there's no point in
+         * running the rest of the test. Clean up as good as we can and get out. */
+        win_skip("SetPalette badness detected, skipping test.\n");
+
+        IDirectDrawPalette_Release(tmp);
+        hr = IDirectDrawSurface4_SetPalette(primary, NULL);
+        ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+        refcount = IDirectDrawPalette_Release(palette);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+        IDirectDrawSurface4_Release(backbuffer);
+        while (IDirectDrawSurface4_Release(primary));
+        while (IDirectDraw4_Release(ddraw));
+        DestroyWindow(window);
+        return;
+    }
+
     refcount = get_refcount((IUnknown *)palette);
     ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
@@ -5778,8 +5804,6 @@ static void test_primary_palette(void)
     ok(SUCCEEDED(hr), "Failed to get palette, hr %#x.\n", hr);
     ok(tmp == palette, "Got unexpected palette %p, expected %p.\n", tmp, palette);
     IDirectDrawPalette_Release(tmp);
-    hr = IDirectDrawSurface4_GetPalette(backbuffer, &tmp);
-    ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr);
 
     refcount = IDirectDrawPalette_Release(palette);
     ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index bed5cb8..d6f9d13 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -5631,6 +5631,32 @@ static void test_primary_palette(void)
 
     hr = IDirectDrawSurface7_SetPalette(primary, palette);
     ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+
+    hr = IDirectDrawSurface7_GetPalette(backbuffer, &tmp);
+    ok(hr == DDERR_NOPALETTEATTACHED || broken(SUCCEEDED(hr)), "Got unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        /* Windows 8 attaches the palette to the backbuffer. Earlier Windows versions do not.
+         * The same windows version has more issues: The GetPalette call after stealing the
+         * reference crashes. The primary has an extra reference after creation call, making
+         * it tricky to destroy. Creating the primary adds 5 references to the ddraw interface,
+         * 4 of which are not properly released. Under these circumstances there's no point in
+         * running the rest of the test. Clean up as good as we can and get out. */
+        win_skip("SetPalette badness detected, skipping test.\n");
+
+        IDirectDrawPalette_Release(tmp);
+        hr = IDirectDrawSurface7_SetPalette(primary, NULL);
+        ok(SUCCEEDED(hr), "Failed to set palette, hr %#x.\n", hr);
+        refcount = IDirectDrawPalette_Release(palette);
+        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
+
+        IDirectDrawSurface7_Release(backbuffer);
+        while (IDirectDrawSurface7_Release(primary));
+        while (IDirectDraw7_Release(ddraw));
+        DestroyWindow(window);
+        return;
+    }
+
     refcount = get_refcount((IUnknown *)palette);
     ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
@@ -5657,8 +5683,6 @@ static void test_primary_palette(void)
     ok(SUCCEEDED(hr), "Failed to get palette, hr %#x.\n", hr);
     ok(tmp == palette, "Got unexpected palette %p, expected %p.\n", tmp, palette);
     IDirectDrawPalette_Release(tmp);
-    hr = IDirectDrawSurface7_GetPalette(backbuffer, &tmp);
-    ok(hr == DDERR_NOPALETTEATTACHED, "Got unexpected hr %#x.\n", hr);
 
     refcount = IDirectDrawPalette_Release(palette);
     ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
-- 
1.8.3.2




More information about the wine-patches mailing list