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