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