xref: /aosp_15_r20/external/mesa3d/src/glx/clientinfo.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2011 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include <string.h>
25*61046927SAndroid Build Coastguard Worker #include <ctype.h>
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
28*61046927SAndroid Build Coastguard Worker #include <xcb/glx.h>
29*61046927SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker void
glxSendClientInfo(struct glx_display * glx_dpy,int screen)32*61046927SAndroid Build Coastguard Worker glxSendClientInfo(struct glx_display *glx_dpy, int screen)
33*61046927SAndroid Build Coastguard Worker {
34*61046927SAndroid Build Coastguard Worker    const unsigned ext_length = strlen("GLX_ARB_create_context");
35*61046927SAndroid Build Coastguard Worker    const unsigned prof_length = strlen("_profile");
36*61046927SAndroid Build Coastguard Worker    char *gl_extension_string;
37*61046927SAndroid Build Coastguard Worker    int gl_extension_length;
38*61046927SAndroid Build Coastguard Worker    xcb_connection_t *c;
39*61046927SAndroid Build Coastguard Worker    Bool any_screen_has_ARB_create_context = False;
40*61046927SAndroid Build Coastguard Worker    Bool any_screen_has_ARB_create_context_profile = False;
41*61046927SAndroid Build Coastguard Worker    unsigned i;
42*61046927SAndroid Build Coastguard Worker    /* You need GLX_ARB_create_context_profile to get beyond 3.1 anyway */
43*61046927SAndroid Build Coastguard Worker    static const uint32_t gl_versions[] = {
44*61046927SAndroid Build Coastguard Worker       2, 1,
45*61046927SAndroid Build Coastguard Worker       3, 0,
46*61046927SAndroid Build Coastguard Worker       3, 1,
47*61046927SAndroid Build Coastguard Worker    };
48*61046927SAndroid Build Coastguard Worker    /*
49*61046927SAndroid Build Coastguard Worker     * This is weird, but it matches what NVIDIA does/expects. For big-GL
50*61046927SAndroid Build Coastguard Worker     * below 3.2 there is no such thing as a "profile", so we name them all
51*61046927SAndroid Build Coastguard Worker     * with no profile bits. Except we don't name anything lower than 2.1,
52*61046927SAndroid Build Coastguard Worker     * since GLX_ARB_create_context_profile says:
53*61046927SAndroid Build Coastguard Worker     *
54*61046927SAndroid Build Coastguard Worker     *   "Only the highest supported version below 3.0 should be sent, since
55*61046927SAndroid Build Coastguard Worker     *   OpenGL 2.1 is backwards compatible with all earlier versions."
56*61046927SAndroid Build Coastguard Worker     *
57*61046927SAndroid Build Coastguard Worker     * In order to also support GLES below 3.2, we name every possible GLES
58*61046927SAndroid Build Coastguard Worker     * version with the ES2 bit set, which happens to just mean GLES generally
59*61046927SAndroid Build Coastguard Worker     * and not a particular major version. 3.2 happens to be a legal version
60*61046927SAndroid Build Coastguard Worker     * number for both big-GL and GLES, so it gets all three bits set.
61*61046927SAndroid Build Coastguard Worker     * Everything 3.3 and above is big-GL only so gets the core and compat
62*61046927SAndroid Build Coastguard Worker     * bits set.
63*61046927SAndroid Build Coastguard Worker     */
64*61046927SAndroid Build Coastguard Worker    static const uint32_t gl_versions_profiles[] = {
65*61046927SAndroid Build Coastguard Worker       1, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
66*61046927SAndroid Build Coastguard Worker       1, 1, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
67*61046927SAndroid Build Coastguard Worker       2, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
68*61046927SAndroid Build Coastguard Worker       2, 1, 0x0,
69*61046927SAndroid Build Coastguard Worker       3, 0, 0x0,
70*61046927SAndroid Build Coastguard Worker       3, 0, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
71*61046927SAndroid Build Coastguard Worker       3, 1, 0x0,
72*61046927SAndroid Build Coastguard Worker       3, 1, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
73*61046927SAndroid Build Coastguard Worker       3, 2, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
74*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB |
75*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
76*61046927SAndroid Build Coastguard Worker       3, 3, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
77*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
78*61046927SAndroid Build Coastguard Worker       4, 0, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
79*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
80*61046927SAndroid Build Coastguard Worker       4, 1, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
81*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
82*61046927SAndroid Build Coastguard Worker       4, 2, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
83*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
84*61046927SAndroid Build Coastguard Worker       4, 3, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
85*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
86*61046927SAndroid Build Coastguard Worker       4, 4, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
87*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
88*61046927SAndroid Build Coastguard Worker       4, 5, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
89*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
90*61046927SAndroid Build Coastguard Worker       4, 6, GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
91*61046927SAndroid Build Coastguard Worker             GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
92*61046927SAndroid Build Coastguard Worker    };
93*61046927SAndroid Build Coastguard Worker    static const char glx_extensions[] =
94*61046927SAndroid Build Coastguard Worker       "GLX_ARB_create_context GLX_ARB_create_context_profile";
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    /* There are three possible flavors of the client info structure that the
97*61046927SAndroid Build Coastguard Worker     * client could send to the server.  The version sent depends on the
98*61046927SAndroid Build Coastguard Worker     * combination of GLX versions and extensions supported by the client and
99*61046927SAndroid Build Coastguard Worker     * the server. This client only supports GLX version >= 1.3.
100*61046927SAndroid Build Coastguard Worker     *
101*61046927SAndroid Build Coastguard Worker     * Server supports                  Client sends
102*61046927SAndroid Build Coastguard Worker     * ----------------------------------------------------------------------
103*61046927SAndroid Build Coastguard Worker     * GLX version = 1.0                Nothing.
104*61046927SAndroid Build Coastguard Worker     *
105*61046927SAndroid Build Coastguard Worker     * GLX version >= 1.1               struct GLXClientInfo
106*61046927SAndroid Build Coastguard Worker     *
107*61046927SAndroid Build Coastguard Worker     * GLX version >= 1.4 and
108*61046927SAndroid Build Coastguard Worker     * GLX_ARB_create_context           struct glXSetClientInfoARB
109*61046927SAndroid Build Coastguard Worker     *
110*61046927SAndroid Build Coastguard Worker     * GLX version >= 1.4 and
111*61046927SAndroid Build Coastguard Worker     * GLX_ARB_create_context_profile   struct glXSetClientInfo2ARB
112*61046927SAndroid Build Coastguard Worker     *
113*61046927SAndroid Build Coastguard Worker     * GLX_ARB_create_context and GLX_ARB_create_context_profile use FBConfigs,
114*61046927SAndroid Build Coastguard Worker     * and these only exist in GLX 1.4 or with GLX_SGIX_fbconfig.  I can't
115*61046927SAndroid Build Coastguard Worker     * imagine an implementation that supports GLX_SGIX_fbconfig and
116*61046927SAndroid Build Coastguard Worker     * GLX_ARB_create_context but not GLX 1.4.  Making GLX 1.4 a hard
117*61046927SAndroid Build Coastguard Worker     * requirement in this case does not seem like a limitation.
118*61046927SAndroid Build Coastguard Worker     */
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker    /* Determine whether any screen on the server supports either of the
121*61046927SAndroid Build Coastguard Worker     * create-context extensions.
122*61046927SAndroid Build Coastguard Worker     */
123*61046927SAndroid Build Coastguard Worker    for (i = 0; i < ScreenCount(glx_dpy->dpy); i++) {
124*61046927SAndroid Build Coastguard Worker       struct glx_screen *src = glx_dpy->screens[i];
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker       const char *haystack = src->serverGLXexts;
127*61046927SAndroid Build Coastguard Worker       while (haystack != NULL) {
128*61046927SAndroid Build Coastguard Worker     char *match = strstr(haystack, "GLX_ARB_create_context");
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker     if (match == NULL)
131*61046927SAndroid Build Coastguard Worker        break;
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker     match += ext_length;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker     switch (match[0]) {
136*61046927SAndroid Build Coastguard Worker     case '\0':
137*61046927SAndroid Build Coastguard Worker     case ' ':
138*61046927SAndroid Build Coastguard Worker        any_screen_has_ARB_create_context = True;
139*61046927SAndroid Build Coastguard Worker        break;
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker     case '_':
142*61046927SAndroid Build Coastguard Worker        if (strncmp(match, "_profile", prof_length) == 0
143*61046927SAndroid Build Coastguard Worker           && (match[prof_length] == '\0'
144*61046927SAndroid Build Coastguard Worker          || match[prof_length] == ' ')) {
145*61046927SAndroid Build Coastguard Worker           any_screen_has_ARB_create_context_profile = True;
146*61046927SAndroid Build Coastguard Worker           match += prof_length;
147*61046927SAndroid Build Coastguard Worker        }
148*61046927SAndroid Build Coastguard Worker        break;
149*61046927SAndroid Build Coastguard Worker     }
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker     haystack = match;
152*61046927SAndroid Build Coastguard Worker       }
153*61046927SAndroid Build Coastguard Worker    }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    gl_extension_string = __glXGetClientGLExtensionString(screen);
156*61046927SAndroid Build Coastguard Worker    gl_extension_length = strlen(gl_extension_string) + 1;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    c = XGetXCBConnection(glx_dpy->dpy);
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker    /* Depending on the GLX version and the available extensions on the server,
161*61046927SAndroid Build Coastguard Worker     * send the correct "flavor" of protocol to the server.
162*61046927SAndroid Build Coastguard Worker     *
163*61046927SAndroid Build Coastguard Worker     * THE ORDER IS IMPORTANT.  We want to send the most recent version of the
164*61046927SAndroid Build Coastguard Worker     * protocol that the server can support.
165*61046927SAndroid Build Coastguard Worker     */
166*61046927SAndroid Build Coastguard Worker    if (glx_dpy->minorVersion == 4
167*61046927SAndroid Build Coastguard Worker        && any_screen_has_ARB_create_context_profile) {
168*61046927SAndroid Build Coastguard Worker       xcb_glx_set_client_info_2arb(c,
169*61046927SAndroid Build Coastguard Worker               GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
170*61046927SAndroid Build Coastguard Worker                sizeof(gl_versions_profiles)
171*61046927SAndroid Build Coastguard Worker                / (3 * sizeof(gl_versions_profiles[0])),
172*61046927SAndroid Build Coastguard Worker               gl_extension_length,
173*61046927SAndroid Build Coastguard Worker               strlen(glx_extensions) + 1,
174*61046927SAndroid Build Coastguard Worker               gl_versions_profiles,
175*61046927SAndroid Build Coastguard Worker               gl_extension_string,
176*61046927SAndroid Build Coastguard Worker               glx_extensions);
177*61046927SAndroid Build Coastguard Worker    } else if (glx_dpy->minorVersion == 4
178*61046927SAndroid Build Coastguard Worker          && any_screen_has_ARB_create_context) {
179*61046927SAndroid Build Coastguard Worker       xcb_glx_set_client_info_arb(c,
180*61046927SAndroid Build Coastguard Worker               GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
181*61046927SAndroid Build Coastguard Worker               sizeof(gl_versions)
182*61046927SAndroid Build Coastguard Worker               / (2 * sizeof(gl_versions[0])),
183*61046927SAndroid Build Coastguard Worker               gl_extension_length,
184*61046927SAndroid Build Coastguard Worker               strlen(glx_extensions) + 1,
185*61046927SAndroid Build Coastguard Worker               gl_versions,
186*61046927SAndroid Build Coastguard Worker               gl_extension_string,
187*61046927SAndroid Build Coastguard Worker               glx_extensions);
188*61046927SAndroid Build Coastguard Worker    } else {
189*61046927SAndroid Build Coastguard Worker       xcb_glx_client_info(c,
190*61046927SAndroid Build Coastguard Worker            GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
191*61046927SAndroid Build Coastguard Worker            gl_extension_length,
192*61046927SAndroid Build Coastguard Worker            gl_extension_string);
193*61046927SAndroid Build Coastguard Worker    }
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker    free(gl_extension_string);
196*61046927SAndroid Build Coastguard Worker }
197