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