[PATCH 1/4] ddraw: Never consider system memory surface lost.
Paul Gofman
gofmanp at gmail.com
Mon Apr 13 05:40:12 CDT 2020
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48923
Fixes a regression triggered by 530a3d94de949030f8d74bacd6c20986b32f1a31.
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
dlls/ddraw/ddraw.c | 2 +-
dlls/ddraw/surface.c | 3 ++-
dlls/ddraw/tests/ddraw7.c | 54 ++++++++++++++++++++++++++++++++++++---
3 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 95e9fba901..c6a94088cb 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4899,7 +4899,7 @@ void ddraw_update_lost_surfaces(struct ddraw *ddraw)
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
{
- surface->is_lost = TRUE;
+ surface->is_lost = !(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY);
}
ddraw->device_state = DDRAW_DEVICE_STATE_OK;
}
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 20143891d3..53617bb9ab 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -35,7 +35,8 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra
static BOOL ddraw_surface_is_lost(const struct ddraw_surface *surface)
{
- return surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost;
+ return !(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
+ && (surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost);
}
/* This is slow, of course. Also, in case of locks, we can't prevent other
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index e44308761b..d3ea36e980 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -9269,6 +9269,7 @@ static void test_vb_writeonly(void)
static void test_lost_device(void)
{
IDirectDrawSurface7 *surface, *back_buffer;
+ IDirectDrawSurface7 *sysmem_surface;
DDSURFACEDESC2 surface_desc;
HWND window1, window2;
IDirectDraw7 *ddraw;
@@ -9284,7 +9285,7 @@ static void test_lost_device(void)
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
@@ -9292,7 +9293,16 @@ static void test_lost_device(void)
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
U5(surface_desc).dwBackBufferCount = 1;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
- ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+ surface_desc.dwWidth = 100;
+ surface_desc.dwHeight = 100;
+ hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &sysmem_surface, NULL);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_TestCooperativeLevel(ddraw);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9300,6 +9310,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ret = SetForegroundWindow(GetDesktopWindow());
ok(ret, "Failed to set foreground window.\n");
@@ -9309,6 +9321,8 @@ static void test_lost_device(void)
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ret = SetForegroundWindow(window1);
ok(ret, "Failed to set foreground window.\n");
@@ -9318,6 +9332,8 @@ static void test_lost_device(void)
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9327,6 +9343,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9336,6 +9354,8 @@ static void test_lost_device(void)
todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
/* Trying to restore the primary will crash, probably because flippable
* surfaces can't exist in DDSCL_NORMAL. */
@@ -9345,12 +9365,16 @@ static void test_lost_device(void)
surface_desc.dwFlags = DDSD_CAPS;
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
- ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_TestCooperativeLevel(ddraw);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(surface);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ret = SetForegroundWindow(GetDesktopWindow());
ok(ret, "Failed to set foreground window.\n");
@@ -9358,6 +9382,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(surface);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
ret = SetForegroundWindow(window1);
ok(ret, "Failed to set foreground window.\n");
@@ -9365,6 +9391,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(surface);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9372,6 +9400,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(surface);
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9379,6 +9409,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(surface);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
IDirectDrawSurface7_Release(surface);
memset(&surface_desc, 0, sizeof(surface_desc));
@@ -9387,7 +9419,7 @@ static void test_lost_device(void)
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
U5(surface_desc).dwBackBufferCount = 1;
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
- ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9397,6 +9429,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9406,6 +9440,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9415,6 +9451,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9424,6 +9462,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9433,6 +9473,8 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
@@ -9442,6 +9484,8 @@ static void test_lost_device(void)
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT);
ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
+ hr = IDirectDrawSurface7_IsLost(sysmem_surface);
+ ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
memset(&caps, 0, sizeof(caps));
caps.dwCaps = DDSCAPS_FLIP;
@@ -9454,8 +9498,10 @@ static void test_lost_device(void)
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface7_IsLost(back_buffer);
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
+
IDirectDrawSurface7_Release(back_buffer);
+ IDirectDrawSurface7_Release(sysmem_surface);
IDirectDrawSurface7_Release(surface);
refcount = IDirectDraw7_Release(ddraw);
ok(!refcount, "Got unexpected refcount %u.\n", refcount);
--
2.25.2
More information about the wine-devel
mailing list