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