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
28 #include <xcb/glx.h>
29
30 #include "mock_xdisplay.h"
31 #include "fake_glx_screen.h"
32
33 /**
34 * \name Wrappers around some X structures to make the more usable for tests
35 */
36 /*@{*/
37 class fake_glx_screen;
38
39 class fake_glx_display : public glx_display {
40 public:
fake_glx_display(mock_XDisplay * dpy,int major,int minor)41 fake_glx_display(mock_XDisplay *dpy, int major, int minor)
42 {
43 this->next = 0;
44 this->dpy = dpy;
45 this->minorVersion = minor;
46 this->glXDrawHash = 0;
47
48 this->screens = new glx_screen *[dpy->nscreens];
49 memset(this->screens, 0, sizeof(struct glx_screen *) * dpy->nscreens);
50 }
51
~fake_glx_display()52 ~fake_glx_display()
53 {
54 for (int i = 0; i < this->dpy->nscreens; i++) {
55 if (this->screens[i] != NULL)
56 delete (fake_glx_screen *)this->screens[i];
57 }
58
59 delete [] this->screens;
60 }
61
62 void init_screen(int i, const char *ext);
63 };
64
65 class glX_send_client_info_test : public ::testing::Test {
66 public:
67 glX_send_client_info_test();
68 virtual ~glX_send_client_info_test();
69 virtual void SetUp();
70 virtual void TearDown();
71
72 void common_protocol_expected_false_test(unsigned major, unsigned minor,
73 const char *glx_ext, bool *value);
74
75 void common_protocol_expected_true_test(unsigned major, unsigned minor,
76 const char *glx_ext, bool *value);
77
78 void create_single_screen_display(unsigned major, unsigned minor,
79 const char *glx_ext);
80
81 void destroy_display();
82
83 protected:
84 fake_glx_display *glx_dpy;
85 mock_XDisplay *display;
86 };
87
88 void
init_screen(int i,const char * ext)89 fake_glx_display::init_screen(int i, const char *ext)
90 {
91 if (this->screens[i] != NULL)
92 delete this->screens[i];
93
94 this->screens[i] = new fake_glx_screen(this, i, ext);
95 }
96 /*@}*/
97
98 static const char ext[] = "GL_XXX_dummy";
99
100 static bool ClientInfo_was_sent;
101 static bool SetClientInfoARB_was_sent;
102 static bool SetClientInfo2ARB_was_sent;
103 static xcb_connection_t *connection_used;
104 static int gl_ext_length;
105 static char *gl_ext_string;
106 static int glx_ext_length;
107 static char *glx_ext_string;
108 static int num_gl_versions;
109 static uint32_t *gl_versions;
110 static int glx_major;
111 static int glx_minor;
112
113 extern "C" xcb_connection_t *
XGetXCBConnection(Display * dpy)114 XGetXCBConnection(Display *dpy)
115 {
116 return (xcb_connection_t *) 0xdeadbeef;
117 }
118
119 extern "C" xcb_void_cookie_t
xcb_glx_client_info(xcb_connection_t * c,uint32_t major_version,uint32_t minor_version,uint32_t str_len,const char * string)120 xcb_glx_client_info(xcb_connection_t *c,
121 uint32_t major_version,
122 uint32_t minor_version,
123 uint32_t str_len,
124 const char *string)
125 {
126 xcb_void_cookie_t cookie;
127
128 ClientInfo_was_sent = true;
129 connection_used = c;
130
131 gl_ext_string = new char[str_len];
132 memcpy(gl_ext_string, string, str_len);
133 gl_ext_length = str_len;
134
135 glx_major = major_version;
136 glx_minor = minor_version;
137
138 cookie.sequence = 0;
139 return cookie;
140 }
141
142 extern "C" xcb_void_cookie_t
xcb_glx_set_client_info_arb(xcb_connection_t * c,uint32_t major_version,uint32_t minor_version,uint32_t num_versions,uint32_t gl_str_len,uint32_t glx_str_len,const uint32_t * versions,const char * gl_string,const char * glx_string)143 xcb_glx_set_client_info_arb(xcb_connection_t *c,
144 uint32_t major_version,
145 uint32_t minor_version,
146 uint32_t num_versions,
147 uint32_t gl_str_len,
148 uint32_t glx_str_len,
149 const uint32_t *versions,
150 const char *gl_string,
151 const char *glx_string)
152 {
153 xcb_void_cookie_t cookie;
154
155 SetClientInfoARB_was_sent = true;
156 connection_used = c;
157
158 gl_ext_string = new char[gl_str_len];
159 memcpy(gl_ext_string, gl_string, gl_str_len);
160 gl_ext_length = gl_str_len;
161
162 glx_ext_string = new char[glx_str_len];
163 memcpy(glx_ext_string, glx_string, glx_str_len);
164 glx_ext_length = glx_str_len;
165
166 gl_versions = new uint32_t[num_versions * 2];
167 memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 2);
168 num_gl_versions = num_versions;
169
170 glx_major = major_version;
171 glx_minor = minor_version;
172
173 cookie.sequence = 0;
174 return cookie;
175 }
176
177 extern "C" xcb_void_cookie_t
xcb_glx_set_client_info_2arb(xcb_connection_t * c,uint32_t major_version,uint32_t minor_version,uint32_t num_versions,uint32_t gl_str_len,uint32_t glx_str_len,const uint32_t * versions,const char * gl_string,const char * glx_string)178 xcb_glx_set_client_info_2arb(xcb_connection_t *c,
179 uint32_t major_version,
180 uint32_t minor_version,
181 uint32_t num_versions,
182 uint32_t gl_str_len,
183 uint32_t glx_str_len,
184 const uint32_t *versions,
185 const char *gl_string,
186 const char *glx_string)
187 {
188 xcb_void_cookie_t cookie;
189
190 SetClientInfo2ARB_was_sent = true;
191 connection_used = c;
192
193 gl_ext_string = new char[gl_str_len];
194 memcpy(gl_ext_string, gl_string, gl_str_len);
195 gl_ext_length = gl_str_len;
196
197 glx_ext_string = new char[glx_str_len];
198 memcpy(glx_ext_string, glx_string, glx_str_len);
199 glx_ext_length = glx_str_len;
200
201 gl_versions = new uint32_t[num_versions * 3];
202 memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 3);
203 num_gl_versions = num_versions;
204
205 glx_major = major_version;
206 glx_minor = minor_version;
207
208 cookie.sequence = 0;
209 return cookie;
210 }
211
212 extern "C" char *
__glXGetClientGLExtensionString()213 __glXGetClientGLExtensionString()
214 {
215 char *str = (char *) malloc(sizeof(ext));
216
217 memcpy(str, ext, sizeof(ext));
218 return str;
219 }
220
glX_send_client_info_test()221 glX_send_client_info_test::glX_send_client_info_test()
222 : glx_dpy(0), display(0)
223 {
224 /* empty */
225 }
226
~glX_send_client_info_test()227 glX_send_client_info_test::~glX_send_client_info_test()
228 {
229 if (glx_dpy)
230 delete glx_dpy;
231
232 if (display)
233 delete display;
234 }
235
236 void
SetUp()237 glX_send_client_info_test::SetUp()
238 {
239 ClientInfo_was_sent = false;
240 SetClientInfoARB_was_sent = false;
241 SetClientInfo2ARB_was_sent = false;
242 connection_used = (xcb_connection_t *) ~0;
243 gl_ext_length = 0;
244 gl_ext_string = (char *) 0;
245 glx_ext_length = 0;
246 glx_ext_string = (char *) 0;
247 num_gl_versions = 0;
248 gl_versions = (uint32_t *) 0;
249 glx_major = 0;
250 glx_minor = 0;
251 }
252
253 void
TearDown()254 glX_send_client_info_test::TearDown()
255 {
256 if (gl_ext_string)
257 delete [] gl_ext_string;
258 if (glx_ext_string)
259 delete [] glx_ext_string;
260 if (gl_versions)
261 delete [] gl_versions;
262 }
263
264 void
create_single_screen_display(unsigned major,unsigned minor,const char * glx_ext)265 glX_send_client_info_test::create_single_screen_display(unsigned major,
266 unsigned minor,
267 const char *glx_ext)
268 {
269 this->display = new mock_XDisplay(1);
270
271 this->glx_dpy = new fake_glx_display(this->display, major, minor);
272 this->glx_dpy->init_screen(0, glx_ext);
273 }
274
275 void
common_protocol_expected_false_test(unsigned major,unsigned minor,const char * glx_ext,bool * value)276 glX_send_client_info_test::common_protocol_expected_false_test(unsigned major,
277 unsigned minor,
278 const char *glx_ext,
279 bool *value)
280 {
281 create_single_screen_display(major, minor, glx_ext);
282 __glX_send_client_info(this->glx_dpy);
283 EXPECT_FALSE(*value);
284 }
285
286 void
common_protocol_expected_true_test(unsigned major,unsigned minor,const char * glx_ext,bool * value)287 glX_send_client_info_test::common_protocol_expected_true_test(unsigned major,
288 unsigned minor,
289 const char *glx_ext,
290 bool *value)
291 {
292 create_single_screen_display(major, minor, glx_ext);
293 __glX_send_client_info(this->glx_dpy);
294 EXPECT_TRUE(*value);
295 }
296
TEST_F(glX_send_client_info_test,doesnt_send_ClientInfo_for_1_0)297 TEST_F(glX_send_client_info_test, doesnt_send_ClientInfo_for_1_0)
298 {
299 /* The glXClientInfo protocol was added in GLX 1.1. Verify that no
300 * glXClientInfo is sent to a GLX server that only has GLX 1.0.
301 */
302 common_protocol_expected_false_test(1, 0, "", &ClientInfo_was_sent);
303 }
304
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_0)305 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_0)
306 {
307 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
308 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
309 * sent to a GLX server that only has GLX 1.0 regardless of the extension
310 * setting.
311 */
312 common_protocol_expected_false_test(1, 0,
313 "GLX_ARB_create_context",
314 &SetClientInfoARB_was_sent);
315 }
316
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_1)317 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_1)
318 {
319 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
320 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
321 * sent to a GLX server that only has GLX 1.0 regardless of the extension
322 * setting.
323 */
324 common_protocol_expected_false_test(1, 1,
325 "GLX_ARB_create_context",
326 &SetClientInfoARB_was_sent);
327 }
328
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)329 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)
330 {
331 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
332 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
333 * sent to a GLX server that has GLX 1.4 but has an empty extension string
334 * (i.e., no extensions at all).
335 */
336 common_protocol_expected_false_test(1, 4,
337 "",
338 &SetClientInfoARB_was_sent);
339 }
340
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_without_extension)341 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_without_extension)
342 {
343 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
344 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
345 * sent to a GLX server that has GLX 1.4 but doesn't have the extension.
346 */
347 common_protocol_expected_false_test(1, 4,
348 "GLX_EXT_texture_from_pixmap",
349 &SetClientInfoARB_was_sent);
350 }
351
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)352 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)
353 {
354 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
355 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
356 * sent to a GLX server that has GLX 1.4 but does not have the extension.
357 *
358 * This test differs from
359 * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
360 * extension exists that looks like the correct extension but isn't.
361 */
362 common_protocol_expected_false_test(1, 4,
363 "GLX_ARB_create_context2",
364 &SetClientInfoARB_was_sent);
365 }
366
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)367 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)
368 {
369 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
370 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
371 * sent to a GLX server that has GLX 1.4 but does not have the extension.
372 *
373 * This test differs from
374 * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
375 * extension exists that looks like the correct extension but isn't.
376 */
377 common_protocol_expected_false_test(1, 4,
378 "GLX_ARB_create_context_profile",
379 &SetClientInfoARB_was_sent);
380 }
381
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_0)382 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_0)
383 {
384 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
385 * GLX_ARB_create_context_profile extension. Verify that no
386 * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.0
387 * regardless of the extension setting.
388 */
389 common_protocol_expected_false_test(1, 0,
390 "GLX_ARB_create_context_profile",
391 &SetClientInfo2ARB_was_sent);
392 }
393
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_1)394 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_1)
395 {
396 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
397 * GLX_ARB_create_context_profile extension. Verify that no
398 * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.1
399 * regardless of the extension setting.
400 */
401 common_protocol_expected_false_test(1, 1,
402 "GLX_ARB_create_context_profile",
403 &SetClientInfo2ARB_was_sent);
404 }
405
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)406 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)
407 {
408 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
409 * GLX_ARB_create_context_profile extension. Verify that no
410 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but has an
411 * empty extension string (i.e., no extensions at all).
412 */
413 common_protocol_expected_false_test(1, 4,
414 "",
415 &SetClientInfo2ARB_was_sent);
416 }
417
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)418 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)
419 {
420 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
421 * GLX_ARB_create_context_profile extension. Verify that no
422 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but
423 * doesn't have the extension.
424 */
425 common_protocol_expected_false_test(1, 4,
426 "GLX_EXT_texture_from_pixmap",
427 &SetClientInfo2ARB_was_sent);
428 }
429
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)430 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)
431 {
432 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
433 * GLX_ARB_create_context_profile extension. Verify that no
434 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but does
435 * not have the extension.
436 *
437 * This test differs from
438 * doesnt_send_SetClientInfo2ARB_for_1_4_without_extension in that an
439 * extension exists that looks like the correct extension but isn't.
440 */
441 common_protocol_expected_false_test(1, 4,
442 "GLX_ARB_create_context_profile2",
443 &SetClientInfo2ARB_was_sent);
444 }
445
TEST_F(glX_send_client_info_test,does_send_ClientInfo_for_1_1)446 TEST_F(glX_send_client_info_test, does_send_ClientInfo_for_1_1)
447 {
448 /* The glXClientInfo protocol was added in GLX 1.1. Verify that
449 * glXClientInfo is sent to a GLX server that has GLX 1.1.
450 */
451 common_protocol_expected_true_test(1, 1,
452 "",
453 &ClientInfo_was_sent);
454 }
455
TEST_F(glX_send_client_info_test,does_send_SetClientInfoARB_for_1_4_with_extension)456 TEST_F(glX_send_client_info_test, does_send_SetClientInfoARB_for_1_4_with_extension)
457 {
458 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
459 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
460 * sent to a GLX server that has GLX 1.4 and the extension.
461 */
462 common_protocol_expected_true_test(1, 4,
463 "GLX_ARB_create_context",
464 &SetClientInfoARB_was_sent);
465 }
466
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)467 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)
468 {
469 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
470 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
471 * sent to a GLX server that has GLX 1.4 and the extension.
472 */
473 common_protocol_expected_true_test(1, 4,
474 "GLX_ARB_create_context_profile",
475 &SetClientInfo2ARB_was_sent);
476 }
477
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)478 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)
479 {
480 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
481 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
482 * sent to a GLX server that has GLX 1.4 and the extension.
483 */
484 common_protocol_expected_true_test(1, 4,
485 "GLX_ARB_create_context "
486 "GLX_ARB_create_context_profile",
487 &SetClientInfo2ARB_was_sent);
488 }
489
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)490 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)
491 {
492 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
493 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
494 * sent to a GLX server that has GLX 1.4 and the extension.
495 */
496 common_protocol_expected_true_test(1, 4,
497 "GLX_ARB_create_context_profile "
498 "GLX_ARB_create_context",
499 &SetClientInfo2ARB_was_sent);
500 }
501
TEST_F(glX_send_client_info_test,uses_correct_connection)502 TEST_F(glX_send_client_info_test, uses_correct_connection)
503 {
504 create_single_screen_display(1, 1, "");
505 __glX_send_client_info(this->glx_dpy);
506 EXPECT_EQ((xcb_connection_t *) 0xdeadbeef, connection_used);
507 }
508
TEST_F(glX_send_client_info_test,sends_correct_gl_extension_string)509 TEST_F(glX_send_client_info_test, sends_correct_gl_extension_string)
510 {
511 create_single_screen_display(1, 1, "");
512 __glX_send_client_info(this->glx_dpy);
513
514 ASSERT_EQ((int) sizeof(ext), gl_ext_length);
515 ASSERT_NE((char *) 0, gl_ext_string);
516 EXPECT_EQ(0, memcmp(gl_ext_string, ext, sizeof(ext)));
517 }
518
TEST_F(glX_send_client_info_test,gl_versions_are_sane)519 TEST_F(glX_send_client_info_test, gl_versions_are_sane)
520 {
521 create_single_screen_display(1, 4, "GLX_ARB_create_context");
522 __glX_send_client_info(this->glx_dpy);
523
524 ASSERT_NE(0, num_gl_versions);
525
526 unsigned versions_below_3_0 = 0;
527 for (int i = 0; i < num_gl_versions; i++) {
528 EXPECT_LT(0u, gl_versions[i * 2]);
529 EXPECT_GE(4u, gl_versions[i * 2]);
530
531 /* Verify that the minor version advertised with the major version makes
532 * sense.
533 */
534 switch (gl_versions[i * 2]) {
535 case 1:
536 EXPECT_GE(5u, gl_versions[i * 2 + 1]);
537 versions_below_3_0++;
538 break;
539 case 2:
540 EXPECT_GE(1u, gl_versions[i * 2 + 1]);
541 versions_below_3_0++;
542 break;
543 case 3:
544 EXPECT_GE(3u, gl_versions[i * 2 + 1]);
545 break;
546 case 4:
547 EXPECT_GE(2u, gl_versions[i * 2 + 1]);
548 break;
549 }
550 }
551
552 /* From the GLX_ARB_create_context spec:
553 *
554 * "Only the highest supported version below 3.0 should be sent, since
555 * OpenGL 2.1 is backwards compatible with all earlier versions."
556 */
557 EXPECT_LE(versions_below_3_0, 1u);
558 }
559
TEST_F(glX_send_client_info_test,gl_versions_and_profiles_are_sane)560 TEST_F(glX_send_client_info_test, gl_versions_and_profiles_are_sane)
561 {
562 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
563 __glX_send_client_info(this->glx_dpy);
564
565 ASSERT_NE(0, num_gl_versions);
566
567 const uint32_t all_valid_bits = GLX_CONTEXT_CORE_PROFILE_BIT_ARB
568 | GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
569 const uint32_t es_bit = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
570
571 unsigned versions_below_3_0 = 0;
572
573 for (int i = 0; i < num_gl_versions; i++) {
574 EXPECT_LT(0u, gl_versions[i * 3]);
575 EXPECT_GE(4u, gl_versions[i * 3]);
576
577 /* Verify that the minor version advertised with the major version makes
578 * sense.
579 */
580 switch (gl_versions[i * 3]) {
581 case 1:
582 if (gl_versions[i * 3 + 2] & es_bit) {
583 EXPECT_GE(1u, gl_versions[i * 3 + 1]);
584 EXPECT_EQ(es_bit, gl_versions[i * 3 + 2]);
585 } else {
586 EXPECT_GE(5u, gl_versions[i * 3 + 1]);
587 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
588 versions_below_3_0++;
589 }
590 break;
591 case 2:
592 if (gl_versions[i * 3 + 2] & es_bit) {
593 EXPECT_EQ(0u, gl_versions[i * 3 + 1]);
594 EXPECT_EQ(es_bit, gl_versions[i * 3 + 2]);
595 } else {
596 EXPECT_GE(1u, gl_versions[i * 3 + 1]);
597 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
598 versions_below_3_0++;
599 }
600 break;
601 case 3:
602 EXPECT_GE(3u, gl_versions[i * 3 + 1]);
603
604 /* Profiles were not introduced until OpenGL 3.2.
605 */
606 if (gl_versions[i * 3 + 1] < 2) {
607 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(es_bit));
608 } else if (gl_versions[i * 3 + 1] == 2) {
609 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits | es_bit));
610 } else {
611 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits));
612 }
613 break;
614 case 4:
615 EXPECT_GE(6u, gl_versions[i * 3 + 1]);
616 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits));
617 break;
618 }
619 }
620
621 /* From the GLX_ARB_create_context_profile spec:
622 *
623 * "Only the highest supported version below 3.0 should be sent, since
624 * OpenGL 2.1 is backwards compatible with all earlier versions."
625 */
626 EXPECT_LE(versions_below_3_0, 1u);
627 }
628
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_1)629 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_1)
630 {
631 create_single_screen_display(1, 1, "");
632 __glX_send_client_info(this->glx_dpy);
633
634 EXPECT_EQ(1, glx_major);
635 EXPECT_EQ(4, glx_minor);
636 }
637
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4)638 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4)
639 {
640 create_single_screen_display(1, 4, "");
641 __glX_send_client_info(this->glx_dpy);
642
643 EXPECT_EQ(1, glx_major);
644 EXPECT_EQ(4, glx_minor);
645 }
646
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4_with_ARB_create_context)647 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context)
648 {
649 create_single_screen_display(1, 4, "GLX_ARB_create_context");
650 __glX_send_client_info(this->glx_dpy);
651
652 EXPECT_EQ(1, glx_major);
653 EXPECT_EQ(4, glx_minor);
654 }
655
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)656 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)
657 {
658 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
659 __glX_send_client_info(this->glx_dpy);
660
661 EXPECT_EQ(1, glx_major);
662 EXPECT_EQ(4, glx_minor);
663 }
664
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_5)665 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_5)
666 {
667 create_single_screen_display(1, 5, "");
668 __glX_send_client_info(this->glx_dpy);
669
670 EXPECT_EQ(1, glx_major);
671 EXPECT_EQ(4, glx_minor);
672 }
673
TEST_F(glX_send_client_info_test,glx_extensions_has_GLX_ARB_create_context)674 TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context)
675 {
676 create_single_screen_display(1, 4, "GLX_ARB_create_context");
677 __glX_send_client_info(this->glx_dpy);
678
679 ASSERT_NE(0, glx_ext_length);
680 ASSERT_NE((char *) 0, glx_ext_string);
681
682 bool found_GLX_ARB_create_context = false;
683 const char *const needle = "GLX_ARB_create_context";
684 const unsigned len = strlen(needle);
685 char *haystack = glx_ext_string;
686 while (haystack != NULL) {
687 char *match = strstr(haystack, needle);
688
689 if (match[len] == '\0' || match[len] == ' ') {
690 found_GLX_ARB_create_context = true;
691 break;
692 }
693
694 haystack = match + len;
695 }
696
697 EXPECT_TRUE(found_GLX_ARB_create_context);
698 }
699
TEST_F(glX_send_client_info_test,glx_extensions_has_GLX_ARB_create_context_profile)700 TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context_profile)
701 {
702 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
703 __glX_send_client_info(this->glx_dpy);
704
705 ASSERT_NE(0, glx_ext_length);
706 ASSERT_NE((char *) 0, glx_ext_string);
707
708 bool found_GLX_ARB_create_context_profile = false;
709 const char *const needle = "GLX_ARB_create_context_profile";
710 const unsigned len = strlen(needle);
711 char *haystack = glx_ext_string;
712 while (haystack != NULL) {
713 char *match = strstr(haystack, needle);
714
715 if (match[len] == '\0' || match[len] == ' ') {
716 found_GLX_ARB_create_context_profile = true;
717 break;
718 }
719
720 haystack = match + len;
721 }
722
723 EXPECT_TRUE(found_GLX_ARB_create_context_profile);
724 }
725