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(int screen)213 __glXGetClientGLExtensionString(int screen)
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 glxSendClientInfo(this->glx_dpy, -1);
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 glxSendClientInfo(this->glx_dpy, -1);
294 EXPECT_TRUE(*value);
295 }
296
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_3)297 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_3)
298 {
299 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
300 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
301 * sent to a GLX server that only has GLX 1.3 regardless of the extension
302 * setting.
303 */
304 common_protocol_expected_false_test(1, 3,
305 "GLX_ARB_create_context",
306 &SetClientInfoARB_was_sent);
307 }
308
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_1)309 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_1)
310 {
311 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
312 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
313 * sent to a GLX server that only has GLX 1.3 regardless of the extension
314 * setting.
315 */
316 common_protocol_expected_false_test(1, 3,
317 "GLX_ARB_create_context",
318 &SetClientInfoARB_was_sent);
319 }
320
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)321 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)
322 {
323 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
324 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
325 * sent to a GLX server that has GLX 1.4 but has an empty extension string
326 * (i.e., no extensions at all).
327 */
328 common_protocol_expected_false_test(1, 4,
329 "",
330 &SetClientInfoARB_was_sent);
331 }
332
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_without_extension)333 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_without_extension)
334 {
335 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
336 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
337 * sent to a GLX server that has GLX 1.4 but doesn't have the extension.
338 */
339 common_protocol_expected_false_test(1, 4,
340 "GLX_EXT_texture_from_pixmap",
341 &SetClientInfoARB_was_sent);
342 }
343
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)344 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)
345 {
346 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
347 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
348 * sent to a GLX server that has GLX 1.4 but does not have the extension.
349 *
350 * This test differs from
351 * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
352 * extension exists that looks like the correct extension but isn't.
353 */
354 common_protocol_expected_false_test(1, 4,
355 "GLX_ARB_create_context2",
356 &SetClientInfoARB_was_sent);
357 }
358
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)359 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)
360 {
361 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
362 * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
363 * sent to a GLX server that has GLX 1.4 but does not have the extension.
364 *
365 * This test differs from
366 * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
367 * extension exists that looks like the correct extension but isn't.
368 */
369 common_protocol_expected_false_test(1, 4,
370 "GLX_ARB_create_context_profile",
371 &SetClientInfoARB_was_sent);
372 }
373
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_3)374 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_3)
375 {
376 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
377 * GLX_ARB_create_context_profile extension. Verify that no
378 * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.3
379 * regardless of the extension setting.
380 */
381 common_protocol_expected_false_test(1, 3,
382 "GLX_ARB_create_context_profile",
383 &SetClientInfo2ARB_was_sent);
384 }
385
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_1)386 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_1)
387 {
388 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
389 * GLX_ARB_create_context_profile extension. Verify that no
390 * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.1
391 * regardless of the extension setting.
392 */
393 common_protocol_expected_false_test(1, 1,
394 "GLX_ARB_create_context_profile",
395 &SetClientInfo2ARB_was_sent);
396 }
397
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)398 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)
399 {
400 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
401 * GLX_ARB_create_context_profile extension. Verify that no
402 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but has an
403 * empty extension string (i.e., no extensions at all).
404 */
405 common_protocol_expected_false_test(1, 4,
406 "",
407 &SetClientInfo2ARB_was_sent);
408 }
409
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)410 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)
411 {
412 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
413 * GLX_ARB_create_context_profile extension. Verify that no
414 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but
415 * doesn't have the extension.
416 */
417 common_protocol_expected_false_test(1, 4,
418 "GLX_EXT_texture_from_pixmap",
419 &SetClientInfo2ARB_was_sent);
420 }
421
TEST_F(glX_send_client_info_test,doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)422 TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)
423 {
424 /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
425 * GLX_ARB_create_context_profile extension. Verify that no
426 * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but does
427 * not have the extension.
428 *
429 * This test differs from
430 * doesnt_send_SetClientInfo2ARB_for_1_4_without_extension in that an
431 * extension exists that looks like the correct extension but isn't.
432 */
433 common_protocol_expected_false_test(1, 4,
434 "GLX_ARB_create_context_profile2",
435 &SetClientInfo2ARB_was_sent);
436 }
437
TEST_F(glX_send_client_info_test,does_send_ClientInfo_for_1_1)438 TEST_F(glX_send_client_info_test, does_send_ClientInfo_for_1_1)
439 {
440 /* The glXClientInfo protocol was added in GLX 1.1. Verify that
441 * glXClientInfo is sent to a GLX server that has GLX 1.1.
442 */
443 common_protocol_expected_true_test(1, 1,
444 "",
445 &ClientInfo_was_sent);
446 }
447
TEST_F(glX_send_client_info_test,does_send_SetClientInfoARB_for_1_4_with_extension)448 TEST_F(glX_send_client_info_test, does_send_SetClientInfoARB_for_1_4_with_extension)
449 {
450 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
451 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
452 * sent to a GLX server that has GLX 1.4 and the extension.
453 */
454 common_protocol_expected_true_test(1, 4,
455 "GLX_ARB_create_context",
456 &SetClientInfoARB_was_sent);
457 }
458
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)459 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)
460 {
461 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
462 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
463 * sent to a GLX server that has GLX 1.4 and the extension.
464 */
465 common_protocol_expected_true_test(1, 4,
466 "GLX_ARB_create_context_profile",
467 &SetClientInfo2ARB_was_sent);
468 }
469
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)470 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)
471 {
472 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
473 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
474 * sent to a GLX server that has GLX 1.4 and the extension.
475 */
476 common_protocol_expected_true_test(1, 4,
477 "GLX_ARB_create_context "
478 "GLX_ARB_create_context_profile",
479 &SetClientInfo2ARB_was_sent);
480 }
481
TEST_F(glX_send_client_info_test,does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)482 TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)
483 {
484 /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
485 * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
486 * sent to a GLX server that has GLX 1.4 and the extension.
487 */
488 common_protocol_expected_true_test(1, 4,
489 "GLX_ARB_create_context_profile "
490 "GLX_ARB_create_context",
491 &SetClientInfo2ARB_was_sent);
492 }
493
TEST_F(glX_send_client_info_test,uses_correct_connection)494 TEST_F(glX_send_client_info_test, uses_correct_connection)
495 {
496 create_single_screen_display(1, 1, "");
497 glxSendClientInfo(this->glx_dpy, -1);
498 EXPECT_EQ((xcb_connection_t *) 0xdeadbeef, connection_used);
499 }
500
TEST_F(glX_send_client_info_test,sends_correct_gl_extension_string)501 TEST_F(glX_send_client_info_test, sends_correct_gl_extension_string)
502 {
503 create_single_screen_display(1, 1, "");
504 glxSendClientInfo(this->glx_dpy, -1);
505
506 ASSERT_EQ((int) sizeof(ext), gl_ext_length);
507 ASSERT_NE((char *) 0, gl_ext_string);
508 EXPECT_EQ(0, memcmp(gl_ext_string, ext, sizeof(ext)));
509 }
510
TEST_F(glX_send_client_info_test,gl_versions_are_sane)511 TEST_F(glX_send_client_info_test, gl_versions_are_sane)
512 {
513 create_single_screen_display(1, 4, "GLX_ARB_create_context");
514 glxSendClientInfo(this->glx_dpy, -1);
515
516 ASSERT_NE(0, num_gl_versions);
517
518 unsigned versions_below_3_0 = 0;
519 for (int i = 0; i < num_gl_versions; i++) {
520 EXPECT_LT(0u, gl_versions[i * 2]);
521 EXPECT_GE(4u, gl_versions[i * 2]);
522
523 /* Verify that the minor version advertised with the major version makes
524 * sense.
525 */
526 switch (gl_versions[i * 2]) {
527 case 1:
528 EXPECT_GE(5u, gl_versions[i * 2 + 1]);
529 versions_below_3_0++;
530 break;
531 case 2:
532 EXPECT_GE(1u, gl_versions[i * 2 + 1]);
533 versions_below_3_0++;
534 break;
535 case 3:
536 EXPECT_GE(3u, gl_versions[i * 2 + 1]);
537 break;
538 case 4:
539 EXPECT_GE(2u, gl_versions[i * 2 + 1]);
540 break;
541 }
542 }
543
544 /* From the GLX_ARB_create_context spec:
545 *
546 * "Only the highest supported version below 3.0 should be sent, since
547 * OpenGL 2.1 is backwards compatible with all earlier versions."
548 */
549 EXPECT_LE(versions_below_3_0, 1u);
550 }
551
TEST_F(glX_send_client_info_test,gl_versions_and_profiles_are_sane)552 TEST_F(glX_send_client_info_test, gl_versions_and_profiles_are_sane)
553 {
554 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
555 glxSendClientInfo(this->glx_dpy, -1);
556
557 ASSERT_NE(0, num_gl_versions);
558
559 const uint32_t all_valid_bits = GLX_CONTEXT_CORE_PROFILE_BIT_ARB
560 | GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
561 const uint32_t es_bit = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
562
563 unsigned versions_below_3_0 = 0;
564
565 for (int i = 0; i < num_gl_versions; i++) {
566 EXPECT_LT(0u, gl_versions[i * 3]);
567 EXPECT_GE(4u, gl_versions[i * 3]);
568
569 /* Verify that the minor version advertised with the major version makes
570 * sense.
571 */
572 switch (gl_versions[i * 3]) {
573 case 1:
574 if (gl_versions[i * 3 + 2] & es_bit) {
575 EXPECT_GE(1u, gl_versions[i * 3 + 1]);
576 EXPECT_EQ(es_bit, gl_versions[i * 3 + 2]);
577 } else {
578 EXPECT_GE(5u, gl_versions[i * 3 + 1]);
579 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
580 versions_below_3_0++;
581 }
582 break;
583 case 2:
584 if (gl_versions[i * 3 + 2] & es_bit) {
585 EXPECT_EQ(0u, gl_versions[i * 3 + 1]);
586 EXPECT_EQ(es_bit, gl_versions[i * 3 + 2]);
587 } else {
588 EXPECT_GE(1u, gl_versions[i * 3 + 1]);
589 EXPECT_EQ(0u, gl_versions[i * 3 + 2]);
590 versions_below_3_0++;
591 }
592 break;
593 case 3:
594 EXPECT_GE(3u, gl_versions[i * 3 + 1]);
595
596 /* Profiles were not introduced until OpenGL 3.2.
597 */
598 if (gl_versions[i * 3 + 1] < 2) {
599 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(es_bit));
600 } else if (gl_versions[i * 3 + 1] == 2) {
601 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits | es_bit));
602 } else {
603 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits));
604 }
605 break;
606 case 4:
607 EXPECT_GE(6u, gl_versions[i * 3 + 1]);
608 EXPECT_EQ(0u, gl_versions[i * 3 + 2] & ~(all_valid_bits));
609 break;
610 }
611 }
612
613 /* From the GLX_ARB_create_context_profile spec:
614 *
615 * "Only the highest supported version below 3.0 should be sent, since
616 * OpenGL 2.1 is backwards compatible with all earlier versions."
617 */
618 EXPECT_LE(versions_below_3_0, 1u);
619 }
620
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_1)621 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_1)
622 {
623 create_single_screen_display(1, 1, "");
624 glxSendClientInfo(this->glx_dpy, -1);
625
626 EXPECT_EQ(1, glx_major);
627 EXPECT_EQ(4, glx_minor);
628 }
629
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4)630 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4)
631 {
632 create_single_screen_display(1, 4, "");
633 glxSendClientInfo(this->glx_dpy, -1);
634
635 EXPECT_EQ(1, glx_major);
636 EXPECT_EQ(4, glx_minor);
637 }
638
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4_with_ARB_create_context)639 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context)
640 {
641 create_single_screen_display(1, 4, "GLX_ARB_create_context");
642 glxSendClientInfo(this->glx_dpy, -1);
643
644 EXPECT_EQ(1, glx_major);
645 EXPECT_EQ(4, glx_minor);
646 }
647
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)648 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)
649 {
650 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
651 glxSendClientInfo(this->glx_dpy, -1);
652
653 EXPECT_EQ(1, glx_major);
654 EXPECT_EQ(4, glx_minor);
655 }
656
TEST_F(glX_send_client_info_test,glx_version_is_1_4_for_1_5)657 TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_5)
658 {
659 create_single_screen_display(1, 5, "");
660 glxSendClientInfo(this->glx_dpy, -1);
661
662 EXPECT_EQ(1, glx_major);
663 EXPECT_EQ(4, glx_minor);
664 }
665
TEST_F(glX_send_client_info_test,glx_extensions_has_GLX_ARB_create_context)666 TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context)
667 {
668 create_single_screen_display(1, 4, "GLX_ARB_create_context");
669 glxSendClientInfo(this->glx_dpy, -1);
670
671 ASSERT_NE(0, glx_ext_length);
672 ASSERT_NE((char *) 0, glx_ext_string);
673
674 bool found_GLX_ARB_create_context = false;
675 const char *const needle = "GLX_ARB_create_context";
676 const unsigned len = strlen(needle);
677 char *haystack = glx_ext_string;
678 while (haystack != NULL) {
679 char *match = strstr(haystack, needle);
680
681 if (match[len] == '\0' || match[len] == ' ') {
682 found_GLX_ARB_create_context = true;
683 break;
684 }
685
686 haystack = match + len;
687 }
688
689 EXPECT_TRUE(found_GLX_ARB_create_context);
690 }
691
TEST_F(glX_send_client_info_test,glx_extensions_has_GLX_ARB_create_context_profile)692 TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context_profile)
693 {
694 create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
695 glxSendClientInfo(this->glx_dpy, -1);
696
697 ASSERT_NE(0, glx_ext_length);
698 ASSERT_NE((char *) 0, glx_ext_string);
699
700 bool found_GLX_ARB_create_context_profile = false;
701 const char *const needle = "GLX_ARB_create_context_profile";
702 const unsigned len = strlen(needle);
703 char *haystack = glx_ext_string;
704 while (haystack != NULL) {
705 char *match = strstr(haystack, needle);
706
707 if (match[len] == '\0' || match[len] == ' ') {
708 found_GLX_ARB_create_context_profile = true;
709 break;
710 }
711
712 haystack = match + len;
713 }
714
715 EXPECT_TRUE(found_GLX_ARB_create_context_profile);
716 }
717