ddraw: Add some overlay tests.
[wine.git] / dlls / ddraw / tests / overlay.c
blob8d38f98574c5c67d751008e8bfc54dfe8334bf10
1 /*
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
20 #define COBJMACROS
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "ddraw.h"
25 #include "unknwn.h"
27 static IDirectDraw7 *ddraw = NULL;
28 static IDirectDrawSurface7 *primary = NULL;
30 static IDirectDrawSurface7 *create_overlay(DWORD width, DWORD height, DWORD format) {
31 DDSURFACEDESC2 ddsd;
32 HRESULT hr;
33 IDirectDrawSurface7 *ret;
35 memset(&ddsd, 0, sizeof(ddsd));
36 ddsd.dwSize = sizeof(ddsd);
37 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
38 ddsd.dwWidth = width;
39 ddsd.dwHeight = height;
40 ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
41 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
42 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
43 ddsd.ddpfPixelFormat.dwFourCC = format;
44 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &ret, NULL);
45 if(FAILED(hr)) return NULL;
46 else return ret;
49 static BOOL CreateDirectDraw(void)
51 HRESULT hr;
52 DDSURFACEDESC2 ddsd;
53 IDirectDrawSurface7 *overlay = NULL;
55 hr = DirectDrawCreateEx(NULL, (void**)&ddraw, &IID_IDirectDraw7, NULL);
56 ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
57 if (!ddraw) {
58 trace("DirectDrawCreateEx() failed with an error %x\n", hr);
59 return FALSE;
62 hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
63 ok(hr == DD_OK, "SetCooperativeLevel returned: %x\n", hr );
65 memset(&ddsd, 0, sizeof(ddsd));
66 ddsd.dwSize = sizeof(ddsd);
67 ddsd.dwFlags = DDSD_CAPS;
68 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
69 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
70 if (!SUCCEEDED(hr)) {
71 IDirectDraw7_Release(ddraw);
72 trace("IDirectDraw7_CreateSurface() failed with an error %x\n", hr);
73 return FALSE;
76 overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
77 if (!overlay) {
78 IDirectDrawSurface7_Release(primary);
79 IDirectDraw7_Release(ddraw);
80 skip("Failed to create an overlay - assuming not supported\n");
81 return FALSE;
83 IDirectDraw7_Release(overlay);
85 return TRUE;
88 static void rectangle_settings(void) {
89 IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
90 HRESULT hr;
91 RECT rect = {0, 0, 64, 64};
92 LONG posx, posy;
94 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is used. Show that this is wrong */
95 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
96 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
97 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_HIDE, NULL);
98 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
99 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_SHOW, NULL);
100 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
102 /* Show that the overlay position is the (top, left) coordinate of the dest rectangle */
103 rect.top += 16;
104 rect.left += 32;
105 rect.bottom += 16;
106 rect.right += 32;
107 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
108 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
109 posx = -1; posy = -1;
110 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
111 ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
112 ok(posx == rect.left && posy == rect.top, "Overlay position is (%d, %d), expected (%d, %d)\n",
113 posx, posy, rect.left, rect.top);
115 /* Passing a NULL dest rect sets the position to 0/0 . Visually it can be seen that the overlay overlays the whole primary(==screen)*/
116 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, 0, NULL);
117 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
118 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
119 ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
120 ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
121 posx, posy, 0, 0);
123 /* The position cannot be retrieved when the overlay is not shown */
124 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_HIDE, NULL);
125 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
126 posx = -1; posy = -1;
127 hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
128 ok(hr == DDERR_OVERLAYNOTVISIBLE, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
129 ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
130 posx, posy, 0, 0);
132 IDirectDrawSurface7_Release(overlay);
135 static void offscreen_test(void) {
136 IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y')), *offscreen = NULL;
137 HRESULT hr;
138 DDSURFACEDESC2 ddsd;
140 /* Try to overlay a NULL surface */
141 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_SHOW, NULL);
142 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
143 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_HIDE, NULL);
144 ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
146 /* Try to overlay an offscreen surface */
147 memset(&ddsd, 0, sizeof(ddsd));
148 ddsd.dwSize = sizeof(ddsd);
149 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
150 ddsd.dwWidth = 64;
151 ddsd.dwHeight = 64;
152 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
153 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
154 ddsd.ddpfPixelFormat.dwFourCC = 0;
155 ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
156 ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
157 ddsd.ddpfPixelFormat.dwGBitMask = 0x07e0;
158 ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
159 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
160 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &offscreen, NULL);
161 ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with hr=0x%08x\n", hr);
163 hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, offscreen, NULL, DDOVER_SHOW, NULL);
164 ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
166 /* Try to overlay the primary with a non-overlay surface */
167 hr = IDirectDrawSurface7_UpdateOverlay(offscreen, NULL, primary, NULL, DDOVER_SHOW, NULL);
168 ok(hr == DDERR_NOTAOVERLAYSURFACE, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
170 IDirectDrawSurface7_Release(offscreen);
171 IDirectDrawSurface7_Release(overlay);
174 static void yv12_test(void)
176 HRESULT hr;
177 DDSURFACEDESC2 desc;
178 IDirectDrawSurface7 *surface;
180 surface = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
181 if(!surface) {
182 skip("YV12 surfaces not available\n");
183 return;
186 memset(&desc, 0, sizeof(desc));
187 desc.dwSize = sizeof(desc);
188 hr = IDirectDrawSurface7_Lock(surface, NULL, &desc, 0, NULL);
189 ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);
191 ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
192 "Unexpected desc.dwFlags 0x%08x\n", desc.dwFlags);
193 ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
194 "Unexpected desc.ddsCaps.dwCaps 0x%08x\n", desc.ddsCaps.dwCaps);
195 ok(desc.dwWidth == 256 && desc.dwHeight == 256, "Expected size 64x64, got %ux%u\n",
196 desc.dwWidth, desc.dwHeight);
197 /* The overlay pitch seems to have 256 byte alignment */
198 ok(desc.lPitch == 256, "Unexpected pitch %u, expected 256\n", desc.lPitch);
200 hr = IDirectDrawSurface7_Unlock(surface, NULL);
201 ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
203 IDirectDrawSurface7_Release(surface);
206 START_TEST(overlay)
208 if(CreateDirectDraw() == FALSE) {
209 skip("Failed to initialize ddraw\n");
210 return;
213 rectangle_settings();
214 offscreen_test();
215 yv12_test();
217 if(primary) IDirectDrawSurface7_Release(primary);
218 if(ddraw) IDirectDraw7_Release(ddraw);