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