[RFC PATCH 2/5] user32/tests: Add Direct3D window surface tests.
Giovanni Mascellani
gmascellani at codeweavers.com
Tue May 18 09:44:10 CDT 2021
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
dlls/user32/tests/Makefile.in | 2 +-
dlls/user32/tests/win.c | 216 +++++++++++++++++++++++++++++++++-
2 files changed, 213 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in
index 5b058b7d914..326c44528ec 100644
--- a/dlls/user32/tests/Makefile.in
+++ b/dlls/user32/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = user32.dll
-IMPORTS = user32 gdi32 advapi32 hid dwmapi
+IMPORTS = user32 gdi32 advapi32 hid dwmapi d3d9
C_SRCS = \
broadcast.c \
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 6f9c566a651..b0796e4babd 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -32,6 +32,7 @@
#include "winuser.h"
#include "winreg.h"
#include "dwmapi.h"
+#include "d3d9.h"
#include "wine/test.h"
@@ -12189,6 +12190,57 @@ static void check_client_surface_(int line, HWND hwnd, const DWORD *expect, SIZE
free(data);
}
+struct d3d9_context
+{
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+};
+
+static struct d3d9_context *create_d3d9_context(HWND hwnd)
+{
+ D3DPRESENT_PARAMETERS params;
+ struct d3d9_context *ctx;
+ HRESULT hr;
+ RECT rect;
+
+ if (!(ctx = malloc(sizeof(struct d3d9_context)))) return NULL;
+ ctx->d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(ctx->d3d != NULL, "Direct3DCreate9 failed, last error %u\n", GetLastError());
+
+ GetClientRect(hwnd, &rect);
+ OffsetRect(&rect, -rect.left, -rect.top);
+
+ memset(¶ms, 0, sizeof(params));
+ params.Windowed = TRUE;
+ params.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ params.hDeviceWindow = hwnd;
+ params.BackBufferFormat = D3DFMT_X8R8G8B8;
+ params.BackBufferWidth = rect.right;
+ params.BackBufferHeight = rect.bottom;
+
+ hr = IDirect3D9_CreateDevice(ctx->d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, &ctx->device);
+ ok(hr == S_OK, "IDirect3D9_CreateDevice returned %#x\n", hr);
+
+ return ctx;
+}
+
+static void paint_d3d9_client_rect(struct d3d9_context *ctx, DWORD color)
+{
+ HRESULT hr;
+ hr = IDirect3DDevice9_Clear(ctx->device, 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0);
+ ok(hr == S_OK, "IDirect3DDevice9_Clear returned %#x\n", hr);
+ hr = IDirect3DDevice9_Present(ctx->device, NULL, NULL, NULL, NULL);
+ ok(hr == S_OK, "IDirect3DDevice9_Present returned %#x\n", hr);
+}
+
+static void destroy_d3d9_context(struct d3d9_context *ctx)
+{
+ IDirect3DDevice9_Release(ctx->device);
+ IDirect3D9_Release(ctx->d3d);
+ free(ctx);
+}
+
static void paint_client_rect(HWND hwnd, COLORREF color)
{
HDC hdc = GetDC(hwnd);
@@ -12226,6 +12278,8 @@ static void test_surface_composition(void)
{
#define COLOR1 0x00ff0000
#define COLOR2 0x0000ffff
+#define COLOR3 0x00ff00ff
+#define COLOR4 0x00ffff00
#define BGRA2RGB(x) RGB((x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff)
static const DWORD minimized_surface[] =
{
@@ -12252,6 +12306,27 @@ static void test_surface_composition(void)
COLOR1, COLOR1, COLOR1, COLOR1,
COLOR1, COLOR1, COLOR1, COLOR1,
};
+ static const DWORD painted_surface2[] =
+ {
+ COLOR2, COLOR2, COLOR2, COLOR2,
+ COLOR2, COLOR2, COLOR2, COLOR2,
+ COLOR2, COLOR2, COLOR2, COLOR2,
+ COLOR2, COLOR2, COLOR2, COLOR2,
+ };
+ static const DWORD painted_surface3[] =
+ {
+ COLOR3, COLOR3, COLOR3, COLOR3,
+ COLOR3, COLOR3, COLOR3, COLOR3,
+ COLOR3, COLOR3, COLOR3, COLOR3,
+ COLOR3, COLOR3, COLOR3, COLOR3,
+ };
+ static const DWORD painted_surface4[] =
+ {
+ COLOR4, COLOR4, COLOR4, COLOR4,
+ COLOR4, COLOR4, COLOR4, COLOR4,
+ COLOR4, COLOR4, COLOR4, COLOR4,
+ COLOR4, COLOR4, COLOR4, COLOR4,
+ };
static const DWORD painted_child_surface[] = {
COLOR1, COLOR1, COLOR1, COLOR1,
COLOR1, COLOR2, COLOR2, COLOR1,
@@ -12261,10 +12336,14 @@ static void test_surface_composition(void)
DWORD screen_surface[ARRAY_SIZE(painted_surface)];
DWORD layered_const_surface[ARRAY_SIZE(painted_surface)];
+ DWORD layered_const_surface2[ARRAY_SIZE(painted_surface2)];
+ DWORD layered_const_surface3[ARRAY_SIZE(painted_surface3)];
+ DWORD layered_const_surface4[ARRAY_SIZE(painted_surface4)];
DWORD layered_child_surface[ARRAY_SIZE(painted_child_surface)];
DWORD layered_child_const_surface[ARRAY_SIZE(painted_child_surface)];
DWORD layered_child_alpha_surface[ARRAY_SIZE(painted_child_surface)];
+ struct d3d9_context *d3d9_ctx1, *d3d9_ctx2;
BLENDFUNCTION blend_cst_alpha = { AC_SRC_OVER, 0, 0x7f, 0 };
BLENDFUNCTION blend_src_alpha = { AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA };
WNDCLASSEXW wc;
@@ -12319,6 +12398,42 @@ static void test_surface_composition(void)
layered_const_surface[i] = BGRA2RGB(RGB(dr, dg, db));
}
+ for (i = 0; i < ARRAY_SIZE(painted_surface2); i++)
+ {
+ BYTE sr = (screen_surface[i] >> 16) & 0xff, dr = (painted_surface2[i] >> 16) & 0xff;
+ BYTE sg = (screen_surface[i] >> 8) & 0xff, dg = (painted_surface2[i] >> 8) & 0xff;
+ BYTE sb = (screen_surface[i] >> 0) & 0xff, db = (painted_surface2[i] >> 0) & 0xff;
+ BYTE da = 0x7f;
+ dr = min(max((sr * (0xff - da) + dr * da + 0x7f) / 0xff, 0), 0xff);
+ dg = min(max((sg * (0xff - da) + dg * da + 0x7f) / 0xff, 0), 0xff);
+ db = min(max((sb * (0xff - da) + db * da + 0x7f) / 0xff, 0), 0xff);
+ layered_const_surface2[i] = BGRA2RGB(RGB(dr, dg, db));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(painted_surface3); i++)
+ {
+ BYTE sr = (screen_surface[i] >> 16) & 0xff, dr = (painted_surface3[i] >> 16) & 0xff;
+ BYTE sg = (screen_surface[i] >> 8) & 0xff, dg = (painted_surface3[i] >> 8) & 0xff;
+ BYTE sb = (screen_surface[i] >> 0) & 0xff, db = (painted_surface3[i] >> 0) & 0xff;
+ BYTE da = 0x7f;
+ dr = min(max((sr * (0xff - da) + dr * da + 0x7f) / 0xff, 0), 0xff);
+ dg = min(max((sg * (0xff - da) + dg * da + 0x7f) / 0xff, 0), 0xff);
+ db = min(max((sb * (0xff - da) + db * da + 0x7f) / 0xff, 0), 0xff);
+ layered_const_surface3[i] = BGRA2RGB(RGB(dr, dg, db));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(painted_surface4); i++)
+ {
+ BYTE sr = (screen_surface[i] >> 16) & 0xff, dr = (painted_surface4[i] >> 16) & 0xff;
+ BYTE sg = (screen_surface[i] >> 8) & 0xff, dg = (painted_surface4[i] >> 8) & 0xff;
+ BYTE sb = (screen_surface[i] >> 0) & 0xff, db = (painted_surface4[i] >> 0) & 0xff;
+ BYTE da = 0x7f;
+ dr = min(max((sr * (0xff - da) + dr * da + 0x7f) / 0xff, 0), 0xff);
+ dg = min(max((sg * (0xff - da) + dg * da + 0x7f) / 0xff, 0), 0xff);
+ db = min(max((sb * (0xff - da) + db * da + 0x7f) / 0xff, 0), 0xff);
+ layered_const_surface4[i] = BGRA2RGB(RGB(dr, dg, db));
+ }
+
memcpy(layered_child_surface, screen_surface, sizeof(screen_surface));
for (i = 0; i < ARRAY_SIZE(painted_child_surface); i++)
{
@@ -12658,10 +12773,6 @@ static void test_surface_composition(void)
check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE);
check_screen_surface(hwnd, layered_child_alpha_surface, sizeof(layered_child_alpha_surface), TRUE);
- DeleteObject(bmp_obj);
- DeleteDC(hdc_src);
- ReleaseDC(NULL, hdc_dst);
-
paint_client_rect(hwnd, BGRA2RGB(COLOR1));
check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE);
check_screen_surface(hwnd, layered_child_alpha_surface, sizeof(layered_child_alpha_surface), TRUE);
@@ -12681,11 +12792,108 @@ static void test_surface_composition(void)
DestroyWindow(hwnd);
+ /* D3D / GDI interactions */
+
+ hwnd = CreateWindowW(L"surface", L"", WS_POPUP | WS_VISIBLE, 0, 0, 4, 4, 0, NULL, NULL, NULL);
+ ok(hwnd != 0, "CreateWindowW failed, last error %u\n", GetLastError());
+ d3d9_ctx1 = create_d3d9_context(hwnd);
+ d3d9_ctx2 = create_d3d9_context(hwnd);
+ flush_events( TRUE );
+
+ paint_client_rect(hwnd, BGRA2RGB(COLOR1));
+ check_client_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE);
+ check_screen_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE);
+
+ paint_d3d9_client_rect(d3d9_ctx1, COLOR2);
+ check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), TRUE);
+ check_screen_surface(hwnd, painted_surface2, sizeof(painted_surface2), FALSE);
+
+ paint_d3d9_client_rect(d3d9_ctx2, COLOR3);
+ check_client_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE);
+ check_screen_surface(hwnd, painted_surface3, sizeof(painted_surface3), FALSE);
+
+ paint_client_rect(hwnd, BGRA2RGB(COLOR4));
+ check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE);
+ check_screen_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE);
+
+ destroy_d3d9_context(d3d9_ctx1);
+ destroy_d3d9_context(d3d9_ctx2);
+ DestroyWindow(hwnd);
+
+
+ /* D3D / SLWA interactions */
+
+ hwnd = CreateWindowW(L"surface", L"", WS_POPUP, 0, 0, 4, 4, 0, NULL, NULL, NULL);
+ ok(hwnd != 0, "CreateWindowW failed, last error %u\n", GetLastError());
+ d3d9_ctx1 = create_d3d9_context(hwnd);
+ d3d9_ctx2 = create_d3d9_context(hwnd);
+
+ SetWindowLongW(hwnd, GWL_EXSTYLE, GetWindowLongW(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+ ret = SetLayeredWindowAttributes(hwnd, 0, 0x7f, LWA_ALPHA);
+ ok(ret, "SetLayeredWindowAttributes failed, last error %u\n", GetLastError());
+
+ ShowWindow(hwnd, SW_SHOW);
+ flush_events( TRUE );
+ paint_client_rect(hwnd, BGRA2RGB(COLOR1));
+ check_client_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE);
+ check_screen_surface(hwnd, layered_const_surface, sizeof(layered_const_surface), TRUE);
+
+ paint_d3d9_client_rect(d3d9_ctx1, COLOR2);
+ check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), TRUE);
+ check_screen_surface(hwnd, layered_const_surface2, sizeof(layered_const_surface2), TRUE);
+
+ paint_d3d9_client_rect(d3d9_ctx2, COLOR3);
+ check_client_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE);
+ check_screen_surface(hwnd, layered_const_surface3, sizeof(layered_const_surface3), TRUE);
+
+ paint_client_rect(hwnd, BGRA2RGB(COLOR4));
+ check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE);
+ check_screen_surface(hwnd, layered_const_surface4, sizeof(layered_const_surface4), TRUE);
+
+ destroy_d3d9_context(d3d9_ctx1);
+ destroy_d3d9_context(d3d9_ctx2);
+ DestroyWindow(hwnd);
+
+
+ /* D3D / ULW interactions */
+
+ hwnd = CreateWindowW(L"surface", L"", WS_POPUP, 0, 0, 4, 4, 0, NULL, NULL, NULL);
+ ok(hwnd != 0, "CreateWindowW failed, last error %u\n", GetLastError());
+ d3d9_ctx1 = create_d3d9_context(hwnd);
+
+ SetWindowLongW(hwnd, GWL_EXSTYLE, GetWindowLongW(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+ ret = UpdateLayeredWindow(hwnd, hdc_dst, NULL, (SIZE *)&rect.right, hdc_src, (POINT *)&rect.left, 0, NULL, ULW_OPAQUE);
+ ok(ret, "UpdateLayeredWindow failed, last error %u\n", GetLastError());
+
+ ShowWindow(hwnd, SW_SHOW);
+ flush_events( TRUE );
+ paint_client_rect(hwnd, BGRA2RGB(COLOR1));
+ check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE);
+ check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE);
+
+ paint_d3d9_client_rect(d3d9_ctx1, COLOR2);
+ check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE);
+ check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE);
+
+ paint_client_rect(hwnd, BGRA2RGB(COLOR1));
+ check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE);
+ check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE);
+
+ destroy_d3d9_context(d3d9_ctx1);
+ DestroyWindow(hwnd);
+
+
+ DeleteObject(bmp_obj);
+ DeleteDC(hdc_src);
+ ReleaseDC(NULL, hdc_dst);
+
UnregisterClassW(L"surface", NULL);
#undef BGRA2RGB
#undef COLOR1
#undef COLOR2
+#undef COLOR3
+#undef COLOR4
}
START_TEST(win)
--
2.31.1
More information about the wine-devel
mailing list