1 /* 2 * Copyright 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 #include <gtest/gtest.h> 24 #include <string.h> 25 26 extern "C" { 27 #include "glxclient.h" 28 #include "glx_error.h" 29 } 30 31 #include <xcb/glx.h> 32 #include "mock_xdisplay.h" 33 #include "fake_glx_screen.h" 34 35 static bool CreateContextAttribsARB_was_sent; 36 static xcb_glx_create_context_attribs_arb_request_t req; 37 static uint32_t sent_attribs[1024]; 38 static uint32_t next_id; 39 40 41 struct glx_screen *psc; 42 43 extern "C" Bool 44 glx_context_init(struct glx_context *gc, 45 struct glx_screen *psc, struct glx_config *config) 46 { 47 gc->majorOpcode = 123; 48 gc->screen = psc->scr; 49 gc->psc = psc; 50 gc->config = config; 51 gc->isDirect = GL_TRUE; 52 gc->currentContextTag = -1; 53 54 return GL_TRUE; 55 } 56 57 extern "C" struct glx_screen * 58 GetGLXScreenConfigs(Display * dpy, int scrn) 59 { 60 (void) dpy; 61 (void) scrn; 62 return psc; 63 } 64 65 extern "C" uint32_t 66 xcb_generate_id(xcb_connection_t *c) 67 { 68 (void) c; 69 70 return next_id++; 71 } 72 73 extern "C" xcb_void_cookie_t 74 xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c, 75 xcb_glx_context_t context, 76 uint32_t fbconfig, 77 uint32_t screen, 78 uint32_t share_list, 79 uint8_t is_direct, 80 uint32_t num_attribs, 81 const uint32_t *attribs) 82 { 83 (void) c; 84 85 CreateContextAttribsARB_was_sent = true; 86 req.context = context; 87 req.fbconfig = fbconfig; 88 req.screen = screen; 89 req.share_list = share_list; 90 req.is_direct = is_direct; 91 req.num_attribs = num_attribs; 92 93 if (num_attribs != 0 && attribs != NULL) 94 memcpy(sent_attribs, attribs, num_attribs * 2 * sizeof(uint32_t)); 95 96 xcb_void_cookie_t cookie; 97 cookie.sequence = 0xbadc0de; 98 99 return cookie; 100 } 101 102 extern "C" xcb_generic_error_t * 103 xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie) 104 { 105 return NULL; 106 } 107 108 extern "C" void 109 __glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err) 110 { 111 } 112 113 extern "C" void 114 __glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID, 115 uint_fast16_t minorCode, bool coreX11error) 116 { 117 } 118 119 class glXCreateContextAttribARB_test : public ::testing::Test { 120 public: 121 virtual void SetUp(); 122 123 /** 124 * Replace the existing screen with a direct-rendering screen 125 */ 126 void use_direct_rendering_screen(); 127 128 mock_XDisplay *dpy; 129 struct glx_config fbc; 130 }; 131 132 void 133 glXCreateContextAttribARB_test::SetUp() 134 { 135 CreateContextAttribsARB_was_sent = false; 136 memset(&req, 0, sizeof(req)); 137 next_id = 99; 138 fake_glx_context::contexts_allocated = 0; 139 psc = new fake_glx_screen(NULL, 0, ""); 140 141 this->dpy = new mock_XDisplay(1); 142 143 memset(&this->fbc, 0, sizeof(this->fbc)); 144 this->fbc.fbconfigID = 0xbeefcafe; 145 } 146 147 void 148 glXCreateContextAttribARB_test::use_direct_rendering_screen() 149 { 150 struct glx_screen *direct_psc = 151 new fake_glx_screen_direct(psc->display, 152 psc->scr, 153 psc->serverGLXexts); 154 155 delete psc; 156 psc = direct_psc; 157 } 158 159 /** 160 * \name Verify detection of client-side errors 161 */ 162 /*@{*/ 163 TEST_F(glXCreateContextAttribARB_test, NULL_display_returns_None) 164 { 165 GLXContext ctx = 166 glXCreateContextAttribsARB(NULL, (GLXFBConfig) &this->fbc, 0, 167 False, NULL); 168 169 EXPECT_EQ(None, ctx); 170 EXPECT_EQ(0, fake_glx_context::contexts_allocated); 171 } 172 173 TEST_F(glXCreateContextAttribARB_test, NULL_fbconfig_returns_None) 174 { 175 GLXContext ctx = 176 glXCreateContextAttribsARB(this->dpy, NULL, 0, False, NULL); 177 178 EXPECT_EQ(None, ctx); 179 EXPECT_EQ(0, fake_glx_context::contexts_allocated); 180 } 181 182 TEST_F(glXCreateContextAttribARB_test, NULL_screen_returns_None) 183 { 184 delete psc; 185 psc = NULL; 186 187 GLXContext ctx = 188 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 189 False, NULL); 190 191 EXPECT_EQ(None, ctx); 192 EXPECT_EQ(0, fake_glx_context::contexts_allocated); 193 } 194 /*@}*/ 195 196 /** 197 * \name Verify that correct protocol bits are sent to the server. 198 */ 199 /*@{*/ 200 TEST_F(glXCreateContextAttribARB_test, does_send_protocol) 201 { 202 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 203 False, NULL); 204 205 EXPECT_TRUE(CreateContextAttribsARB_was_sent); 206 } 207 208 TEST_F(glXCreateContextAttribARB_test, sent_correct_context) 209 { 210 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 211 False, NULL); 212 213 EXPECT_EQ(99u, req.context); 214 } 215 216 TEST_F(glXCreateContextAttribARB_test, sent_correct_fbconfig) 217 { 218 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 219 False, NULL); 220 221 EXPECT_EQ(0xbeefcafe, req.fbconfig); 222 } 223 224 TEST_F(glXCreateContextAttribARB_test, sent_correct_share_list) 225 { 226 GLXContext share = 227 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 228 False, NULL); 229 230 ASSERT_NE((GLXContext) 0, share); 231 232 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, share, 233 False, NULL); 234 235 struct glx_context *glx_ctx = (struct glx_context *) share; 236 EXPECT_EQ(glx_ctx->xid, req.share_list); 237 } 238 239 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_true) 240 { 241 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 242 True, NULL); 243 244 EXPECT_FALSE(req.is_direct); 245 } 246 247 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_false) 248 { 249 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 250 False, NULL); 251 252 EXPECT_FALSE(req.is_direct); 253 } 254 255 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_true) 256 { 257 this->use_direct_rendering_screen(); 258 259 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 260 True, NULL); 261 262 EXPECT_TRUE(req.is_direct); 263 } 264 265 TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_false) 266 { 267 this->use_direct_rendering_screen(); 268 269 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 270 False, NULL); 271 272 EXPECT_FALSE(req.is_direct); 273 } 274 275 TEST_F(glXCreateContextAttribARB_test, sent_correct_screen) 276 { 277 this->fbc.screen = 7; 278 psc->scr = 7; 279 280 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 281 False, NULL); 282 283 EXPECT_EQ(7u, req.screen); 284 } 285 286 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs) 287 { 288 /* Use zeros in the second half of each attribute pair to try and trick the 289 * implementation into termiating the list early. 290 * 291 * Use non-zero in the second half of the last attribute pair to try and 292 * trick the implementation into not terminating the list early enough. 293 */ 294 static const int attribs[] = { 295 1, 0, 296 2, 0, 297 3, 0, 298 4, 0, 299 0, 6, 300 0, 0 301 }; 302 303 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 304 False, attribs); 305 306 EXPECT_EQ(4u, req.num_attribs); 307 } 308 309 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_empty_list) 310 { 311 static const int attribs[] = { 312 0, 313 }; 314 315 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 316 False, attribs); 317 318 EXPECT_EQ(0u, req.num_attribs); 319 } 320 321 TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_NULL_list_pointer) 322 { 323 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 324 False, NULL); 325 326 EXPECT_EQ(0u, req.num_attribs); 327 } 328 329 TEST_F(glXCreateContextAttribARB_test, sent_correct_attrib_list) 330 { 331 int attribs[] = { 332 GLX_RENDER_TYPE, GLX_RGBA_TYPE, 333 GLX_CONTEXT_MAJOR_VERSION_ARB, 1, 334 GLX_CONTEXT_MINOR_VERSION_ARB, 2, 335 0 336 }; 337 338 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 339 False, attribs); 340 341 for (unsigned i = 0; i < 6; i++) { 342 EXPECT_EQ((uint32_t) attribs[i], sent_attribs[i]); 343 } 344 } 345 /*@}*/ 346 347 /** 348 * \name Verify details of the returned GLXContext 349 */ 350 /*@{*/ 351 TEST_F(glXCreateContextAttribARB_test, correct_context) 352 { 353 GLXContext ctx = 354 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 355 False, NULL); 356 357 /* Since the server did not return an error, the GLXContext should not be 358 * NULL. 359 */ 360 EXPECT_NE((GLXContext)0, ctx); 361 362 /* It shouldn't be the XID of the context either. 363 */ 364 EXPECT_NE((GLXContext)99, ctx); 365 } 366 367 TEST_F(glXCreateContextAttribARB_test, correct_context_xid) 368 { 369 GLXContext ctx = 370 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 371 False, NULL); 372 373 /* Since the server did not return an error, the GLXContext should not be 374 * NULL. 375 */ 376 ASSERT_NE((GLXContext)0, ctx); 377 378 struct glx_context *glx_ctx = (struct glx_context *) ctx; 379 EXPECT_EQ(99u, glx_ctx->xid); 380 } 381 382 TEST_F(glXCreateContextAttribARB_test, correct_context_share_xid) 383 { 384 GLXContext first = 385 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 386 False, NULL); 387 388 ASSERT_NE((GLXContext) 0, first); 389 390 GLXContext second = 391 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, first, 392 False, NULL); 393 394 ASSERT_NE((GLXContext) 0, second); 395 396 struct glx_context *share = (struct glx_context *) first; 397 struct glx_context *ctx = (struct glx_context *) second; 398 EXPECT_EQ(share->xid, ctx->share_xid); 399 } 400 401 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_true) 402 { 403 GLXContext ctx = 404 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 405 True, NULL); 406 407 ASSERT_NE((GLXContext) 0, ctx); 408 409 struct glx_context *gc = (struct glx_context *) ctx; 410 411 EXPECT_FALSE(gc->isDirect); 412 } 413 414 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_false) 415 { 416 GLXContext ctx = 417 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 418 False, NULL); 419 420 ASSERT_NE((GLXContext) 0, ctx); 421 422 struct glx_context *gc = (struct glx_context *) ctx; 423 424 EXPECT_FALSE(gc->isDirect); 425 } 426 427 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_true) 428 { 429 this->use_direct_rendering_screen(); 430 431 GLXContext ctx = 432 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 433 True, NULL); 434 435 ASSERT_NE((GLXContext) 0, ctx); 436 437 struct glx_context *gc = (struct glx_context *) ctx; 438 439 EXPECT_TRUE(gc->isDirect); 440 } 441 442 TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_false) 443 { 444 this->use_direct_rendering_screen(); 445 446 GLXContext ctx = 447 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 448 False, NULL); 449 450 ASSERT_NE((GLXContext) 0, ctx); 451 452 struct glx_context *gc = (struct glx_context *) ctx; 453 454 EXPECT_FALSE(gc->isDirect); 455 } 456 457 TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_client_state_private) 458 { 459 GLXContext ctx = 460 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 461 False, NULL); 462 463 ASSERT_NE((GLXContext) 0, ctx); 464 465 struct glx_context *gc = (struct glx_context *) ctx; 466 467 ASSERT_FALSE(gc->isDirect); 468 EXPECT_EQ((struct __GLXattributeRec *) 0xcafebabe, 469 gc->client_state_private); 470 } 471 472 TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_config) 473 { 474 GLXContext ctx = 475 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 476 False, NULL); 477 478 ASSERT_NE((GLXContext) 0, ctx); 479 480 struct glx_context *gc = (struct glx_context *) ctx; 481 482 EXPECT_EQ(&this->fbc, gc->config); 483 } 484 485 TEST_F(glXCreateContextAttribARB_test, correct_context_screen_number) 486 { 487 this->fbc.screen = 7; 488 psc->scr = 7; 489 490 GLXContext ctx = 491 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 492 False, NULL); 493 494 ASSERT_NE((GLXContext) 0, ctx); 495 496 struct glx_context *gc = (struct glx_context *) ctx; 497 498 EXPECT_EQ(7, gc->screen); 499 } 500 501 TEST_F(glXCreateContextAttribARB_test, correct_context_screen_pointer) 502 { 503 GLXContext ctx = 504 glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0, 505 False, NULL); 506 507 ASSERT_NE((GLXContext) 0, ctx); 508 509 struct glx_context *gc = (struct glx_context *) ctx; 510 511 EXPECT_EQ(psc, gc->psc); 512 } 513 /*@}*/ 514