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