1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * PURPOSE: Tests pixel formats exposed by the software implementation 5 * PROGRAMMERS: J�r�me Gardou 6 */ 7 8 #include <windows.h> 9 #include <wingdi.h> 10 #include <GL/gl.h> 11 #include <stdio.h> 12 13 #include "wine/test.h" 14 15 static char* str_dbg_pfd_flags(DWORD flags) 16 { 17 static char buffer[1000]; 18 static char *p = buffer; 19 char* ret; 20 21 BOOL first = TRUE; 22 23 if (p > &buffer[800]) 24 p = buffer; 25 26 *p = 0; 27 28 #define FLAGS_TO_STR(__x__) \ 29 do { \ 30 if (flags & __x__) \ 31 { \ 32 if (!first) strcat(p, " | "); \ 33 strcat(p, #__x__); \ 34 first = FALSE; \ 35 flags &= ~((DWORD)__x__); \ 36 } \ 37 } while(0) 38 39 FLAGS_TO_STR(PFD_DOUBLEBUFFER); 40 FLAGS_TO_STR(PFD_STEREO); 41 FLAGS_TO_STR(PFD_DRAW_TO_WINDOW); 42 FLAGS_TO_STR(PFD_DRAW_TO_BITMAP); 43 FLAGS_TO_STR(PFD_SUPPORT_GDI); 44 FLAGS_TO_STR(PFD_SUPPORT_OPENGL); 45 FLAGS_TO_STR(PFD_GENERIC_FORMAT); 46 FLAGS_TO_STR(PFD_NEED_PALETTE); 47 FLAGS_TO_STR(PFD_NEED_SYSTEM_PALETTE); 48 FLAGS_TO_STR(PFD_SWAP_EXCHANGE); 49 FLAGS_TO_STR(PFD_SWAP_COPY); 50 FLAGS_TO_STR(PFD_SWAP_LAYER_BUFFERS); 51 FLAGS_TO_STR(PFD_GENERIC_ACCELERATED); 52 FLAGS_TO_STR(PFD_SUPPORT_COMPOSITION); 53 #undef FLAGS_TO_STR 54 55 if (flags) 56 { 57 char tmp[16]; 58 sprintf(tmp, " | 0x%08x", (UINT)flags); 59 strcat(p, tmp); 60 } 61 62 ret = p; 63 64 p += strlen(p) + 1; 65 66 return ret; 67 } 68 69 struct test_color 70 { 71 BYTE iPixelType; 72 BYTE cColorBits; 73 BYTE cRedBits; BYTE cRedShift; 74 BYTE cGreenBits; BYTE cGreenShift; 75 BYTE cBlueBits; BYTE cBlueShift; 76 BYTE cAlphaBits; BYTE cAlphaShift; 77 BYTE cAccumBits; 78 BYTE cAccumRedBits; BYTE cAccumGreenBits; BYTE cAccumBlueBits; BYTE cAccumAlphaBits; 79 }; 80 81 static const struct test_color test_colors_32[] = 82 { 83 {PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0}, 84 {PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16}, 85 {PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0}, 86 }; 87 88 static const struct test_color test_colors_24[] = 89 { 90 {PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0}, 91 {PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16}, 92 {PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0}, 93 }; 94 95 static const struct test_color test_colors_16[] = 96 { 97 {PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0}, 98 {PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8}, 99 {PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 100 }; 101 102 static const struct test_color test_colors_16_565[] = 103 { 104 {PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0}, 105 {PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8}, 106 {PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 107 }; 108 109 static const struct test_color test_colors_8[] = 110 { 111 {PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0}, 112 {PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8}, 113 {PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0}, 114 }; 115 116 static const struct test_color test_colors_4[] = 117 { 118 {PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0}, 119 {PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4}, 120 {PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0}, 121 }; 122 123 static const struct test_color* test_colors_32bpp[] = {test_colors_32, test_colors_24, test_colors_16, test_colors_8, test_colors_4, NULL}; 124 static const struct test_color* test_colors_24bpp[] = {test_colors_24, test_colors_32, test_colors_16, test_colors_8, test_colors_4, NULL}; 125 static const struct test_color* test_colors_16bpp[] = {test_colors_16_565, test_colors_24, test_colors_32, test_colors_8, test_colors_4, NULL}; 126 static const struct test_color* test_colors_8bpp[] = {test_colors_8, test_colors_24, test_colors_32, test_colors_16, test_colors_4, NULL}; 127 128 static const BYTE test_depths[] = { 32, 16 }; 129 130 static void test_format(HDC hdc, int num_pf, int pf, const struct test_color *colors, BYTE depth, BOOL is_window, BOOL is_double_buffered) 131 { 132 PIXELFORMATDESCRIPTOR pfd; 133 int ret; 134 135 ret = DescribePixelFormat(hdc, pf, sizeof(pfd), &pfd); 136 ok(ret == num_pf, "Number of pixel formats changed!\n"); 137 138 ok(pfd.nSize == sizeof(pfd), "Wrong nSize for format %i, expected %u, got %u\n", pf, (WORD)sizeof(pfd), pfd.nSize); 139 ok(pfd.nVersion == 1, "Wrong nVersion for format %i, expected 1, got %u\n", pf, pfd.nVersion); 140 if (is_window) 141 { 142 DWORD flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT; 143 144 if ((pfd.cColorBits <= 8) && (pfd.iPixelType == PFD_TYPE_RGBA)) 145 flags |= PFD_NEED_PALETTE; 146 147 if (is_double_buffered) 148 { 149 flags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY; 150 } 151 else 152 { 153 flags |= PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI; 154 } 155 ok((pfd.dwFlags == flags) || (pfd.dwFlags == (flags | PFD_SUPPORT_COMPOSITION)), 156 "Wrong dwFlags for format %i, expected %s (0x%08x), got %s(0x%08x)\n", 157 pf, str_dbg_pfd_flags(flags), (UINT)flags, str_dbg_pfd_flags(pfd.dwFlags), (UINT)pfd.dwFlags); 158 } 159 else 160 { 161 ok(pfd.dwFlags == (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT), 162 "Wrong dwFlags for format %i, expected PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT, got %s\n", 163 pf, str_dbg_pfd_flags(pfd.dwFlags)); 164 } 165 166 #define TEST_FIELD(__x__) ok(pfd.__x__ == colors->__x__, "Wrong " #__x__ " for format %i, expected %u, got %u\n", pf, colors->__x__, pfd.__x__) 167 TEST_FIELD(iPixelType); 168 TEST_FIELD(cColorBits); 169 TEST_FIELD(cRedBits); 170 TEST_FIELD(cRedShift); 171 TEST_FIELD(cGreenBits); 172 TEST_FIELD(cGreenShift); 173 TEST_FIELD(cBlueBits); 174 TEST_FIELD(cBlueShift); 175 TEST_FIELD(cAlphaBits); 176 TEST_FIELD(cAlphaShift); 177 TEST_FIELD(cAccumBits); 178 TEST_FIELD(cAccumRedBits); 179 TEST_FIELD(cAccumGreenBits); 180 TEST_FIELD(cAccumBlueBits); 181 TEST_FIELD(cAccumAlphaBits); 182 #undef TEST_FIELD 183 ok(pfd.cDepthBits == depth, "Wrong cDepthBit for format %i, expected %u, got %u\n", pf, depth, pfd.cDepthBits); 184 185 /* the rest is constant */ 186 #define TEST_FIELD(__x__, __y__) ok(pfd.__x__ == __y__, "Wrong " #__x__ " for format %i, expected " #__y__ ", got %u\n", pf, (UINT)pfd.__x__) 187 TEST_FIELD(cStencilBits, 8); 188 TEST_FIELD(cAuxBuffers, 0); 189 TEST_FIELD(iLayerType, 0); 190 TEST_FIELD(bReserved, 0); 191 TEST_FIELD(dwLayerMask, 0); 192 TEST_FIELD(dwVisibleMask, 0); 193 TEST_FIELD(dwDamageMask, 0); 194 #undef TEST_FIELD 195 } 196 197 static void test_screen_colors(const struct test_color **colors) 198 { 199 int pf, num_pf, ret; 200 int i, j; 201 HDC hdc; 202 HWND hwnd; 203 PIXELFORMATDESCRIPTOR pfd; 204 205 hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, 206 NULL, NULL); 207 if (!hwnd) 208 { 209 ok(hwnd != NULL, "Failed to create a window.\n"); 210 return; 211 } 212 213 hdc = GetDC( hwnd ); 214 num_pf = DescribePixelFormat(hdc, 0, 0, NULL); 215 ok(num_pf > 0, "DescribePixelFormat failed.\n"); 216 217 for (pf = 1; pf <= num_pf; pf++) 218 { 219 ret = DescribePixelFormat(hdc, pf, sizeof(pfd), &pfd); 220 ok(ret == num_pf, "Number of pixel formats changed!\n"); 221 222 if (pfd.dwFlags & PFD_GENERIC_FORMAT) 223 break; 224 } 225 226 ok(pf < num_pf, "No generic pixel format!\n"); 227 228 /* First the formats compatible with the DC */ 229 for (i = 0; i < 3; i++) 230 { 231 /* Single buffered first */ 232 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 233 { 234 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], TRUE, FALSE); 235 } 236 237 /* Then double buffered */ 238 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 239 { 240 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], TRUE, TRUE); 241 } 242 } 243 244 colors++; 245 246 /* Then the rest */ 247 while (*colors) 248 { 249 for (i = 0; i < 3; i++) 250 { 251 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 252 { 253 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], FALSE, FALSE); 254 } 255 } 256 colors++; 257 } 258 259 /* We must have tested all generic formats. */ 260 ok(pf - 1 == num_pf, "We didn't test all generic formats : tested %u, total %u.\n", pf, num_pf); 261 262 ReleaseDC( hwnd, hdc ); 263 DestroyWindow( hwnd ); 264 } 265 266 static HBITMAP create_dib_section(WORD bpp, void** dstBuffer) 267 { 268 BITMAPINFO bi; 269 270 memset(&bi, 0, sizeof(BITMAPINFO)); 271 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 272 bi.bmiHeader.biWidth = 4; 273 bi.bmiHeader.biHeight = -4; 274 bi.bmiHeader.biPlanes = 1; 275 bi.bmiHeader.biBitCount = bpp; 276 bi.bmiHeader.biCompression = BI_RGB; 277 278 return CreateDIBSection(0, &bi, DIB_RGB_COLORS, dstBuffer, NULL, 0); 279 } 280 281 static void test_bitmap_colors(HDC hdc, const struct test_color** colors) 282 { 283 INT num_pf, pf, ret; 284 PIXELFORMATDESCRIPTOR pfd; 285 INT i, j; 286 287 num_pf = DescribePixelFormat(hdc, 0, 0, NULL); 288 ok(num_pf > 0, "DescribePixelFormat failed.\n"); 289 290 for (pf = 1; pf <= num_pf; pf++) 291 { 292 ret = DescribePixelFormat(hdc, pf, sizeof(pfd), &pfd); 293 ok(ret == num_pf, "Number of pixel formats changed!\n"); 294 295 if (pfd.dwFlags & PFD_GENERIC_FORMAT) 296 break; 297 } 298 299 ok(pf < num_pf, "No generic pixel format!\n"); 300 301 /* First the formats compatible with the DC */ 302 for (i = 0; i < 3; i++) 303 { 304 /* Single buffered first */ 305 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 306 { 307 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], TRUE, FALSE); 308 } 309 310 /* Then double buffered */ 311 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 312 { 313 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], TRUE, TRUE); 314 } 315 } 316 317 colors++; 318 319 /* Then the rest */ 320 while (*colors) 321 { 322 for (i = 0; i < 3; i++) 323 { 324 for (j = 0; j < ARRAY_SIZE(test_depths); j++) 325 { 326 test_format(hdc, num_pf, pf++, &colors[0][i], test_depths[j], FALSE, FALSE); 327 } 328 } 329 colors++; 330 } 331 332 /* We must have tested all generic formats. */ 333 ok(pf - 1 == num_pf, "We didn't test all generic formats : tested %u, total %u.\n", pf, num_pf); 334 } 335 336 static void test_bitmap_formats(const struct test_color ** colors) 337 { 338 HBITMAP oldBmp, dib; 339 HDC hdc; 340 static const INT bpps [] = {4, 8, 16, 24, 32}; 341 INT i; 342 void* dib_buffer; 343 344 hdc = CreateCompatibleDC(NULL); 345 ok (hdc != NULL, "Failed creating a memory DC.\n"); 346 347 for (i = 0; i < ARRAY_SIZE(bpps); i++) 348 { 349 dib = create_dib_section(bpps[i], &dib_buffer); 350 ok(dib != NULL, "Failed to create DIB for %u bpp\n", bpps[i]); 351 352 oldBmp = SelectObject(hdc, dib); 353 ok (oldBmp != NULL, "Failed to select the DIB\n"); 354 355 trace("testing DIB %ubpp\n", bpps[i]); 356 /* For mem DC, this is always the depth of the screen which is taken into account */ 357 test_bitmap_colors(hdc, colors); 358 359 SelectObject(hdc, oldBmp); 360 DeleteObject(dib); 361 } 362 } 363 364 START_TEST(sw_pixelformat) 365 { 366 DEVMODEW devMode; 367 INT ret; 368 DWORD orig_bpp; 369 static const WORD bit_depths[] = {8, 16, 24, 32}; 370 static const struct test_color** colors[] = {test_colors_8bpp, test_colors_16bpp, test_colors_24bpp, test_colors_32bpp}; 371 INT i; 372 373 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devMode); 374 ok (ret != 0, "EnumDisplaySettings failed.\n"); 375 orig_bpp = devMode.dmBitsPerPel; 376 377 for (i = 0; i < ARRAY_SIZE(bit_depths); i++) 378 { 379 devMode.dmBitsPerPel = bit_depths[i]; 380 ret = ChangeDisplaySettingsExW(NULL, &devMode, NULL, 0, NULL); 381 if (ret == DISP_CHANGE_SUCCESSFUL) 382 { 383 trace("Testing %ubpp\n", bit_depths[i]); 384 test_screen_colors(colors[i]); 385 test_bitmap_formats(colors[i]); 386 } 387 else 388 { 389 skip("Unable to switch to %ubpp\n", bit_depths[i]); 390 } 391 } 392 393 devMode.dmBitsPerPel = orig_bpp; 394 ret = ChangeDisplaySettingsExW(NULL, &devMode, NULL, 0, NULL); 395 } 396