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