Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.