1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2013 Keith Packard
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission to use, copy, modify, distribute, and sell this software and its
5*61046927SAndroid Build Coastguard Worker * documentation for any purpose is hereby granted without fee, provided that
6*61046927SAndroid Build Coastguard Worker * the above copyright notice appear in all copies and that both that copyright
7*61046927SAndroid Build Coastguard Worker * notice and this permission notice appear in supporting documentation, and
8*61046927SAndroid Build Coastguard Worker * that the name of the copyright holders not be used in advertising or
9*61046927SAndroid Build Coastguard Worker * publicity pertaining to distribution of the software without specific,
10*61046927SAndroid Build Coastguard Worker * written prior permission. The copyright holders make no representations
11*61046927SAndroid Build Coastguard Worker * about the suitability of this software for any purpose. It is provided "as
12*61046927SAndroid Build Coastguard Worker * is" without express or implied warranty.
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*61046927SAndroid Build Coastguard Worker * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*61046927SAndroid Build Coastguard Worker * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*61046927SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*61046927SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*61046927SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20*61046927SAndroid Build Coastguard Worker * OF THIS SOFTWARE.
21*61046927SAndroid Build Coastguard Worker */
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker /*
24*61046927SAndroid Build Coastguard Worker * Portions of this code were adapted from dri2_glx.c which carries the
25*61046927SAndroid Build Coastguard Worker * following copyright:
26*61046927SAndroid Build Coastguard Worker *
27*61046927SAndroid Build Coastguard Worker * Copyright © 2008 Red Hat, Inc.
28*61046927SAndroid Build Coastguard Worker *
29*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
30*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Soft-
31*61046927SAndroid Build Coastguard Worker * ware"), to deal in the Software without restriction, including without
32*61046927SAndroid Build Coastguard Worker * limitation the rights to use, copy, modify, merge, publish, distribute,
33*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
34*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, provided that the above copyright
35*61046927SAndroid Build Coastguard Worker * notice(s) and this permission notice appear in all copies of the Soft-
36*61046927SAndroid Build Coastguard Worker * ware and that both the above copyright notice(s) and this permission
37*61046927SAndroid Build Coastguard Worker * notice appear in supporting documentation.
38*61046927SAndroid Build Coastguard Worker *
39*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
41*61046927SAndroid Build Coastguard Worker * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
42*61046927SAndroid Build Coastguard Worker * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
43*61046927SAndroid Build Coastguard Worker * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
44*61046927SAndroid Build Coastguard Worker * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
45*61046927SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
46*61046927SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
47*61046927SAndroid Build Coastguard Worker * MANCE OF THIS SOFTWARE.
48*61046927SAndroid Build Coastguard Worker *
49*61046927SAndroid Build Coastguard Worker * Except as contained in this notice, the name of a copyright holder shall
50*61046927SAndroid Build Coastguard Worker * not be used in advertising or otherwise to promote the sale, use or
51*61046927SAndroid Build Coastguard Worker * other dealings in this Software without prior written authorization of
52*61046927SAndroid Build Coastguard Worker * the copyright holder.
53*61046927SAndroid Build Coastguard Worker *
54*61046927SAndroid Build Coastguard Worker * Authors:
55*61046927SAndroid Build Coastguard Worker * Kristian Høgsberg ([email protected])
56*61046927SAndroid Build Coastguard Worker */
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker #include <X11/Xlib.h>
61*61046927SAndroid Build Coastguard Worker #include <X11/extensions/Xfixes.h>
62*61046927SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
63*61046927SAndroid Build Coastguard Worker #include <X11/xshmfence.h>
64*61046927SAndroid Build Coastguard Worker #include <xcb/xcb.h>
65*61046927SAndroid Build Coastguard Worker #include <xcb/dri3.h>
66*61046927SAndroid Build Coastguard Worker #include <xcb/present.h>
67*61046927SAndroid Build Coastguard Worker #include <GL/gl.h>
68*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
69*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
70*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
71*61046927SAndroid Build Coastguard Worker #include <unistd.h>
72*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
73*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
74*61046927SAndroid Build Coastguard Worker #include <sys/time.h>
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker #include "dri_common.h"
77*61046927SAndroid Build Coastguard Worker #include "dri3_priv.h"
78*61046927SAndroid Build Coastguard Worker #include "loader.h"
79*61046927SAndroid Build Coastguard Worker #include "loader_x11.h"
80*61046927SAndroid Build Coastguard Worker #include "loader_dri_helper.h"
81*61046927SAndroid Build Coastguard Worker #include "dri2.h"
82*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
83*61046927SAndroid Build Coastguard Worker #include "dri_util.h"
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker static struct dri3_drawable *
loader_drawable_to_dri3_drawable(struct loader_dri3_drawable * draw)86*61046927SAndroid Build Coastguard Worker loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) {
87*61046927SAndroid Build Coastguard Worker size_t offset = offsetof(struct dri3_drawable, loader_drawable);
88*61046927SAndroid Build Coastguard Worker if (!draw)
89*61046927SAndroid Build Coastguard Worker return NULL;
90*61046927SAndroid Build Coastguard Worker return (struct dri3_drawable *)(((void*) draw) - offset);
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker static void
glx_dri3_set_drawable_size(struct loader_dri3_drawable * draw,int width,int height)94*61046927SAndroid Build Coastguard Worker glx_dri3_set_drawable_size(struct loader_dri3_drawable *draw,
95*61046927SAndroid Build Coastguard Worker int width, int height)
96*61046927SAndroid Build Coastguard Worker {
97*61046927SAndroid Build Coastguard Worker /* Nothing to do */
98*61046927SAndroid Build Coastguard Worker }
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker static bool
glx_dri3_in_current_context(struct loader_dri3_drawable * draw)101*61046927SAndroid Build Coastguard Worker glx_dri3_in_current_context(struct loader_dri3_drawable *draw)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = loader_drawable_to_dri3_drawable(draw);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker if (!priv)
106*61046927SAndroid Build Coastguard Worker return false;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker struct glx_context *pcp = __glXGetCurrentContext();
109*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc;
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker return (pcp != &dummyContext) && pcp->psc == &psc->base;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker static __DRIcontext *
glx_dri3_get_dri_context(struct loader_dri3_drawable * draw)115*61046927SAndroid Build Coastguard Worker glx_dri3_get_dri_context(struct loader_dri3_drawable *draw)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker struct glx_context *gc = __glXGetCurrentContext();
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker return (gc != &dummyContext) ? gc->driContext : NULL;
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker static __DRIscreen *
glx_dri3_get_dri_screen(void)123*61046927SAndroid Build Coastguard Worker glx_dri3_get_dri_screen(void)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker struct glx_context *gc = __glXGetCurrentContext();
126*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc = (struct dri3_screen *) gc->psc;
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker return (gc != &dummyContext && psc) ? psc->base.frontend_screen : NULL;
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker static void
glx_dri3_flush_drawable(struct loader_dri3_drawable * draw,unsigned flags)132*61046927SAndroid Build Coastguard Worker glx_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker static const struct loader_dri3_vtable glx_dri3_vtable = {
138*61046927SAndroid Build Coastguard Worker .set_drawable_size = glx_dri3_set_drawable_size,
139*61046927SAndroid Build Coastguard Worker .in_current_context = glx_dri3_in_current_context,
140*61046927SAndroid Build Coastguard Worker .get_dri_context = glx_dri3_get_dri_context,
141*61046927SAndroid Build Coastguard Worker .get_dri_screen = glx_dri3_get_dri_screen,
142*61046927SAndroid Build Coastguard Worker .flush_drawable = glx_dri3_flush_drawable,
143*61046927SAndroid Build Coastguard Worker };
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable dri3_context_vtable;
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker static void
dri3_destroy_drawable(__GLXDRIdrawable * base)149*61046927SAndroid Build Coastguard Worker dri3_destroy_drawable(__GLXDRIdrawable *base)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker struct dri3_drawable *pdraw = (struct dri3_drawable *) base;
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker loader_dri3_drawable_fini(&pdraw->loader_drawable);
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker free(pdraw);
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker static enum loader_dri3_drawable_type
glx_to_loader_dri3_drawable_type(int type)159*61046927SAndroid Build Coastguard Worker glx_to_loader_dri3_drawable_type(int type)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker switch (type) {
162*61046927SAndroid Build Coastguard Worker case GLX_WINDOW_BIT:
163*61046927SAndroid Build Coastguard Worker return LOADER_DRI3_DRAWABLE_WINDOW;
164*61046927SAndroid Build Coastguard Worker case GLX_PIXMAP_BIT:
165*61046927SAndroid Build Coastguard Worker return LOADER_DRI3_DRAWABLE_PIXMAP;
166*61046927SAndroid Build Coastguard Worker case GLX_PBUFFER_BIT:
167*61046927SAndroid Build Coastguard Worker return LOADER_DRI3_DRAWABLE_PBUFFER;
168*61046927SAndroid Build Coastguard Worker default:
169*61046927SAndroid Build Coastguard Worker return LOADER_DRI3_DRAWABLE_UNKNOWN;
170*61046927SAndroid Build Coastguard Worker }
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker static __GLXDRIdrawable *
dri3_create_drawable(struct glx_screen * base,XID xDrawable,GLXDrawable drawable,int type,struct glx_config * config_base)174*61046927SAndroid Build Coastguard Worker dri3_create_drawable(struct glx_screen *base, XID xDrawable,
175*61046927SAndroid Build Coastguard Worker GLXDrawable drawable, int type,
176*61046927SAndroid Build Coastguard Worker struct glx_config *config_base)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker struct dri3_drawable *pdraw;
179*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc = (struct dri3_screen *) base;
180*61046927SAndroid Build Coastguard Worker __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
181*61046927SAndroid Build Coastguard Worker bool has_multibuffer = false;
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker pdraw = calloc(1, sizeof(*pdraw));
184*61046927SAndroid Build Coastguard Worker if (!pdraw)
185*61046927SAndroid Build Coastguard Worker return NULL;
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker pdraw->base.destroyDrawable = dri3_destroy_drawable;
188*61046927SAndroid Build Coastguard Worker pdraw->base.xDrawable = xDrawable;
189*61046927SAndroid Build Coastguard Worker pdraw->base.drawable = drawable;
190*61046927SAndroid Build Coastguard Worker pdraw->base.psc = &psc->base;
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker #ifdef HAVE_X11_DRM
193*61046927SAndroid Build Coastguard Worker has_multibuffer = base->display->has_multibuffer;
194*61046927SAndroid Build Coastguard Worker #endif
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker (void) __glXInitialize(psc->base.dpy);
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
199*61046927SAndroid Build Coastguard Worker xDrawable,
200*61046927SAndroid Build Coastguard Worker glx_to_loader_dri3_drawable_type(type),
201*61046927SAndroid Build Coastguard Worker psc->base.frontend_screen, psc->driScreenDisplayGPU,
202*61046927SAndroid Build Coastguard Worker has_multibuffer,
203*61046927SAndroid Build Coastguard Worker psc->prefer_back_buffer_reuse,
204*61046927SAndroid Build Coastguard Worker config->driConfig,
205*61046927SAndroid Build Coastguard Worker &glx_dri3_vtable,
206*61046927SAndroid Build Coastguard Worker &pdraw->loader_drawable)) {
207*61046927SAndroid Build Coastguard Worker free(pdraw);
208*61046927SAndroid Build Coastguard Worker return NULL;
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker pdraw->base.dri_drawable = pdraw->loader_drawable.dri_drawable;
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker return &pdraw->base;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker /** dri3_wait_for_msc
217*61046927SAndroid Build Coastguard Worker *
218*61046927SAndroid Build Coastguard Worker * Get the X server to send an event when the target msc/divisor/remainder is
219*61046927SAndroid Build Coastguard Worker * reached.
220*61046927SAndroid Build Coastguard Worker */
221*61046927SAndroid Build Coastguard Worker static int
dri3_wait_for_msc(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,int64_t * ust,int64_t * msc,int64_t * sbc)222*61046927SAndroid Build Coastguard Worker dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
223*61046927SAndroid Build Coastguard Worker int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
224*61046927SAndroid Build Coastguard Worker {
225*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker loader_dri3_wait_for_msc(&priv->loader_drawable, target_msc, divisor,
228*61046927SAndroid Build Coastguard Worker remainder, ust, msc, sbc);
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker return 1;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker /** dri3_drawable_get_msc
234*61046927SAndroid Build Coastguard Worker *
235*61046927SAndroid Build Coastguard Worker * Return the current UST/MSC/SBC triplet by asking the server
236*61046927SAndroid Build Coastguard Worker * for an event
237*61046927SAndroid Build Coastguard Worker */
238*61046927SAndroid Build Coastguard Worker static int
dri3_drawable_get_msc(struct glx_screen * psc,__GLXDRIdrawable * pdraw,int64_t * ust,int64_t * msc,int64_t * sbc)239*61046927SAndroid Build Coastguard Worker dri3_drawable_get_msc(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
240*61046927SAndroid Build Coastguard Worker int64_t *ust, int64_t *msc, int64_t *sbc)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker return dri3_wait_for_msc(pdraw, 0, 0, 0, ust, msc,sbc);
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker
245*61046927SAndroid Build Coastguard Worker /** dri3_wait_for_sbc
246*61046927SAndroid Build Coastguard Worker *
247*61046927SAndroid Build Coastguard Worker * Wait for the completed swap buffer count to reach the specified
248*61046927SAndroid Build Coastguard Worker * target. Presumably the application knows that this will be reached with
249*61046927SAndroid Build Coastguard Worker * outstanding complete events, or we're going to be here awhile.
250*61046927SAndroid Build Coastguard Worker */
251*61046927SAndroid Build Coastguard Worker static int
dri3_wait_for_sbc(__GLXDRIdrawable * pdraw,int64_t target_sbc,int64_t * ust,int64_t * msc,int64_t * sbc)252*61046927SAndroid Build Coastguard Worker dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
253*61046927SAndroid Build Coastguard Worker int64_t *msc, int64_t *sbc)
254*61046927SAndroid Build Coastguard Worker {
255*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker return loader_dri3_wait_for_sbc(&priv->loader_drawable, target_sbc,
258*61046927SAndroid Build Coastguard Worker ust, msc, sbc);
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker static void
dri3_copy_sub_buffer(__GLXDRIdrawable * pdraw,int x,int y,int width,int height,Bool flush)262*61046927SAndroid Build Coastguard Worker dri3_copy_sub_buffer(__GLXDRIdrawable *pdraw, int x, int y,
263*61046927SAndroid Build Coastguard Worker int width, int height,
264*61046927SAndroid Build Coastguard Worker Bool flush)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker loader_dri3_copy_sub_buffer(&priv->loader_drawable, x, y,
269*61046927SAndroid Build Coastguard Worker width, height, flush);
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker static void
dri3_wait_x(struct glx_context * gc)273*61046927SAndroid Build Coastguard Worker dri3_wait_x(struct glx_context *gc)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *)
276*61046927SAndroid Build Coastguard Worker GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker if (priv)
279*61046927SAndroid Build Coastguard Worker loader_dri3_wait_x(&priv->loader_drawable);
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker static void
dri3_wait_gl(struct glx_context * gc)283*61046927SAndroid Build Coastguard Worker dri3_wait_gl(struct glx_context *gc)
284*61046927SAndroid Build Coastguard Worker {
285*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *)
286*61046927SAndroid Build Coastguard Worker GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker if (priv)
289*61046927SAndroid Build Coastguard Worker loader_dri3_wait_gl(&priv->loader_drawable);
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker /**
293*61046927SAndroid Build Coastguard Worker * Called by the driver when it needs to update the real front buffer with the
294*61046927SAndroid Build Coastguard Worker * contents of its fake front buffer.
295*61046927SAndroid Build Coastguard Worker */
296*61046927SAndroid Build Coastguard Worker static void
dri3_flush_front_buffer(__DRIdrawable * driDrawable,void * loaderPrivate)297*61046927SAndroid Build Coastguard Worker dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
298*61046927SAndroid Build Coastguard Worker {
299*61046927SAndroid Build Coastguard Worker struct loader_dri3_drawable *draw = loaderPrivate;
300*61046927SAndroid Build Coastguard Worker struct dri3_drawable *pdraw = loader_drawable_to_dri3_drawable(draw);
301*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc;
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker if (!pdraw)
304*61046927SAndroid Build Coastguard Worker return;
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker if (!pdraw->base.psc)
307*61046927SAndroid Build Coastguard Worker return;
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker psc = (struct dri3_screen *) pdraw->base.psc;
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker (void) __glXInitialize(psc->base.dpy);
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker loader_dri3_flush(draw, __DRI2_FLUSH_DRAWABLE, __DRI2_THROTTLE_FLUSHFRONT);
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker dri_invalidate_drawable(driDrawable);
316*61046927SAndroid Build Coastguard Worker loader_dri3_wait_gl(draw);
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker /**
320*61046927SAndroid Build Coastguard Worker * Make sure all pending swapbuffers have been submitted to hardware
321*61046927SAndroid Build Coastguard Worker *
322*61046927SAndroid Build Coastguard Worker * \param driDrawable[in] Pointer to the dri drawable whose swaps we are
323*61046927SAndroid Build Coastguard Worker * flushing.
324*61046927SAndroid Build Coastguard Worker * \param loaderPrivate[in] Pointer to the corresponding struct
325*61046927SAndroid Build Coastguard Worker * loader_dri_drawable.
326*61046927SAndroid Build Coastguard Worker */
327*61046927SAndroid Build Coastguard Worker static void
dri3_flush_swap_buffers(__DRIdrawable * driDrawable,void * loaderPrivate)328*61046927SAndroid Build Coastguard Worker dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker struct loader_dri3_drawable *draw = loaderPrivate;
331*61046927SAndroid Build Coastguard Worker struct dri3_drawable *pdraw = loader_drawable_to_dri3_drawable(draw);
332*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc;
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker if (!pdraw)
335*61046927SAndroid Build Coastguard Worker return;
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker if (!pdraw->base.psc)
338*61046927SAndroid Build Coastguard Worker return;
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker psc = (struct dri3_screen *) pdraw->base.psc;
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker (void) __glXInitialize(psc->base.dpy);
343*61046927SAndroid Build Coastguard Worker loader_dri3_swapbuffer_barrier(draw);
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker static void
dri_set_background_context(void * loaderPrivate)347*61046927SAndroid Build Coastguard Worker dri_set_background_context(void *loaderPrivate)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker __glXSetCurrentContext(loaderPrivate);
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker static GLboolean
dri_is_thread_safe(void * loaderPrivate)353*61046927SAndroid Build Coastguard Worker dri_is_thread_safe(void *loaderPrivate)
354*61046927SAndroid Build Coastguard Worker {
355*61046927SAndroid Build Coastguard Worker /* Unlike DRI2, DRI3 doesn't call GetBuffers/GetBuffersWithFormat
356*61046927SAndroid Build Coastguard Worker * during draw so we're safe here.
357*61046927SAndroid Build Coastguard Worker */
358*61046927SAndroid Build Coastguard Worker return true;
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker /* The image loader extension record for DRI3
362*61046927SAndroid Build Coastguard Worker */
363*61046927SAndroid Build Coastguard Worker static const __DRIimageLoaderExtension imageLoaderExtension = {
364*61046927SAndroid Build Coastguard Worker .base = { __DRI_IMAGE_LOADER, 3 },
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker .getBuffers = loader_dri3_get_buffers,
367*61046927SAndroid Build Coastguard Worker .flushFrontBuffer = dri3_flush_front_buffer,
368*61046927SAndroid Build Coastguard Worker .flushSwapBuffers = dri3_flush_swap_buffers,
369*61046927SAndroid Build Coastguard Worker };
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker const __DRIuseInvalidateExtension dri3UseInvalidate = {
372*61046927SAndroid Build Coastguard Worker .base = { __DRI_USE_INVALIDATE, 1 }
373*61046927SAndroid Build Coastguard Worker };
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker static const __DRIbackgroundCallableExtension dri3BackgroundCallable = {
376*61046927SAndroid Build Coastguard Worker .base = { __DRI_BACKGROUND_CALLABLE, 2 },
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker .setBackgroundContext = dri_set_background_context,
379*61046927SAndroid Build Coastguard Worker .isThreadSafe = dri_is_thread_safe,
380*61046927SAndroid Build Coastguard Worker };
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker static const __DRIextension *loader_extensions[] = {
383*61046927SAndroid Build Coastguard Worker &imageLoaderExtension.base,
384*61046927SAndroid Build Coastguard Worker &dri3UseInvalidate.base,
385*61046927SAndroid Build Coastguard Worker &dri3BackgroundCallable.base,
386*61046927SAndroid Build Coastguard Worker NULL
387*61046927SAndroid Build Coastguard Worker };
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker /** dri3_swap_buffers
390*61046927SAndroid Build Coastguard Worker *
391*61046927SAndroid Build Coastguard Worker * Make the current back buffer visible using the present extension
392*61046927SAndroid Build Coastguard Worker */
393*61046927SAndroid Build Coastguard Worker static int64_t
dri3_swap_buffers(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,Bool flush)394*61046927SAndroid Build Coastguard Worker dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
395*61046927SAndroid Build Coastguard Worker int64_t remainder, Bool flush)
396*61046927SAndroid Build Coastguard Worker {
397*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
398*61046927SAndroid Build Coastguard Worker unsigned flags = __DRI2_FLUSH_DRAWABLE;
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker if (flush)
401*61046927SAndroid Build Coastguard Worker flags |= __DRI2_FLUSH_CONTEXT;
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker return loader_dri3_swap_buffers_msc(&priv->loader_drawable,
404*61046927SAndroid Build Coastguard Worker target_msc, divisor, remainder,
405*61046927SAndroid Build Coastguard Worker flags, NULL, 0, false);
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker int
409*61046927SAndroid Build Coastguard Worker dri3_get_buffer_age(__GLXDRIdrawable *pdraw);
410*61046927SAndroid Build Coastguard Worker int
dri3_get_buffer_age(__GLXDRIdrawable * pdraw)411*61046927SAndroid Build Coastguard Worker dri3_get_buffer_age(__GLXDRIdrawable *pdraw)
412*61046927SAndroid Build Coastguard Worker {
413*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *)pdraw;
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker return loader_dri3_query_buffer_age(&priv->loader_drawable);
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker /** dri3_destroy_screen
419*61046927SAndroid Build Coastguard Worker */
420*61046927SAndroid Build Coastguard Worker static void
dri3_deinit_screen(struct glx_screen * base)421*61046927SAndroid Build Coastguard Worker dri3_deinit_screen(struct glx_screen *base)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc = (struct dri3_screen *) base;
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker /* Free the direct rendering per screen data */
426*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu != psc->fd_display_gpu && psc->driScreenDisplayGPU) {
427*61046927SAndroid Build Coastguard Worker loader_dri3_close_screen(psc->driScreenDisplayGPU);
428*61046927SAndroid Build Coastguard Worker driDestroyScreen(psc->driScreenDisplayGPU);
429*61046927SAndroid Build Coastguard Worker }
430*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu != psc->fd_display_gpu)
431*61046927SAndroid Build Coastguard Worker close(psc->fd_display_gpu);
432*61046927SAndroid Build Coastguard Worker loader_dri3_close_screen(psc->base.frontend_screen);
433*61046927SAndroid Build Coastguard Worker close(psc->fd_render_gpu);
434*61046927SAndroid Build Coastguard Worker }
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker /** dri3_set_swap_interval
437*61046927SAndroid Build Coastguard Worker *
438*61046927SAndroid Build Coastguard Worker * Record the application swap interval specification,
439*61046927SAndroid Build Coastguard Worker */
440*61046927SAndroid Build Coastguard Worker static int
dri3_set_swap_interval(__GLXDRIdrawable * pdraw,int interval)441*61046927SAndroid Build Coastguard Worker dri3_set_swap_interval(__GLXDRIdrawable *pdraw, int interval)
442*61046927SAndroid Build Coastguard Worker {
443*61046927SAndroid Build Coastguard Worker assert(pdraw != NULL);
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
446*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc = (struct dri3_screen *) priv->base.psc;
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker if (!dri_valid_swap_interval(psc->base.frontend_screen, interval))
449*61046927SAndroid Build Coastguard Worker return GLX_BAD_VALUE;
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker loader_dri3_set_swap_interval(&priv->loader_drawable, interval);
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker return 0;
454*61046927SAndroid Build Coastguard Worker }
455*61046927SAndroid Build Coastguard Worker
456*61046927SAndroid Build Coastguard Worker /** dri3_get_swap_interval
457*61046927SAndroid Build Coastguard Worker *
458*61046927SAndroid Build Coastguard Worker * Return the stored swap interval
459*61046927SAndroid Build Coastguard Worker */
460*61046927SAndroid Build Coastguard Worker static int
dri3_get_swap_interval(__GLXDRIdrawable * pdraw)461*61046927SAndroid Build Coastguard Worker dri3_get_swap_interval(__GLXDRIdrawable *pdraw)
462*61046927SAndroid Build Coastguard Worker {
463*61046927SAndroid Build Coastguard Worker assert(pdraw != NULL);
464*61046927SAndroid Build Coastguard Worker
465*61046927SAndroid Build Coastguard Worker struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker return priv->loader_drawable.swap_interval;
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker
470*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable dri3_context_vtable = {
471*61046927SAndroid Build Coastguard Worker .destroy = dri_destroy_context,
472*61046927SAndroid Build Coastguard Worker .bind = dri_bind_context,
473*61046927SAndroid Build Coastguard Worker .unbind = dri_unbind_context,
474*61046927SAndroid Build Coastguard Worker .wait_gl = dri3_wait_gl,
475*61046927SAndroid Build Coastguard Worker .wait_x = dri3_wait_x,
476*61046927SAndroid Build Coastguard Worker };
477*61046927SAndroid Build Coastguard Worker
478*61046927SAndroid Build Coastguard Worker /** dri3_create_screen
479*61046927SAndroid Build Coastguard Worker *
480*61046927SAndroid Build Coastguard Worker * Initialize DRI3 on the specified screen.
481*61046927SAndroid Build Coastguard Worker *
482*61046927SAndroid Build Coastguard Worker * Opens the DRI device, locates the appropriate DRI driver
483*61046927SAndroid Build Coastguard Worker * and loads that.
484*61046927SAndroid Build Coastguard Worker *
485*61046927SAndroid Build Coastguard Worker * Checks to see if the driver supports the necessary extensions
486*61046927SAndroid Build Coastguard Worker *
487*61046927SAndroid Build Coastguard Worker * Initializes the driver for the screen and sets up our structures
488*61046927SAndroid Build Coastguard Worker */
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker struct glx_screen *
dri3_create_screen(int screen,struct glx_display * priv,bool driver_name_is_inferred,bool * return_zink)491*61046927SAndroid Build Coastguard Worker dri3_create_screen(int screen, struct glx_display * priv, bool driver_name_is_inferred, bool *return_zink)
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker xcb_connection_t *c = XGetXCBConnection(priv->dpy);
494*61046927SAndroid Build Coastguard Worker const __DRIconfig **driver_configs;
495*61046927SAndroid Build Coastguard Worker struct dri3_screen *psc;
496*61046927SAndroid Build Coastguard Worker __GLXDRIscreen *psp;
497*61046927SAndroid Build Coastguard Worker char *driverName, *driverNameDisplayGPU;
498*61046927SAndroid Build Coastguard Worker *return_zink = false;
499*61046927SAndroid Build Coastguard Worker
500*61046927SAndroid Build Coastguard Worker psc = calloc(1, sizeof *psc);
501*61046927SAndroid Build Coastguard Worker if (psc == NULL)
502*61046927SAndroid Build Coastguard Worker return NULL;
503*61046927SAndroid Build Coastguard Worker
504*61046927SAndroid Build Coastguard Worker psc->fd_display_gpu = -1;
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker psc->fd_render_gpu = x11_dri3_open(c, RootWindow(priv->dpy, screen), None);
507*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu < 0) {
508*61046927SAndroid Build Coastguard Worker int conn_error = xcb_connection_has_error(c);
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker glx_screen_cleanup(&psc->base);
511*61046927SAndroid Build Coastguard Worker free(psc);
512*61046927SAndroid Build Coastguard Worker InfoMessageF("screen %d does not appear to be DRI3 capable\n", screen);
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker if (conn_error)
515*61046927SAndroid Build Coastguard Worker ErrorMessageF("Connection closed during DRI3 initialization failure");
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker return NULL;
518*61046927SAndroid Build Coastguard Worker }
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker loader_get_user_preferred_fd(&psc->fd_render_gpu, &psc->fd_display_gpu);
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker driverName = loader_get_driver_for_fd(psc->fd_render_gpu);
523*61046927SAndroid Build Coastguard Worker if (!driverName) {
524*61046927SAndroid Build Coastguard Worker ErrorMessageF("No driver found\n");
525*61046927SAndroid Build Coastguard Worker goto handle_error;
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker psc->base.driverName = driverName;
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker if (!strcmp(driverName, "zink") && !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false)) {
530*61046927SAndroid Build Coastguard Worker *return_zink = true;
531*61046927SAndroid Build Coastguard Worker goto handle_error;
532*61046927SAndroid Build Coastguard Worker }
533*61046927SAndroid Build Coastguard Worker
534*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu != psc->fd_display_gpu) {
535*61046927SAndroid Build Coastguard Worker driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
536*61046927SAndroid Build Coastguard Worker if (driverNameDisplayGPU) {
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker /* check if driver name is matching so that non mesa drivers
539*61046927SAndroid Build Coastguard Worker * will not crash. Also need this check since image extension
540*61046927SAndroid Build Coastguard Worker * pointer from render gpu is shared with display gpu. Image
541*61046927SAndroid Build Coastguard Worker * extension pointer is shared because it keeps things simple.
542*61046927SAndroid Build Coastguard Worker */
543*61046927SAndroid Build Coastguard Worker if (strcmp(driverName, driverNameDisplayGPU) == 0) {
544*61046927SAndroid Build Coastguard Worker psc->driScreenDisplayGPU = driCreateNewScreen3(screen, psc->fd_display_gpu,
545*61046927SAndroid Build Coastguard Worker loader_extensions,
546*61046927SAndroid Build Coastguard Worker DRI_SCREEN_DRI3,
547*61046927SAndroid Build Coastguard Worker &driver_configs, driver_name_is_inferred,
548*61046927SAndroid Build Coastguard Worker priv->has_multibuffer, psc);
549*61046927SAndroid Build Coastguard Worker }
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker free(driverNameDisplayGPU);
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker priv->driver = GLX_DRIVER_DRI3;
555*61046927SAndroid Build Coastguard Worker
556*61046927SAndroid Build Coastguard Worker if (!dri_screen_init(&psc->base, priv, screen, psc->fd_render_gpu, loader_extensions, driver_name_is_inferred)) {
557*61046927SAndroid Build Coastguard Worker ErrorMessageF("glx: failed to create dri3 screen\n");
558*61046927SAndroid Build Coastguard Worker goto handle_error;
559*61046927SAndroid Build Coastguard Worker }
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu == psc->fd_display_gpu)
562*61046927SAndroid Build Coastguard Worker psc->driScreenDisplayGPU = psc->base.frontend_screen;
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker psc->base.context_vtable = &dri3_context_vtable;
565*61046927SAndroid Build Coastguard Worker psp = &psc->base.driScreen;
566*61046927SAndroid Build Coastguard Worker psp->deinitScreen = dri3_deinit_screen;
567*61046927SAndroid Build Coastguard Worker psp->createDrawable = dri3_create_drawable;
568*61046927SAndroid Build Coastguard Worker psp->swapBuffers = dri3_swap_buffers;
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker psp->getDrawableMSC = dri3_drawable_get_msc;
571*61046927SAndroid Build Coastguard Worker psp->waitForMSC = dri3_wait_for_msc;
572*61046927SAndroid Build Coastguard Worker psp->waitForSBC = dri3_wait_for_sbc;
573*61046927SAndroid Build Coastguard Worker psp->setSwapInterval = dri3_set_swap_interval;
574*61046927SAndroid Build Coastguard Worker psp->getSwapInterval = dri3_get_swap_interval;
575*61046927SAndroid Build Coastguard Worker psp->maxSwapInterval = INT_MAX;
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker /* when on a different gpu than the server, the server pixmaps
578*61046927SAndroid Build Coastguard Worker * can have a tiling mode we can't read. Thus we can't create
579*61046927SAndroid Build Coastguard Worker * a texture from them.
580*61046927SAndroid Build Coastguard Worker */
581*61046927SAndroid Build Coastguard Worker psc->base.can_EXT_texture_from_pixmap = psc->fd_render_gpu == psc->fd_display_gpu;
582*61046927SAndroid Build Coastguard Worker psp->copySubBuffer = dri3_copy_sub_buffer;
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker InfoMessageF("Using DRI3 for screen %d\n", screen);
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker psc->prefer_back_buffer_reuse = 1;
587*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu != psc->fd_display_gpu) {
588*61046927SAndroid Build Coastguard Worker unsigned value;
589*61046927SAndroid Build Coastguard Worker if (dri_query_renderer_integer(psc->base.frontend_screen,
590*61046927SAndroid Build Coastguard Worker __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE,
591*61046927SAndroid Build Coastguard Worker &value) == 0)
592*61046927SAndroid Build Coastguard Worker psc->prefer_back_buffer_reuse = value;
593*61046927SAndroid Build Coastguard Worker }
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker return &psc->base;
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker handle_error:
599*61046927SAndroid Build Coastguard Worker if (!*return_zink)
600*61046927SAndroid Build Coastguard Worker CriticalErrorMessageF("failed to load driver: %s\n", driverName ? driverName : "(null)");
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu != psc->fd_display_gpu && psc->driScreenDisplayGPU)
603*61046927SAndroid Build Coastguard Worker driDestroyScreen(psc->driScreenDisplayGPU);
604*61046927SAndroid Build Coastguard Worker psc->driScreenDisplayGPU = NULL;
605*61046927SAndroid Build Coastguard Worker if (psc->fd_display_gpu >= 0 && psc->fd_render_gpu != psc->fd_display_gpu)
606*61046927SAndroid Build Coastguard Worker close(psc->fd_display_gpu);
607*61046927SAndroid Build Coastguard Worker if (psc->fd_render_gpu >= 0)
608*61046927SAndroid Build Coastguard Worker close(psc->fd_render_gpu);
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker glx_screen_cleanup(&psc->base);
611*61046927SAndroid Build Coastguard Worker free(psc);
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker return NULL;
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker
616*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING */
617