create_context_unittest.cpp revision 01e04c3f
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
33static bool CreateContextAttribsARB_was_sent;
34static xcb_glx_create_context_attribs_arb_request_t req;
35static uint32_t sent_attribs[1024];
36static uint32_t next_id;
37
38
39struct glx_screen *psc;
40
41extern "C" Bool
42glx_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
55bool GetGLXScreenConfigs_called = false;
56
57extern "C" struct glx_screen *
58GetGLXScreenConfigs(Display * dpy, int scrn)
59{
60   (void) dpy;
61   (void) scrn;
62
63   GetGLXScreenConfigs_called = true;
64   return psc;
65}
66
67extern "C" uint32_t
68xcb_generate_id(xcb_connection_t *c)
69{
70   (void) c;
71
72   return next_id++;
73}
74
75extern "C" xcb_void_cookie_t
76xcb_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
104extern "C" xcb_generic_error_t *
105xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
106{
107   return NULL;
108}
109
110extern "C" void
111__glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err)
112{
113}
114
115extern "C" void
116__glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID,
117               uint_fast16_t minorCode, bool coreX11error)
118{
119}
120
121class glXCreateContextAttribARB_test : public ::testing::Test {
122public:
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
134void
135glXCreateContextAttribARB_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
149void
150glXCreateContextAttribARB_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/*@{*/
165TEST_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
175TEST_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
184TEST_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/*@{*/
202TEST_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
210TEST_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
218TEST_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
226TEST_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
241TEST_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
249TEST_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
257TEST_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
267TEST_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
277TEST_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
288TEST_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
311TEST_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
323TEST_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
331TEST_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/*@{*/
353TEST_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
369TEST_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
384TEST_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
403TEST_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
416TEST_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
429TEST_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
444TEST_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
459TEST_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
474TEST_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
487TEST_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
503TEST_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