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 57extern "C" struct glx_screen * 58GetGLXScreenConfigs(Display * dpy, int scrn) 59{ 60 (void) dpy; 61 (void) scrn; 62 return psc; 63} 64 65extern "C" uint32_t 66xcb_generate_id(xcb_connection_t *c) 67{ 68 (void) c; 69 70 return next_id++; 71} 72 73extern "C" xcb_void_cookie_t 74xcb_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 102extern "C" xcb_generic_error_t * 103xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie) 104{ 105 return NULL; 106} 107 108extern "C" void 109__glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err) 110{ 111} 112 113extern "C" void 114__glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID, 115 uint_fast16_t minorCode, bool coreX11error) 116{ 117} 118 119class glXCreateContextAttribARB_test : public ::testing::Test { 120public: 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 132void 133glXCreateContextAttribARB_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 147void 148glXCreateContextAttribARB_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/*@{*/ 163TEST_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 173TEST_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 182TEST_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/*@{*/ 200TEST_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 208TEST_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 216TEST_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 224TEST_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 239TEST_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 247TEST_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 255TEST_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 265TEST_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 275TEST_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 286TEST_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 309TEST_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 321TEST_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 329TEST_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/*@{*/ 351TEST_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 367TEST_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 382TEST_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 401TEST_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 414TEST_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 427TEST_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 442TEST_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 457TEST_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 472TEST_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 485TEST_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 501TEST_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