1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Jon Turney
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 DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
25*61046927SAndroid Build Coastguard Worker #include "glx_error.h"
26*61046927SAndroid Build Coastguard Worker #include "dri_common.h"
27*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
28*61046927SAndroid Build Coastguard Worker #include "windows/xwindowsdri.h"
29*61046927SAndroid Build Coastguard Worker #include "windows/windowsgl.h"
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker struct driwindows_context
32*61046927SAndroid Build Coastguard Worker {
33*61046927SAndroid Build Coastguard Worker struct glx_context base;
34*61046927SAndroid Build Coastguard Worker windowsContext *windowsContext;
35*61046927SAndroid Build Coastguard Worker };
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker struct driwindows_config
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker struct glx_config base;
40*61046927SAndroid Build Coastguard Worker int pxfi;
41*61046927SAndroid Build Coastguard Worker };
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker struct driwindows_screen
44*61046927SAndroid Build Coastguard Worker {
45*61046927SAndroid Build Coastguard Worker struct glx_screen base;
46*61046927SAndroid Build Coastguard Worker __DRIscreen *driScreen;
47*61046927SAndroid Build Coastguard Worker int event_base;
48*61046927SAndroid Build Coastguard Worker Bool copySubBuffer;
49*61046927SAndroid Build Coastguard Worker };
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker struct driwindows_drawable
52*61046927SAndroid Build Coastguard Worker {
53*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable base;
54*61046927SAndroid Build Coastguard Worker windowsDrawable *windowsDrawable;
55*61046927SAndroid Build Coastguard Worker };
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker /**
58*61046927SAndroid Build Coastguard Worker * GLXDRI functions
59*61046927SAndroid Build Coastguard Worker */
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker static void
driwindows_destroy_context(struct glx_context * context)62*61046927SAndroid Build Coastguard Worker driwindows_destroy_context(struct glx_context *context)
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker struct driwindows_context *pcp = (struct driwindows_context *) context;
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker driReleaseDrawables(&pcp->base);
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker free((char *) context->extensions);
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker windows_destroy_context(pcp->windowsContext);
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker free(pcp);
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker static int
driwindows_bind_context(struct glx_context * context,GLXDrawable draw,GLXDrawable read)76*61046927SAndroid Build Coastguard Worker driwindows_bind_context(struct glx_context *context, GLXDrawable draw, GLXDrawable read)
77*61046927SAndroid Build Coastguard Worker {
78*61046927SAndroid Build Coastguard Worker struct driwindows_context *pcp = (struct driwindows_context *) context;
79*61046927SAndroid Build Coastguard Worker struct driwindows_drawable *pdraw, *pread;
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker pdraw = (struct driwindows_drawable *) driFetchDrawable(context, draw);
82*61046927SAndroid Build Coastguard Worker pread = (struct driwindows_drawable *) driFetchDrawable(context, read);
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker driReleaseDrawables(&pcp->base);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker if (pdraw == NULL || pread == NULL)
87*61046927SAndroid Build Coastguard Worker return GLXBadDrawable;
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker if (windows_bind_context(pcp->windowsContext,
90*61046927SAndroid Build Coastguard Worker pdraw->windowsDrawable, pread->windowsDrawable))
91*61046927SAndroid Build Coastguard Worker return Success;
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker return GLXBadContext;
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker static void
driwindows_unbind_context(struct glx_context * context)97*61046927SAndroid Build Coastguard Worker driwindows_unbind_context(struct glx_context *context)
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker struct driwindows_context *pcp = (struct driwindows_context *) context;
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker windows_unbind_context(pcp->windowsContext);
102*61046927SAndroid Build Coastguard Worker }
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable driwindows_context_vtable = {
105*61046927SAndroid Build Coastguard Worker .destroy = driwindows_destroy_context,
106*61046927SAndroid Build Coastguard Worker .bind = driwindows_bind_context,
107*61046927SAndroid Build Coastguard Worker .unbind = driwindows_unbind_context,
108*61046927SAndroid Build Coastguard Worker .wait_gl = NULL,
109*61046927SAndroid Build Coastguard Worker .wait_x = NULL,
110*61046927SAndroid Build Coastguard Worker };
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker static struct glx_context *
driwindows_create_context(struct glx_screen * base,struct glx_config * config_base,struct glx_context * shareList,int renderType)113*61046927SAndroid Build Coastguard Worker driwindows_create_context(struct glx_screen *base,
114*61046927SAndroid Build Coastguard Worker struct glx_config *config_base,
115*61046927SAndroid Build Coastguard Worker struct glx_context *shareList, int renderType)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker struct driwindows_context *pcp, *pcp_shared;
118*61046927SAndroid Build Coastguard Worker struct driwindows_config *config = (struct driwindows_config *) config_base;
119*61046927SAndroid Build Coastguard Worker struct driwindows_screen *psc = (struct driwindows_screen *) base;
120*61046927SAndroid Build Coastguard Worker windowsContext *shared = NULL;
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker if (!psc->base.driScreen)
123*61046927SAndroid Build Coastguard Worker return NULL;
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker /* Check the renderType value */
126*61046927SAndroid Build Coastguard Worker if (!validate_renderType_against_config(config_base, renderType))
127*61046927SAndroid Build Coastguard Worker return NULL;
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker if (shareList) {
130*61046927SAndroid Build Coastguard Worker /* If the shareList context is not on this renderer, we cannot possibly
131*61046927SAndroid Build Coastguard Worker * create a context that shares with it.
132*61046927SAndroid Build Coastguard Worker */
133*61046927SAndroid Build Coastguard Worker if (shareList->vtable->destroy != driwindows_destroy_context) {
134*61046927SAndroid Build Coastguard Worker return NULL;
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker pcp_shared = (struct driwindows_context *) shareList;
138*61046927SAndroid Build Coastguard Worker shared = pcp_shared->windowsContext;
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker pcp = calloc(1, sizeof *pcp);
142*61046927SAndroid Build Coastguard Worker if (pcp == NULL)
143*61046927SAndroid Build Coastguard Worker return NULL;
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
146*61046927SAndroid Build Coastguard Worker free(pcp);
147*61046927SAndroid Build Coastguard Worker return NULL;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker pcp->base.renderType = renderType;
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker InfoMessageF("visualID %x, fbConfigID %x -> pxfi %d\n", config_base->visualID, config_base->fbconfigID, config->pxfi);
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker pcp->windowsContext = windows_create_context(config->pxfi, shared);
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker if (!pcp->windowsContext) {
157*61046927SAndroid Build Coastguard Worker free(pcp);
158*61046927SAndroid Build Coastguard Worker return NULL;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker pcp->base.vtable = &driwindows_context_vtable;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker return &pcp->base;
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker static struct glx_context *
driwindows_create_context_attribs(struct glx_screen * base,struct glx_config * config_base,struct glx_context * shareList,unsigned num_attribs,const uint32_t * attribs,unsigned * error)167*61046927SAndroid Build Coastguard Worker driwindows_create_context_attribs(struct glx_screen *base,
168*61046927SAndroid Build Coastguard Worker struct glx_config *config_base,
169*61046927SAndroid Build Coastguard Worker struct glx_context *shareList,
170*61046927SAndroid Build Coastguard Worker unsigned num_attribs,
171*61046927SAndroid Build Coastguard Worker const uint32_t *attribs,
172*61046927SAndroid Build Coastguard Worker unsigned *error)
173*61046927SAndroid Build Coastguard Worker {
174*61046927SAndroid Build Coastguard Worker struct driwindows_context *pcp, *pcp_shared;
175*61046927SAndroid Build Coastguard Worker struct driwindows_config *config = (struct driwindows_config *) config_base;
176*61046927SAndroid Build Coastguard Worker struct driwindows_screen *psc = (struct driwindows_screen *) base;
177*61046927SAndroid Build Coastguard Worker windowsContext *shared = NULL;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker int i;
180*61046927SAndroid Build Coastguard Worker uint32_t renderType = GLX_RGBA_TYPE;
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker /* Extract renderType from attribs */
183*61046927SAndroid Build Coastguard Worker for (i = 0; i < num_attribs; i++) {
184*61046927SAndroid Build Coastguard Worker switch (attribs[i * 2]) {
185*61046927SAndroid Build Coastguard Worker case GLX_RENDER_TYPE:
186*61046927SAndroid Build Coastguard Worker renderType = attribs[i * 2 + 1];
187*61046927SAndroid Build Coastguard Worker break;
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker /*
192*61046927SAndroid Build Coastguard Worker Perhaps we should map GLX tokens to WGL tokens, but they appear to have
193*61046927SAndroid Build Coastguard Worker identical values, so far
194*61046927SAndroid Build Coastguard Worker */
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker if (!psc->base.driScreen || !config_base)
197*61046927SAndroid Build Coastguard Worker return NULL;
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker /* Check the renderType value */
200*61046927SAndroid Build Coastguard Worker if (!validate_renderType_against_config(config_base, renderType)) {
201*61046927SAndroid Build Coastguard Worker return NULL;
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker if (shareList) {
205*61046927SAndroid Build Coastguard Worker /* If the shareList context is not on this renderer, we cannot possibly
206*61046927SAndroid Build Coastguard Worker * create a context that shares with it.
207*61046927SAndroid Build Coastguard Worker */
208*61046927SAndroid Build Coastguard Worker if (shareList->vtable->destroy != driwindows_destroy_context) {
209*61046927SAndroid Build Coastguard Worker return NULL;
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker pcp_shared = (struct driwindows_context *) shareList;
213*61046927SAndroid Build Coastguard Worker shared = pcp_shared->windowsContext;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker pcp = calloc(1, sizeof *pcp);
217*61046927SAndroid Build Coastguard Worker if (pcp == NULL)
218*61046927SAndroid Build Coastguard Worker return NULL;
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
221*61046927SAndroid Build Coastguard Worker free(pcp);
222*61046927SAndroid Build Coastguard Worker return NULL;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker pcp->base.renderType = renderType;
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker InfoMessageF("visualID %x, fbConfigID %x -> pxfi %d\n", config_base->visualID, config_base->fbconfigID, config->pxfi);
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker pcp->windowsContext = windows_create_context_attribs(config->pxfi,
230*61046927SAndroid Build Coastguard Worker shared,
231*61046927SAndroid Build Coastguard Worker (const int *)attribs);
232*61046927SAndroid Build Coastguard Worker if (pcp->windowsContext == NULL) {
233*61046927SAndroid Build Coastguard Worker free(pcp);
234*61046927SAndroid Build Coastguard Worker return NULL;
235*61046927SAndroid Build Coastguard Worker }
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker pcp->base.vtable = &driwindows_context_vtable;
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker return &pcp->base;
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker static void
driwindowsDestroyDrawable(__GLXDRIdrawable * pdraw)243*61046927SAndroid Build Coastguard Worker driwindowsDestroyDrawable(__GLXDRIdrawable * pdraw)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker struct driwindows_drawable *pdp = (struct driwindows_drawable *) pdraw;
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker windows_destroy_drawable(pdp->windowsDrawable);
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker free(pdp);
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker static __GLXDRIdrawable *
driwindowsCreateDrawable(struct glx_screen * base,XID xDrawable,GLXDrawable drawable,int type,struct glx_config * modes)253*61046927SAndroid Build Coastguard Worker driwindowsCreateDrawable(struct glx_screen *base, XID xDrawable,
254*61046927SAndroid Build Coastguard Worker GLXDrawable drawable, int type,
255*61046927SAndroid Build Coastguard Worker struct glx_config *modes)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker struct driwindows_drawable *pdp;
258*61046927SAndroid Build Coastguard Worker struct driwindows_screen *psc = (struct driwindows_screen *) base;
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker pdp = calloc(1, sizeof(*pdp));
261*61046927SAndroid Build Coastguard Worker if (!pdp)
262*61046927SAndroid Build Coastguard Worker return NULL;
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker pdp->base.xDrawable = xDrawable;
265*61046927SAndroid Build Coastguard Worker pdp->base.drawable = drawable;
266*61046927SAndroid Build Coastguard Worker pdp->base.psc = &psc->base;
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker /*
269*61046927SAndroid Build Coastguard Worker By this stage, the X drawable already exists, but the GLX drawable may
270*61046927SAndroid Build Coastguard Worker not.
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker Query the server with the XID to find the correct HWND, HPBUFFERARB or
273*61046927SAndroid Build Coastguard Worker HBITMAP
274*61046927SAndroid Build Coastguard Worker */
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker unsigned int type;
277*61046927SAndroid Build Coastguard Worker void *handle;
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker if (!XWindowsDRIQueryDrawable(psc->base.dpy, base->scr, drawable, &type, &handle))
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker free(pdp);
282*61046927SAndroid Build Coastguard Worker return NULL;
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker /* No handle found is a failure */
286*61046927SAndroid Build Coastguard Worker if (!handle) {
287*61046927SAndroid Build Coastguard Worker free(pdp);
288*61046927SAndroid Build Coastguard Worker return NULL;
289*61046927SAndroid Build Coastguard Worker }
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker /* Create a new drawable */
292*61046927SAndroid Build Coastguard Worker pdp->windowsDrawable = windows_create_drawable(type, handle);
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker if (!pdp->windowsDrawable) {
295*61046927SAndroid Build Coastguard Worker free(pdp);
296*61046927SAndroid Build Coastguard Worker return NULL;
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker pdp->base.destroyDrawable = driwindowsDestroyDrawable;
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker return &pdp->base;
302*61046927SAndroid Build Coastguard Worker }
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker static int64_t
driwindowsSwapBuffers(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,Bool flush)305*61046927SAndroid Build Coastguard Worker driwindowsSwapBuffers(__GLXDRIdrawable * pdraw,
306*61046927SAndroid Build Coastguard Worker int64_t target_msc, int64_t divisor, int64_t remainder,
307*61046927SAndroid Build Coastguard Worker Bool flush)
308*61046927SAndroid Build Coastguard Worker {
309*61046927SAndroid Build Coastguard Worker struct driwindows_drawable *pdp = (struct driwindows_drawable *) pdraw;
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker (void) target_msc;
312*61046927SAndroid Build Coastguard Worker (void) divisor;
313*61046927SAndroid Build Coastguard Worker (void) remainder;
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker if (flush) {
316*61046927SAndroid Build Coastguard Worker glFlush();
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker windows_swap_buffers(pdp->windowsDrawable);
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker return 0;
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker static void
driwindowsCopySubBuffer(__GLXDRIdrawable * pdraw,int x,int y,int width,int height,Bool flush)325*61046927SAndroid Build Coastguard Worker driwindowsCopySubBuffer(__GLXDRIdrawable * pdraw,
326*61046927SAndroid Build Coastguard Worker int x, int y, int width, int height, Bool flush)
327*61046927SAndroid Build Coastguard Worker {
328*61046927SAndroid Build Coastguard Worker struct driwindows_drawable *pdp = (struct driwindows_drawable *) pdraw;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker if (flush) {
331*61046927SAndroid Build Coastguard Worker glFlush();
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker windows_copy_subbuffer(pdp->windowsDrawable, x, y, width, height);
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker static const struct glx_screen_vtable driwindows_screen_vtable = {
338*61046927SAndroid Build Coastguard Worker .create_context = driwindows_create_context,
339*61046927SAndroid Build Coastguard Worker .create_context_attribs = driwindows_create_context_attribs,
340*61046927SAndroid Build Coastguard Worker .query_renderer_integer = NULL,
341*61046927SAndroid Build Coastguard Worker .query_renderer_string = NULL,
342*61046927SAndroid Build Coastguard Worker };
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker static Bool
driwindowsBindExtensions(struct driwindows_screen * psc)345*61046927SAndroid Build Coastguard Worker driwindowsBindExtensions(struct driwindows_screen *psc)
346*61046927SAndroid Build Coastguard Worker {
347*61046927SAndroid Build Coastguard Worker Bool result = 1;
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker const struct
350*61046927SAndroid Build Coastguard Worker {
351*61046927SAndroid Build Coastguard Worker char *wglext;
352*61046927SAndroid Build Coastguard Worker char *glxext;
353*61046927SAndroid Build Coastguard Worker Bool mandatory;
354*61046927SAndroid Build Coastguard Worker } extensionMap[] = {
355*61046927SAndroid Build Coastguard Worker { "WGL_ARB_make_current_read", "GLX_SGI_make_current_read", 0 },
356*61046927SAndroid Build Coastguard Worker { "WGL_EXT_swap_control", "GLX_SGI_swap_control", 0 },
357*61046927SAndroid Build Coastguard Worker { "WGL_EXT_swap_control", "GLX_MESA_swap_control", 0 },
358*61046927SAndroid Build Coastguard Worker // { "WGL_ARB_render_texture", "GLX_EXT_texture_from_pixmap", 0 },
359*61046927SAndroid Build Coastguard Worker // Not exactly equivalent, needs some more glue to be written
360*61046927SAndroid Build Coastguard Worker { "WGL_ARB_pbuffer", "GLX_SGIX_pbuffer", 1 },
361*61046927SAndroid Build Coastguard Worker { "WGL_ARB_multisample", "GLX_ARB_multisample", 1 },
362*61046927SAndroid Build Coastguard Worker { "WGL_ARB_multisample", "GLX_SGIS_multisample", 1 },
363*61046927SAndroid Build Coastguard Worker { "WGL_ARB_create_context", "GLX_ARB_create_context", 0 },
364*61046927SAndroid Build Coastguard Worker { "WGL_ARB_create_context_profile", "GLX_ARB_create_context_profile", 0 },
365*61046927SAndroid Build Coastguard Worker { "WGL_ARB_create_context_robustness", "GLX_ARB_create_context_robustness", 0 },
366*61046927SAndroid Build Coastguard Worker { "WGL_EXT_create_context_es2_profile", "GLX_EXT_create_context_es2_profile", 0 },
367*61046927SAndroid Build Coastguard Worker };
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker char *wgl_extensions;
370*61046927SAndroid Build Coastguard Worker char *gl_extensions;
371*61046927SAndroid Build Coastguard Worker int i;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker windows_extensions(&gl_extensions, &wgl_extensions);
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(extensionMap); i++) {
376*61046927SAndroid Build Coastguard Worker if (strstr(wgl_extensions, extensionMap[i].wglext)) {
377*61046927SAndroid Build Coastguard Worker __glXEnableDirectExtension(&psc->base, extensionMap[i].glxext);
378*61046927SAndroid Build Coastguard Worker InfoMessageF("enabled %s\n", extensionMap[i].glxext);
379*61046927SAndroid Build Coastguard Worker }
380*61046927SAndroid Build Coastguard Worker else if (extensionMap[i].mandatory) {
381*61046927SAndroid Build Coastguard Worker ErrorMessageF("required WGL extension %s is missing\n", extensionMap[i].wglext);
382*61046927SAndroid Build Coastguard Worker result = 0;
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker /*
387*61046927SAndroid Build Coastguard Worker Because it pre-dates WGL_EXT_extensions_string, GL_WIN_swap_hint might
388*61046927SAndroid Build Coastguard Worker only be in GL_EXTENSIONS
389*61046927SAndroid Build Coastguard Worker */
390*61046927SAndroid Build Coastguard Worker if (strstr(gl_extensions, "GL_WIN_swap_hint")) {
391*61046927SAndroid Build Coastguard Worker psc->copySubBuffer = 1;
392*61046927SAndroid Build Coastguard Worker __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
393*61046927SAndroid Build Coastguard Worker InfoMessageF("enabled GLX_MESA_copy_sub_buffer\n");
394*61046927SAndroid Build Coastguard Worker }
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker free(gl_extensions);
397*61046927SAndroid Build Coastguard Worker free(wgl_extensions);
398*61046927SAndroid Build Coastguard Worker
399*61046927SAndroid Build Coastguard Worker return result;
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker static struct glx_config *
driwindowsMapConfigs(struct glx_display * priv,int screen,struct glx_config * configs,struct glx_config * fbconfigs)403*61046927SAndroid Build Coastguard Worker driwindowsMapConfigs(struct glx_display *priv, int screen, struct glx_config *configs, struct glx_config *fbconfigs)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker struct glx_config head, *tail, *m;
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker tail = &head;
408*61046927SAndroid Build Coastguard Worker head.next = NULL;
409*61046927SAndroid Build Coastguard Worker
410*61046927SAndroid Build Coastguard Worker for (m = configs; m; m = m->next) {
411*61046927SAndroid Build Coastguard Worker int fbconfigID = GLX_DONT_CARE;
412*61046927SAndroid Build Coastguard Worker if (fbconfigs) {
413*61046927SAndroid Build Coastguard Worker /*
414*61046927SAndroid Build Coastguard Worker visuals have fbconfigID of GLX_DONT_CARE, so search for a fbconfig
415*61046927SAndroid Build Coastguard Worker with matching visualID and get the fbconfigID from there
416*61046927SAndroid Build Coastguard Worker */
417*61046927SAndroid Build Coastguard Worker struct glx_config *f;
418*61046927SAndroid Build Coastguard Worker for (f = fbconfigs; f; f = f->next) {
419*61046927SAndroid Build Coastguard Worker if (f->visualID == m->visualID)
420*61046927SAndroid Build Coastguard Worker fbconfigID = f->fbconfigID;
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker else {
424*61046927SAndroid Build Coastguard Worker fbconfigID = m->fbconfigID;
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker int pxfi;
428*61046927SAndroid Build Coastguard Worker XWindowsDRIFBConfigToPixelFormat(priv->dpy, screen, fbconfigID, &pxfi);
429*61046927SAndroid Build Coastguard Worker if (pxfi == 0)
430*61046927SAndroid Build Coastguard Worker continue;
431*61046927SAndroid Build Coastguard Worker
432*61046927SAndroid Build Coastguard Worker struct driwindows_config *config = malloc(sizeof(*config));
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker tail->next = &config->base;
435*61046927SAndroid Build Coastguard Worker if (tail->next == NULL)
436*61046927SAndroid Build Coastguard Worker continue;
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker config->base = *m;
439*61046927SAndroid Build Coastguard Worker config->pxfi = pxfi;
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker tail = tail->next;
442*61046927SAndroid Build Coastguard Worker }
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker return head.next;
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker static struct glx_screen *
driwindowsCreateScreen(int screen,struct glx_display * priv,bool driver_name_is_inferred)448*61046927SAndroid Build Coastguard Worker driwindowsCreateScreen(int screen, struct glx_display *priv, bool driver_name_is_inferred)
449*61046927SAndroid Build Coastguard Worker {
450*61046927SAndroid Build Coastguard Worker __GLXDRIscreen *psp;
451*61046927SAndroid Build Coastguard Worker struct driwindows_screen *psc;
452*61046927SAndroid Build Coastguard Worker struct glx_config *configs = NULL, *visuals = NULL;
453*61046927SAndroid Build Coastguard Worker int directCapable;
454*61046927SAndroid Build Coastguard Worker int eventBase, errorBase;
455*61046927SAndroid Build Coastguard Worker int major, minor, patch;
456*61046927SAndroid Build Coastguard Worker
457*61046927SAndroid Build Coastguard Worker /* Verify server has Windows-DRI extension */
458*61046927SAndroid Build Coastguard Worker if (!XWindowsDRIQueryExtension(dpy, &eventBase, &errorBase)) {
459*61046927SAndroid Build Coastguard Worker ErrorMessageF("Windows-DRI extension not available\n");
460*61046927SAndroid Build Coastguard Worker return NULL;
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker if (!XWindowsDRIQueryVersion(dpy, &major, &minor, &patch)) {
464*61046927SAndroid Build Coastguard Worker ErrorMessageF("Fetching Windows-DRI extension version failed\n");
465*61046927SAndroid Build Coastguard Worker return NULL;
466*61046927SAndroid Build Coastguard Worker }
467*61046927SAndroid Build Coastguard Worker
468*61046927SAndroid Build Coastguard Worker if (!windows_check_renderer()) {
469*61046927SAndroid Build Coastguard Worker ErrorMessageF("Windows-DRI extension disabled for GDI Generic renderer\n");
470*61046927SAndroid Build Coastguard Worker return NULL;
471*61046927SAndroid Build Coastguard Worker }
472*61046927SAndroid Build Coastguard Worker
473*61046927SAndroid Build Coastguard Worker psc = calloc(1, sizeof *psc);
474*61046927SAndroid Build Coastguard Worker if (psc == NULL)
475*61046927SAndroid Build Coastguard Worker return NULL;
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker if (!glx_screen_init(&psc->base, screen, priv)) {
478*61046927SAndroid Build Coastguard Worker free(psc);
479*61046927SAndroid Build Coastguard Worker return NULL;
480*61046927SAndroid Build Coastguard Worker }
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker if (!XWindowsDRIQueryDirectRenderingCapable(psc->base.dpy, screen, &directCapable) ||
483*61046927SAndroid Build Coastguard Worker !directCapable) {
484*61046927SAndroid Build Coastguard Worker ErrorMessageF("Screen is not Windows-DRI capable\n");
485*61046927SAndroid Build Coastguard Worker goto handle_error;
486*61046927SAndroid Build Coastguard Worker }
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker /* discover native supported extensions */
489*61046927SAndroid Build Coastguard Worker if (!driwindowsBindExtensions(psc)) {
490*61046927SAndroid Build Coastguard Worker goto handle_error;
491*61046927SAndroid Build Coastguard Worker }
492*61046927SAndroid Build Coastguard Worker
493*61046927SAndroid Build Coastguard Worker /* Augment configs with pxfi information */
494*61046927SAndroid Build Coastguard Worker configs = driwindowsMapConfigs(priv, screen, psc->base.configs, NULL);
495*61046927SAndroid Build Coastguard Worker visuals = driwindowsMapConfigs(priv, screen, psc->base.visuals, configs);
496*61046927SAndroid Build Coastguard Worker
497*61046927SAndroid Build Coastguard Worker if (!configs || !visuals) {
498*61046927SAndroid Build Coastguard Worker ErrorMessageF("No fbConfigs or visuals found\n");
499*61046927SAndroid Build Coastguard Worker goto handle_error;
500*61046927SAndroid Build Coastguard Worker }
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker glx_config_destroy_list(psc->base.configs);
503*61046927SAndroid Build Coastguard Worker psc->base.configs = configs;
504*61046927SAndroid Build Coastguard Worker glx_config_destroy_list(psc->base.visuals);
505*61046927SAndroid Build Coastguard Worker psc->base.visuals = visuals;
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker psc->base.vtable = &driwindows_screen_vtable;
508*61046927SAndroid Build Coastguard Worker psp = &psc->base.driScreen;
509*61046927SAndroid Build Coastguard Worker psp->createDrawable = driwindowsCreateDrawable;
510*61046927SAndroid Build Coastguard Worker psp->swapBuffers = driwindowsSwapBuffers;
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker if (psc->copySubBuffer)
513*61046927SAndroid Build Coastguard Worker psp->copySubBuffer = driwindowsCopySubBuffer;
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker priv->driver = GLX_DRIVER_WINDOWS;
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker return &psc->base;
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker handle_error:
520*61046927SAndroid Build Coastguard Worker glx_screen_cleanup(&psc->base);
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker return NULL;
523*61046927SAndroid Build Coastguard Worker }
524