Home | History | Annotate | Download | only in tests
      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:
     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 
     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
     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 *
    119 XGetXCBConnection(Display *dpy)
    120 {
    121    return (xcb_connection_t *) 0xdeadbeef;
    122 }
    123 
    124 extern "C" xcb_void_cookie_t
    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
    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
    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 *
    218 __glXGetClientGLExtensionString()
    219 {
    220    char *str = (char *) malloc(sizeof(ext));
    221 
    222    memcpy(str, ext, sizeof(ext));
    223    return str;
    224 }
    225 
    226 glX_send_client_info_test::glX_send_client_info_test()
    227    : glx_dpy(0), display(0)
    228 {
    229    /* empty */
    230 }
    231 
    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
    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
    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
    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
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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