2 * Unit tests for DirectDraw overlay functions
4 * Copyright (C) 2008 Stefan Dösinger for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
27 static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
29 static IDirectDraw7 *ddraw = NULL;
30 static IDirectDrawSurface7 *primary = NULL;
32 static IDirectDrawSurface7 *create_overlay(DWORD width, DWORD height, DWORD format) {
35 IDirectDrawSurface7 *ret;
37 memset(&ddsd, 0, sizeof(ddsd));
38 ddsd.dwSize = sizeof(ddsd);
39 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
41 ddsd.dwHeight = height;
42 ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
43 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
44 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
45 U4(ddsd).ddpfPixelFormat.dwFourCC = format;
46 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &ret, NULL);
47 if(FAILED(hr)) return NULL;
51 static BOOL CreateDirectDraw(void)
55 IDirectDrawSurface7 *overlay = NULL;
56 HMODULE hmod = GetModuleHandleA("ddraw.dll");
58 pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
59 if (!pDirectDrawCreateEx) {
60 win_skip("DirectDrawCreateEx is not available\n");
64 hr = pDirectDrawCreateEx(NULL, (void**)&ddraw, &IID_IDirectDraw7, NULL);
65 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
67 trace("DirectDrawCreateEx() failed with an error %x\n", hr);
71 hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
72 ok(hr == DD_OK, "SetCooperativeLevel returned: %x\n", hr );
74 memset(&ddsd, 0, sizeof(ddsd));
75 ddsd.dwSize = sizeof(ddsd);
76 ddsd.dwFlags = DDSD_CAPS;
77 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
78 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
80 IDirectDraw7_Release(ddraw);
81 trace("IDirectDraw7_CreateSurface() failed with an error %x\n", hr);
85 overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
87 IDirectDrawSurface7_Release(primary);
88 IDirectDraw7_Release(ddraw);
89 skip("Failed to create an overlay - assuming not supported\n");
92 IDirectDraw7_Release(overlay);
97 static void rectangle_settings(void) {
98 IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
100 RECT rect = {0, 0, 64, 64};
103 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is used. Show that this is wrong */
104 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
105 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
106 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_HIDE, NULL);
107 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
108 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_SHOW, NULL);
109 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
111 /* Show that the overlay position is the (top, left) coordinate of the dest rectangle */
116 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
117 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
118 posx = -1; posy = -1;
119 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
120 ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
121 ok(posx == rect.left && posy == rect.top, "Overlay position is (%d, %d), expected (%d, %d)\n",
122 posx, posy, rect.left, rect.top);
124 /* Passing a NULL dest rect sets the position to 0/0 . Visually it can be seen that the overlay overlays the whole primary(==screen)*/
125 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, 0, NULL);
126 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
127 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
128 ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
129 ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
132 /* The position cannot be retrieved when the overlay is not shown */
133 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_HIDE, NULL);
134 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
135 posx = -1; posy = -1;
136 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
137 ok(hr == DDERR_OVERLAYNOTVISIBLE, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
138 ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
141 IDirectDrawSurface7_Release(overlay);
144 static void offscreen_test(void) {
145 IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y')), *offscreen = NULL;
149 /* Try to overlay a NULL surface */
150 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_SHOW, NULL);
151 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
152 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_HIDE, NULL);
153 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
155 /* Try to overlay an offscreen surface */
156 memset(&ddsd, 0, sizeof(ddsd));
157 ddsd.dwSize = sizeof(ddsd);
158 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
161 U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
162 U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
163 U4(ddsd).ddpfPixelFormat.dwFourCC = 0;
164 U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
165 U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
166 U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07e0;
167 U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
168 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
169 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &offscreen, NULL);
170 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with hr=0x%08x\n", hr);
172 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, offscreen, NULL, DDOVER_SHOW, NULL);
173 ok(hr == DD_OK || broken(hr == E_NOTIMPL),
174 "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
176 /* Try to overlay the primary with a non-overlay surface */
177 hr = IDirectDrawSurface7_UpdateOverlay(offscreen, NULL, primary, NULL, DDOVER_SHOW, NULL);
178 ok(hr == DDERR_NOTAOVERLAYSURFACE, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
180 IDirectDrawSurface7_Release(offscreen);
181 IDirectDrawSurface7_Release(overlay);
184 static void yv12_test(void)
188 IDirectDrawSurface7 *surface;
190 surface = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
192 skip("YV12 surfaces not available\n");
196 memset(&desc, 0, sizeof(desc));
197 desc.dwSize = sizeof(desc);
198 hr = IDirectDrawSurface7_Lock(surface, NULL, &desc, 0, NULL);
199 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);
201 ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
202 "Unexpected desc.dwFlags 0x%08x\n", desc.dwFlags);
203 ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM) ||
204 desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC),
205 "Unexpected desc.ddsCaps.dwCaps 0x%08x\n", desc.ddsCaps.dwCaps);
206 ok(desc.dwWidth == 256 && desc.dwHeight == 256, "Expected size 64x64, got %ux%u\n",
207 desc.dwWidth, desc.dwHeight);
208 /* The overlay pitch seems to have 256 byte alignment */
209 ok(U1(desc).lPitch == 256, "Unexpected pitch %u, expected 256\n", U1(desc).lPitch);
211 hr = IDirectDrawSurface7_Unlock(surface, NULL);
212 ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
214 IDirectDrawSurface7_Release(surface);
219 if(CreateDirectDraw() == FALSE) {
220 skip("Failed to initialize ddraw\n");
224 rectangle_settings();
228 if(primary) IDirectDrawSurface7_Release(primary);
229 if(ddraw) IDirectDraw7_Release(ddraw);