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