1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2008 George Sapountzis
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 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include <xcb/xcb.h>
27*61046927SAndroid Build Coastguard Worker #include <xcb/xproto.h>
28*61046927SAndroid Build Coastguard Worker #include <xcb/shm.h>
29*61046927SAndroid Build Coastguard Worker #include <X11/Xlib.h>
30*61046927SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
31*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
32*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
33*61046927SAndroid Build Coastguard Worker #include "dri_common.h"
34*61046927SAndroid Build Coastguard Worker #include "drisw_priv.h"
35*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
36*61046927SAndroid Build Coastguard Worker #include "dri3_priv.h"
37*61046927SAndroid Build Coastguard Worker #endif
38*61046927SAndroid Build Coastguard Worker #include <X11/extensions/shmproto.h>
39*61046927SAndroid Build Coastguard Worker #include <assert.h>
40*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
41*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan_xcb.h>
42*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
43*61046927SAndroid Build Coastguard Worker #include "kopper_interface.h"
44*61046927SAndroid Build Coastguard Worker #include "loader_dri_helper.h"
45*61046927SAndroid Build Coastguard Worker #include "dri_util.h"
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker static int xshm_error = 0;
48*61046927SAndroid Build Coastguard Worker static int xshm_opcode = -1;
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker /**
51*61046927SAndroid Build Coastguard Worker * Catches potential Xlib errors.
52*61046927SAndroid Build Coastguard Worker */
53*61046927SAndroid Build Coastguard Worker static int
handle_xerror(Display * dpy,XErrorEvent * event)54*61046927SAndroid Build Coastguard Worker handle_xerror(Display *dpy, XErrorEvent *event)
55*61046927SAndroid Build Coastguard Worker {
56*61046927SAndroid Build Coastguard Worker (void) dpy;
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker assert(xshm_opcode != -1);
59*61046927SAndroid Build Coastguard Worker if (event->request_code != xshm_opcode)
60*61046927SAndroid Build Coastguard Worker return 0;
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker xshm_error = event->error_code;
63*61046927SAndroid Build Coastguard Worker return 0;
64*61046927SAndroid Build Coastguard Worker }
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker static Bool
XCreateDrawable(struct drisw_drawable * pdp,int shmid,Display * dpy)67*61046927SAndroid Build Coastguard Worker XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker if (pdp->ximage) {
70*61046927SAndroid Build Coastguard Worker XDestroyImage(pdp->ximage);
71*61046927SAndroid Build Coastguard Worker pdp->ximage = NULL;
72*61046927SAndroid Build Coastguard Worker if ((pdp->shminfo.shmid > 0) && (shmid != pdp->shminfo.shmid))
73*61046927SAndroid Build Coastguard Worker XShmDetach(dpy, &pdp->shminfo);
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker if (!xshm_error && shmid >= 0) {
77*61046927SAndroid Build Coastguard Worker pdp->shminfo.shmid = shmid;
78*61046927SAndroid Build Coastguard Worker pdp->ximage = XShmCreateImage(dpy,
79*61046927SAndroid Build Coastguard Worker NULL,
80*61046927SAndroid Build Coastguard Worker pdp->xDepth,
81*61046927SAndroid Build Coastguard Worker ZPixmap, /* format */
82*61046927SAndroid Build Coastguard Worker NULL, /* data */
83*61046927SAndroid Build Coastguard Worker &pdp->shminfo, /* shminfo */
84*61046927SAndroid Build Coastguard Worker 0, 0); /* width, height */
85*61046927SAndroid Build Coastguard Worker if (pdp->ximage != NULL) {
86*61046927SAndroid Build Coastguard Worker int (*old_handler)(Display *, XErrorEvent *);
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker /* dispatch pending errors */
89*61046927SAndroid Build Coastguard Worker XSync(dpy, False);
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker old_handler = XSetErrorHandler(handle_xerror);
92*61046927SAndroid Build Coastguard Worker /* This may trigger the X protocol error we're ready to catch: */
93*61046927SAndroid Build Coastguard Worker XShmAttach(dpy, &pdp->shminfo);
94*61046927SAndroid Build Coastguard Worker XSync(dpy, False);
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker if (xshm_error) {
97*61046927SAndroid Build Coastguard Worker /* we are on a remote display, this error is normal, don't print it */
98*61046927SAndroid Build Coastguard Worker XDestroyImage(pdp->ximage);
99*61046927SAndroid Build Coastguard Worker pdp->ximage = NULL;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker (void) XSetErrorHandler(old_handler);
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker if (pdp->ximage == NULL) {
107*61046927SAndroid Build Coastguard Worker pdp->shminfo.shmid = -1;
108*61046927SAndroid Build Coastguard Worker pdp->ximage = XCreateImage(dpy,
109*61046927SAndroid Build Coastguard Worker NULL,
110*61046927SAndroid Build Coastguard Worker pdp->xDepth,
111*61046927SAndroid Build Coastguard Worker ZPixmap, 0, /* format, offset */
112*61046927SAndroid Build Coastguard Worker NULL, /* data */
113*61046927SAndroid Build Coastguard Worker 0, 0, /* width, height */
114*61046927SAndroid Build Coastguard Worker 32, /* bitmap_pad */
115*61046927SAndroid Build Coastguard Worker 0); /* bytes_per_line */
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker /**
119*61046927SAndroid Build Coastguard Worker * swrast does not handle 24-bit depth with 24 bpp, so let X do the
120*61046927SAndroid Build Coastguard Worker * the conversion for us.
121*61046927SAndroid Build Coastguard Worker */
122*61046927SAndroid Build Coastguard Worker if (pdp->ximage->bits_per_pixel == 24)
123*61046927SAndroid Build Coastguard Worker pdp->ximage->bits_per_pixel = 32;
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker return True;
126*61046927SAndroid Build Coastguard Worker }
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker static void
XDestroyDrawable(struct drisw_drawable * pdp,Display * dpy,XID drawable)129*61046927SAndroid Build Coastguard Worker XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable)
130*61046927SAndroid Build Coastguard Worker {
131*61046927SAndroid Build Coastguard Worker if (pdp->ximage)
132*61046927SAndroid Build Coastguard Worker XDestroyImage(pdp->ximage);
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker if (pdp->shminfo.shmid > 0)
135*61046927SAndroid Build Coastguard Worker XShmDetach(dpy, &pdp->shminfo);
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker XFreeGC(dpy, pdp->gc);
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker /**
141*61046927SAndroid Build Coastguard Worker * swrast loader functions
142*61046927SAndroid Build Coastguard Worker */
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker static void
swrastGetDrawableInfo(__DRIdrawable * draw,int * x,int * y,int * w,int * h,void * loaderPrivate)145*61046927SAndroid Build Coastguard Worker swrastGetDrawableInfo(__DRIdrawable * draw,
146*61046927SAndroid Build Coastguard Worker int *x, int *y, int *w, int *h,
147*61046927SAndroid Build Coastguard Worker void *loaderPrivate)
148*61046927SAndroid Build Coastguard Worker {
149*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = loaderPrivate;
150*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable *pdraw = &(pdp->base);
151*61046927SAndroid Build Coastguard Worker Display *dpy = pdraw->psc->dpy;
152*61046927SAndroid Build Coastguard Worker Drawable drawable;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker Window root;
155*61046927SAndroid Build Coastguard Worker unsigned uw, uh, bw, depth;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker drawable = pdraw->xDrawable;
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker XGetGeometry(dpy, drawable, &root, x, y, &uw, &uh, &bw, &depth);
160*61046927SAndroid Build Coastguard Worker *w = uw;
161*61046927SAndroid Build Coastguard Worker *h = uh;
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker /**
165*61046927SAndroid Build Coastguard Worker * Align renderbuffer pitch.
166*61046927SAndroid Build Coastguard Worker *
167*61046927SAndroid Build Coastguard Worker * This should be chosen by the driver and the loader (libGL, xserver/glx)
168*61046927SAndroid Build Coastguard Worker * should use the driver provided pitch.
169*61046927SAndroid Build Coastguard Worker *
170*61046927SAndroid Build Coastguard Worker * It seems that the xorg loader (that is the xserver loading swrast_dri for
171*61046927SAndroid Build Coastguard Worker * indirect rendering, not client-side libGL) requires that the pitch is
172*61046927SAndroid Build Coastguard Worker * exactly the image width padded to 32 bits. XXX
173*61046927SAndroid Build Coastguard Worker *
174*61046927SAndroid Build Coastguard Worker * The above restriction can probably be overcome by using ScratchPixmap and
175*61046927SAndroid Build Coastguard Worker * CopyArea in the xserver, similar to ShmPutImage, and setting the width of
176*61046927SAndroid Build Coastguard Worker * the scratch pixmap to 'pitch / cpp'.
177*61046927SAndroid Build Coastguard Worker */
178*61046927SAndroid Build Coastguard Worker static inline int
bytes_per_line(unsigned pitch_bits,unsigned mul)179*61046927SAndroid Build Coastguard Worker bytes_per_line(unsigned pitch_bits, unsigned mul)
180*61046927SAndroid Build Coastguard Worker {
181*61046927SAndroid Build Coastguard Worker unsigned mask = mul - 1;
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker return ((pitch_bits + mask) & ~mask) / 8;
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker static void
swrastXPutImage(__DRIdrawable * draw,int op,int srcx,int srcy,int x,int y,int w,int h,int stride,int shmid,char * data,void * loaderPrivate)187*61046927SAndroid Build Coastguard Worker swrastXPutImage(__DRIdrawable * draw, int op,
188*61046927SAndroid Build Coastguard Worker int srcx, int srcy, int x, int y,
189*61046927SAndroid Build Coastguard Worker int w, int h, int stride,
190*61046927SAndroid Build Coastguard Worker int shmid, char *data, void *loaderPrivate)
191*61046927SAndroid Build Coastguard Worker {
192*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = loaderPrivate;
193*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable *pdraw = &(pdp->base);
194*61046927SAndroid Build Coastguard Worker Display *dpy = pdraw->psc->dpy;
195*61046927SAndroid Build Coastguard Worker Drawable drawable;
196*61046927SAndroid Build Coastguard Worker XImage *ximage;
197*61046927SAndroid Build Coastguard Worker GC gc = pdp->gc;
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker if (!pdp->ximage || shmid != pdp->shminfo.shmid) {
200*61046927SAndroid Build Coastguard Worker if (!XCreateDrawable(pdp, shmid, dpy))
201*61046927SAndroid Build Coastguard Worker return;
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker drawable = pdraw->xDrawable;
205*61046927SAndroid Build Coastguard Worker ximage = pdp->ximage;
206*61046927SAndroid Build Coastguard Worker ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
207*61046927SAndroid Build Coastguard Worker ximage->data = data;
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker ximage->width = ximage->bytes_per_line / ((ximage->bits_per_pixel + 7)/ 8);
210*61046927SAndroid Build Coastguard Worker ximage->height = h;
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker if (pdp->shminfo.shmid >= 0) {
213*61046927SAndroid Build Coastguard Worker XShmPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h, False);
214*61046927SAndroid Build Coastguard Worker XSync(dpy, False);
215*61046927SAndroid Build Coastguard Worker } else {
216*61046927SAndroid Build Coastguard Worker XPutImage(dpy, drawable, gc, ximage, srcx, srcy, x, y, w, h);
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker ximage->data = NULL;
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker static void
swrastPutImageShm(__DRIdrawable * draw,int op,int x,int y,int w,int h,int stride,int shmid,char * shmaddr,unsigned offset,void * loaderPrivate)222*61046927SAndroid Build Coastguard Worker swrastPutImageShm(__DRIdrawable * draw, int op,
223*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h, int stride,
224*61046927SAndroid Build Coastguard Worker int shmid, char *shmaddr, unsigned offset,
225*61046927SAndroid Build Coastguard Worker void *loaderPrivate)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = loaderPrivate;
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker if (!pdp)
230*61046927SAndroid Build Coastguard Worker return;
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker pdp->shminfo.shmaddr = shmaddr;
233*61046927SAndroid Build Coastguard Worker swrastXPutImage(draw, op, 0, 0, x, y, w, h, stride, shmid,
234*61046927SAndroid Build Coastguard Worker shmaddr + offset, loaderPrivate);
235*61046927SAndroid Build Coastguard Worker }
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker static void
swrastPutImageShm2(__DRIdrawable * draw,int op,int x,int y,int w,int h,int stride,int shmid,char * shmaddr,unsigned offset,void * loaderPrivate)238*61046927SAndroid Build Coastguard Worker swrastPutImageShm2(__DRIdrawable * draw, int op,
239*61046927SAndroid Build Coastguard Worker int x, int y,
240*61046927SAndroid Build Coastguard Worker int w, int h, int stride,
241*61046927SAndroid Build Coastguard Worker int shmid, char *shmaddr, unsigned offset,
242*61046927SAndroid Build Coastguard Worker void *loaderPrivate)
243*61046927SAndroid Build Coastguard Worker {
244*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = loaderPrivate;
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker if (!pdp)
247*61046927SAndroid Build Coastguard Worker return;
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker pdp->shminfo.shmaddr = shmaddr;
250*61046927SAndroid Build Coastguard Worker swrastXPutImage(draw, op, x, 0, x, y, w, h, stride, shmid,
251*61046927SAndroid Build Coastguard Worker shmaddr + offset, loaderPrivate);
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker static void
swrastPutImage2(__DRIdrawable * draw,int op,int x,int y,int w,int h,int stride,char * data,void * loaderPrivate)255*61046927SAndroid Build Coastguard Worker swrastPutImage2(__DRIdrawable * draw, int op,
256*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h, int stride,
257*61046927SAndroid Build Coastguard Worker char *data, void *loaderPrivate)
258*61046927SAndroid Build Coastguard Worker {
259*61046927SAndroid Build Coastguard Worker if (!loaderPrivate)
260*61046927SAndroid Build Coastguard Worker return;
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker swrastXPutImage(draw, op, 0, 0, x, y, w, h, stride, -1,
263*61046927SAndroid Build Coastguard Worker data, loaderPrivate);
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker static void
swrastPutImage(__DRIdrawable * draw,int op,int x,int y,int w,int h,char * data,void * loaderPrivate)267*61046927SAndroid Build Coastguard Worker swrastPutImage(__DRIdrawable * draw, int op,
268*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h,
269*61046927SAndroid Build Coastguard Worker char *data, void *loaderPrivate)
270*61046927SAndroid Build Coastguard Worker {
271*61046927SAndroid Build Coastguard Worker if (!loaderPrivate)
272*61046927SAndroid Build Coastguard Worker return;
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker swrastXPutImage(draw, op, 0, 0, x, y, w, h, 0, -1,
275*61046927SAndroid Build Coastguard Worker data, loaderPrivate);
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker static void
swrastGetImage2(__DRIdrawable * read,int x,int y,int w,int h,int stride,char * data,void * loaderPrivate)279*61046927SAndroid Build Coastguard Worker swrastGetImage2(__DRIdrawable * read,
280*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h, int stride,
281*61046927SAndroid Build Coastguard Worker char *data, void *loaderPrivate)
282*61046927SAndroid Build Coastguard Worker {
283*61046927SAndroid Build Coastguard Worker struct drisw_drawable *prp = loaderPrivate;
284*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable *pread = &(prp->base);
285*61046927SAndroid Build Coastguard Worker Display *dpy = pread->psc->dpy;
286*61046927SAndroid Build Coastguard Worker Drawable readable;
287*61046927SAndroid Build Coastguard Worker XImage *ximage;
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker if (!prp->ximage || prp->shminfo.shmid >= 0) {
290*61046927SAndroid Build Coastguard Worker if (!XCreateDrawable(prp, -1, dpy))
291*61046927SAndroid Build Coastguard Worker return;
292*61046927SAndroid Build Coastguard Worker }
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker readable = pread->xDrawable;
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker ximage = prp->ximage;
297*61046927SAndroid Build Coastguard Worker ximage->data = data;
298*61046927SAndroid Build Coastguard Worker ximage->width = w;
299*61046927SAndroid Build Coastguard Worker ximage->height = h;
300*61046927SAndroid Build Coastguard Worker ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker ximage->data = NULL;
305*61046927SAndroid Build Coastguard Worker }
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker static void
swrastGetImage(__DRIdrawable * read,int x,int y,int w,int h,char * data,void * loaderPrivate)308*61046927SAndroid Build Coastguard Worker swrastGetImage(__DRIdrawable * read,
309*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h,
310*61046927SAndroid Build Coastguard Worker char *data, void *loaderPrivate)
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate);
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker static GLboolean
swrastGetImageShm2(__DRIdrawable * read,int x,int y,int w,int h,int shmid,void * loaderPrivate)316*61046927SAndroid Build Coastguard Worker swrastGetImageShm2(__DRIdrawable * read,
317*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h,
318*61046927SAndroid Build Coastguard Worker int shmid, void *loaderPrivate)
319*61046927SAndroid Build Coastguard Worker {
320*61046927SAndroid Build Coastguard Worker struct drisw_drawable *prp = loaderPrivate;
321*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable *pread = &(prp->base);
322*61046927SAndroid Build Coastguard Worker Display *dpy = pread->psc->dpy;
323*61046927SAndroid Build Coastguard Worker Drawable readable;
324*61046927SAndroid Build Coastguard Worker XImage *ximage;
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker if (!prp->ximage || shmid != prp->shminfo.shmid) {
327*61046927SAndroid Build Coastguard Worker if (!XCreateDrawable(prp, shmid, dpy))
328*61046927SAndroid Build Coastguard Worker return GL_FALSE;
329*61046927SAndroid Build Coastguard Worker }
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker if (prp->shminfo.shmid == -1)
332*61046927SAndroid Build Coastguard Worker return GL_FALSE;
333*61046927SAndroid Build Coastguard Worker readable = pread->xDrawable;
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker ximage = prp->ximage;
336*61046927SAndroid Build Coastguard Worker ximage->data = prp->shminfo.shmaddr; /* no offset */
337*61046927SAndroid Build Coastguard Worker ximage->width = w;
338*61046927SAndroid Build Coastguard Worker ximage->height = h;
339*61046927SAndroid Build Coastguard Worker ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker XShmGetImage(dpy, readable, ximage, x, y, ~0L);
342*61046927SAndroid Build Coastguard Worker return GL_TRUE;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker static void
swrastGetImageShm(__DRIdrawable * read,int x,int y,int w,int h,int shmid,void * loaderPrivate)346*61046927SAndroid Build Coastguard Worker swrastGetImageShm(__DRIdrawable * read,
347*61046927SAndroid Build Coastguard Worker int x, int y, int w, int h,
348*61046927SAndroid Build Coastguard Worker int shmid, void *loaderPrivate)
349*61046927SAndroid Build Coastguard Worker {
350*61046927SAndroid Build Coastguard Worker swrastGetImageShm2(read, x, y, w, h, shmid, loaderPrivate);
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker static const __DRIswrastLoaderExtension swrastLoaderExtension_shm = {
354*61046927SAndroid Build Coastguard Worker .base = {__DRI_SWRAST_LOADER, 6 },
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker .getDrawableInfo = swrastGetDrawableInfo,
357*61046927SAndroid Build Coastguard Worker .putImage = swrastPutImage,
358*61046927SAndroid Build Coastguard Worker .getImage = swrastGetImage,
359*61046927SAndroid Build Coastguard Worker .putImage2 = swrastPutImage2,
360*61046927SAndroid Build Coastguard Worker .getImage2 = swrastGetImage2,
361*61046927SAndroid Build Coastguard Worker .putImageShm = swrastPutImageShm,
362*61046927SAndroid Build Coastguard Worker .getImageShm = swrastGetImageShm,
363*61046927SAndroid Build Coastguard Worker .putImageShm2 = swrastPutImageShm2,
364*61046927SAndroid Build Coastguard Worker .getImageShm2 = swrastGetImageShm2,
365*61046927SAndroid Build Coastguard Worker };
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker static const __DRIswrastLoaderExtension swrastLoaderExtension = {
368*61046927SAndroid Build Coastguard Worker .base = {__DRI_SWRAST_LOADER, 3 },
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker .getDrawableInfo = swrastGetDrawableInfo,
371*61046927SAndroid Build Coastguard Worker .putImage = swrastPutImage,
372*61046927SAndroid Build Coastguard Worker .getImage = swrastGetImage,
373*61046927SAndroid Build Coastguard Worker .putImage2 = swrastPutImage2,
374*61046927SAndroid Build Coastguard Worker .getImage2 = swrastGetImage2,
375*61046927SAndroid Build Coastguard Worker };
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct kopper_vk_surface_create_storage) >= sizeof(VkXcbSurfaceCreateInfoKHR), "");
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker static void
kopperSetSurfaceCreateInfo(void * _draw,struct kopper_loader_info * out)380*61046927SAndroid Build Coastguard Worker kopperSetSurfaceCreateInfo(void *_draw, struct kopper_loader_info *out)
381*61046927SAndroid Build Coastguard Worker {
382*61046927SAndroid Build Coastguard Worker __GLXDRIdrawable *draw = _draw;
383*61046927SAndroid Build Coastguard Worker VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&out->bos;
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker xcb->sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
386*61046927SAndroid Build Coastguard Worker xcb->pNext = NULL;
387*61046927SAndroid Build Coastguard Worker xcb->flags = 0;
388*61046927SAndroid Build Coastguard Worker xcb->connection = XGetXCBConnection(draw->psc->dpy);
389*61046927SAndroid Build Coastguard Worker xcb->window = draw->xDrawable;
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker static const __DRIkopperLoaderExtension kopperLoaderExtension = {
393*61046927SAndroid Build Coastguard Worker .base = { __DRI_KOPPER_LOADER, 1 },
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker .SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo,
396*61046927SAndroid Build Coastguard Worker };
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker static const __DRIextension *loader_extensions_shm[] = {
399*61046927SAndroid Build Coastguard Worker &swrastLoaderExtension_shm.base,
400*61046927SAndroid Build Coastguard Worker &kopperLoaderExtension.base,
401*61046927SAndroid Build Coastguard Worker NULL
402*61046927SAndroid Build Coastguard Worker };
403*61046927SAndroid Build Coastguard Worker
404*61046927SAndroid Build Coastguard Worker static const __DRIextension *loader_extensions_noshm[] = {
405*61046927SAndroid Build Coastguard Worker &swrastLoaderExtension.base,
406*61046927SAndroid Build Coastguard Worker &kopperLoaderExtension.base,
407*61046927SAndroid Build Coastguard Worker NULL
408*61046927SAndroid Build Coastguard Worker };
409*61046927SAndroid Build Coastguard Worker
410*61046927SAndroid Build Coastguard Worker static const __DRIextension *kopper_extensions_noshm[] = {
411*61046927SAndroid Build Coastguard Worker &swrastLoaderExtension.base,
412*61046927SAndroid Build Coastguard Worker &kopperLoaderExtension.base,
413*61046927SAndroid Build Coastguard Worker &dri2UseInvalidate.base,
414*61046927SAndroid Build Coastguard Worker &driBackgroundCallable.base,
415*61046927SAndroid Build Coastguard Worker NULL
416*61046927SAndroid Build Coastguard Worker };
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker /**
419*61046927SAndroid Build Coastguard Worker * GLXDRI functions
420*61046927SAndroid Build Coastguard Worker */
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker static void
drisw_wait_gl(struct glx_context * context)424*61046927SAndroid Build Coastguard Worker drisw_wait_gl(struct glx_context *context)
425*61046927SAndroid Build Coastguard Worker {
426*61046927SAndroid Build Coastguard Worker glFinish();
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker static void
drisw_wait_x(struct glx_context * context)430*61046927SAndroid Build Coastguard Worker drisw_wait_x(struct glx_context *context)
431*61046927SAndroid Build Coastguard Worker {
432*61046927SAndroid Build Coastguard Worker XSync(context->currentDpy, False);
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker int
436*61046927SAndroid Build Coastguard Worker kopper_get_buffer_age(__GLXDRIdrawable *pdraw);
437*61046927SAndroid Build Coastguard Worker int
kopper_get_buffer_age(__GLXDRIdrawable * pdraw)438*61046927SAndroid Build Coastguard Worker kopper_get_buffer_age(__GLXDRIdrawable *pdraw)
439*61046927SAndroid Build Coastguard Worker {
440*61046927SAndroid Build Coastguard Worker return kopperQueryBufferAge(pdraw->dri_drawable);
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker static const struct glx_context_vtable drisw_context_vtable = {
444*61046927SAndroid Build Coastguard Worker .destroy = dri_destroy_context,
445*61046927SAndroid Build Coastguard Worker .bind = dri_bind_context,
446*61046927SAndroid Build Coastguard Worker .unbind = dri_unbind_context,
447*61046927SAndroid Build Coastguard Worker .wait_gl = drisw_wait_gl,
448*61046927SAndroid Build Coastguard Worker .wait_x = drisw_wait_x,
449*61046927SAndroid Build Coastguard Worker };
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker static void
driswDestroyDrawable(__GLXDRIdrawable * pdraw)452*61046927SAndroid Build Coastguard Worker driswDestroyDrawable(__GLXDRIdrawable * pdraw)
453*61046927SAndroid Build Coastguard Worker {
454*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
455*61046927SAndroid Build Coastguard Worker
456*61046927SAndroid Build Coastguard Worker driDestroyDrawable(pdp->base.dri_drawable);
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
459*61046927SAndroid Build Coastguard Worker free(pdp);
460*61046927SAndroid Build Coastguard Worker }
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker static __GLXDRIdrawable *
driswCreateDrawable(struct glx_screen * base,XID xDrawable,GLXDrawable drawable,int type,struct glx_config * modes)463*61046927SAndroid Build Coastguard Worker driswCreateDrawable(struct glx_screen *base, XID xDrawable,
464*61046927SAndroid Build Coastguard Worker GLXDrawable drawable, int type,
465*61046927SAndroid Build Coastguard Worker struct glx_config *modes)
466*61046927SAndroid Build Coastguard Worker {
467*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp;
468*61046927SAndroid Build Coastguard Worker __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
469*61046927SAndroid Build Coastguard Worker unsigned depth;
470*61046927SAndroid Build Coastguard Worker struct drisw_screen *psc = (struct drisw_screen *) base;
471*61046927SAndroid Build Coastguard Worker Display *dpy = psc->base.dpy;
472*61046927SAndroid Build Coastguard Worker
473*61046927SAndroid Build Coastguard Worker xcb_connection_t *conn = XGetXCBConnection(dpy);
474*61046927SAndroid Build Coastguard Worker xcb_generic_error_t *error;
475*61046927SAndroid Build Coastguard Worker xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, xDrawable);
476*61046927SAndroid Build Coastguard Worker xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(conn, cookie, &error);
477*61046927SAndroid Build Coastguard Worker if (reply)
478*61046927SAndroid Build Coastguard Worker depth = reply->depth;
479*61046927SAndroid Build Coastguard Worker free(reply);
480*61046927SAndroid Build Coastguard Worker if (!reply || error)
481*61046927SAndroid Build Coastguard Worker return NULL;
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker pdp = calloc(1, sizeof(*pdp));
484*61046927SAndroid Build Coastguard Worker if (!pdp)
485*61046927SAndroid Build Coastguard Worker return NULL;
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker pdp->base.xDrawable = xDrawable;
488*61046927SAndroid Build Coastguard Worker pdp->base.drawable = drawable;
489*61046927SAndroid Build Coastguard Worker pdp->base.psc = &psc->base;
490*61046927SAndroid Build Coastguard Worker pdp->config = modes;
491*61046927SAndroid Build Coastguard Worker pdp->gc = XCreateGC(dpy, xDrawable, 0, NULL);
492*61046927SAndroid Build Coastguard Worker pdp->xDepth = 0;
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker /* Use the visual depth, if this fbconfig corresponds to a visual */
495*61046927SAndroid Build Coastguard Worker if (pdp->config->visualID != 0) {
496*61046927SAndroid Build Coastguard Worker int matches = 0;
497*61046927SAndroid Build Coastguard Worker XVisualInfo *visinfo, template;
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker template.visualid = pdp->config->visualID;
500*61046927SAndroid Build Coastguard Worker template.screen = pdp->config->screen;
501*61046927SAndroid Build Coastguard Worker visinfo = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask,
502*61046927SAndroid Build Coastguard Worker &template, &matches);
503*61046927SAndroid Build Coastguard Worker
504*61046927SAndroid Build Coastguard Worker if (visinfo && matches) {
505*61046927SAndroid Build Coastguard Worker pdp->xDepth = visinfo->depth;
506*61046927SAndroid Build Coastguard Worker XFree(visinfo);
507*61046927SAndroid Build Coastguard Worker }
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker /* Otherwise, or if XGetVisualInfo failed, ask the server */
511*61046927SAndroid Build Coastguard Worker if (pdp->xDepth == 0) {
512*61046927SAndroid Build Coastguard Worker pdp->xDepth = depth;
513*61046927SAndroid Build Coastguard Worker }
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker pdp->swapInterval = dri_get_initial_swap_interval(psc->base.frontend_screen);
516*61046927SAndroid Build Coastguard Worker /* Create a new drawable */
517*61046927SAndroid Build Coastguard Worker pdp->base.dri_drawable = dri_create_drawable(psc->base.frontend_screen, config->driConfig, !(type & GLX_WINDOW_BIT), pdp);
518*61046927SAndroid Build Coastguard Worker if (psc->kopper)
519*61046927SAndroid Build Coastguard Worker kopperSetSwapInterval(pdp->base.dri_drawable, pdp->swapInterval);
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker if (!pdp->base.dri_drawable) {
522*61046927SAndroid Build Coastguard Worker XDestroyDrawable(pdp, psc->base.dpy, xDrawable);
523*61046927SAndroid Build Coastguard Worker free(pdp);
524*61046927SAndroid Build Coastguard Worker return NULL;
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker pdp->base.destroyDrawable = driswDestroyDrawable;
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker return &pdp->base;
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker static int64_t
driswSwapBuffers(__GLXDRIdrawable * pdraw,int64_t target_msc,int64_t divisor,int64_t remainder,Bool flush)533*61046927SAndroid Build Coastguard Worker driswSwapBuffers(__GLXDRIdrawable * pdraw,
534*61046927SAndroid Build Coastguard Worker int64_t target_msc, int64_t divisor, int64_t remainder,
535*61046927SAndroid Build Coastguard Worker Bool flush)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker struct drisw_screen *psc = (struct drisw_screen *) pdraw->psc;
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker (void) target_msc;
540*61046927SAndroid Build Coastguard Worker (void) divisor;
541*61046927SAndroid Build Coastguard Worker (void) remainder;
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker if (flush) {
544*61046927SAndroid Build Coastguard Worker glFlush();
545*61046927SAndroid Build Coastguard Worker }
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker if (psc->kopper)
548*61046927SAndroid Build Coastguard Worker return kopperSwapBuffers(pdraw->dri_drawable, 0);
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker driSwapBuffers(pdraw->dri_drawable);
551*61046927SAndroid Build Coastguard Worker
552*61046927SAndroid Build Coastguard Worker return 0;
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker static void
drisw_copy_sub_buffer(__GLXDRIdrawable * pdraw,int x,int y,int width,int height,Bool flush)556*61046927SAndroid Build Coastguard Worker drisw_copy_sub_buffer(__GLXDRIdrawable * pdraw,
557*61046927SAndroid Build Coastguard Worker int x, int y, int width, int height, Bool flush)
558*61046927SAndroid Build Coastguard Worker {
559*61046927SAndroid Build Coastguard Worker if (flush) {
560*61046927SAndroid Build Coastguard Worker glFlush();
561*61046927SAndroid Build Coastguard Worker }
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker driswCopySubBuffer(pdraw->dri_drawable, x, y, width, height);
564*61046927SAndroid Build Coastguard Worker }
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker static int
check_xshm(Display * dpy)567*61046927SAndroid Build Coastguard Worker check_xshm(Display *dpy)
568*61046927SAndroid Build Coastguard Worker {
569*61046927SAndroid Build Coastguard Worker xcb_connection_t *c = XGetXCBConnection(dpy);
570*61046927SAndroid Build Coastguard Worker xcb_void_cookie_t cookie;
571*61046927SAndroid Build Coastguard Worker xcb_generic_error_t *error;
572*61046927SAndroid Build Coastguard Worker int ret = True;
573*61046927SAndroid Build Coastguard Worker xcb_query_extension_cookie_t shm_cookie;
574*61046927SAndroid Build Coastguard Worker xcb_query_extension_reply_t *shm_reply;
575*61046927SAndroid Build Coastguard Worker bool has_mit_shm;
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker shm_cookie = xcb_query_extension(c, 7, "MIT-SHM");
578*61046927SAndroid Build Coastguard Worker shm_reply = xcb_query_extension_reply(c, shm_cookie, NULL);
579*61046927SAndroid Build Coastguard Worker xshm_opcode = shm_reply->major_opcode;
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker has_mit_shm = shm_reply->present;
582*61046927SAndroid Build Coastguard Worker free(shm_reply);
583*61046927SAndroid Build Coastguard Worker if (!has_mit_shm)
584*61046927SAndroid Build Coastguard Worker return False;
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker cookie = xcb_shm_detach_checked(c, 0);
587*61046927SAndroid Build Coastguard Worker if ((error = xcb_request_check(c, cookie))) {
588*61046927SAndroid Build Coastguard Worker /* BadRequest means we're a remote client. If we were local we'd
589*61046927SAndroid Build Coastguard Worker * expect BadValue since 'info' has an invalid segment name.
590*61046927SAndroid Build Coastguard Worker */
591*61046927SAndroid Build Coastguard Worker if (error->error_code == BadRequest)
592*61046927SAndroid Build Coastguard Worker ret = False;
593*61046927SAndroid Build Coastguard Worker free(error);
594*61046927SAndroid Build Coastguard Worker }
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker return ret;
597*61046927SAndroid Build Coastguard Worker }
598*61046927SAndroid Build Coastguard Worker
599*61046927SAndroid Build Coastguard Worker static int
driswKopperSetSwapInterval(__GLXDRIdrawable * pdraw,int interval)600*61046927SAndroid Build Coastguard Worker driswKopperSetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
601*61046927SAndroid Build Coastguard Worker {
602*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
603*61046927SAndroid Build Coastguard Worker struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
604*61046927SAndroid Build Coastguard Worker
605*61046927SAndroid Build Coastguard Worker if (!dri_valid_swap_interval(psc->base.frontend_screen, interval))
606*61046927SAndroid Build Coastguard Worker return GLX_BAD_VALUE;
607*61046927SAndroid Build Coastguard Worker
608*61046927SAndroid Build Coastguard Worker kopperSetSwapInterval(pdp->base.dri_drawable, interval);
609*61046927SAndroid Build Coastguard Worker pdp->swapInterval = interval;
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker return 0;
612*61046927SAndroid Build Coastguard Worker }
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker static int
kopperGetSwapInterval(__GLXDRIdrawable * pdraw)615*61046927SAndroid Build Coastguard Worker kopperGetSwapInterval(__GLXDRIdrawable *pdraw)
616*61046927SAndroid Build Coastguard Worker {
617*61046927SAndroid Build Coastguard Worker struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
618*61046927SAndroid Build Coastguard Worker
619*61046927SAndroid Build Coastguard Worker return pdp->swapInterval;
620*61046927SAndroid Build Coastguard Worker }
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker struct glx_screen *
driswCreateScreen(int screen,struct glx_display * priv,enum glx_driver glx_driver,bool driver_name_is_inferred)623*61046927SAndroid Build Coastguard Worker driswCreateScreen(int screen, struct glx_display *priv, enum glx_driver glx_driver, bool driver_name_is_inferred)
624*61046927SAndroid Build Coastguard Worker {
625*61046927SAndroid Build Coastguard Worker __GLXDRIscreen *psp;
626*61046927SAndroid Build Coastguard Worker struct drisw_screen *psc;
627*61046927SAndroid Build Coastguard Worker const __DRIextension **loader_extensions_local;
628*61046927SAndroid Build Coastguard Worker bool kopper_disable = debug_get_bool_option("LIBGL_KOPPER_DISABLE", false);
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker /* this is only relevant if zink bits are set */
631*61046927SAndroid Build Coastguard Worker glx_driver &= (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES);
632*61046927SAndroid Build Coastguard Worker const char *driver = glx_driver && !kopper_disable ? "zink" : "swrast";
633*61046927SAndroid Build Coastguard Worker
634*61046927SAndroid Build Coastguard Worker psc = calloc(1, sizeof *psc);
635*61046927SAndroid Build Coastguard Worker if (psc == NULL)
636*61046927SAndroid Build Coastguard Worker return NULL;
637*61046927SAndroid Build Coastguard Worker psc->kopper = !strcmp(driver, "zink");
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker if (!glx_screen_init(&psc->base, screen, priv)) {
640*61046927SAndroid Build Coastguard Worker free(psc);
641*61046927SAndroid Build Coastguard Worker return NULL;
642*61046927SAndroid Build Coastguard Worker }
643*61046927SAndroid Build Coastguard Worker
644*61046927SAndroid Build Coastguard Worker psc->base.driverName = strdup(driver);
645*61046927SAndroid Build Coastguard Worker
646*61046927SAndroid Build Coastguard Worker if (glx_driver)
647*61046927SAndroid Build Coastguard Worker loader_extensions_local = kopper_extensions_noshm;
648*61046927SAndroid Build Coastguard Worker else if (!check_xshm(psc->base.dpy))
649*61046927SAndroid Build Coastguard Worker loader_extensions_local = loader_extensions_noshm;
650*61046927SAndroid Build Coastguard Worker else
651*61046927SAndroid Build Coastguard Worker loader_extensions_local = loader_extensions_shm;
652*61046927SAndroid Build Coastguard Worker priv->driver = glx_driver ? GLX_DRIVER_ZINK_YES : GLX_DRIVER_SW;
653*61046927SAndroid Build Coastguard Worker
654*61046927SAndroid Build Coastguard Worker if (!dri_screen_init(&psc->base, priv, screen, -1, loader_extensions_local, driver_name_is_inferred)) {
655*61046927SAndroid Build Coastguard Worker if (!glx_driver || !driver_name_is_inferred)
656*61046927SAndroid Build Coastguard Worker ErrorMessageF("glx: failed to create drisw screen\n");
657*61046927SAndroid Build Coastguard Worker goto handle_error;
658*61046927SAndroid Build Coastguard Worker }
659*61046927SAndroid Build Coastguard Worker
660*61046927SAndroid Build Coastguard Worker psc->base.context_vtable = &drisw_context_vtable;
661*61046927SAndroid Build Coastguard Worker psp = &psc->base.driScreen;
662*61046927SAndroid Build Coastguard Worker psc->base.can_EXT_texture_from_pixmap = true;
663*61046927SAndroid Build Coastguard Worker psp->createDrawable = driswCreateDrawable;
664*61046927SAndroid Build Coastguard Worker psp->swapBuffers = driswSwapBuffers;
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker if (!glx_driver)
667*61046927SAndroid Build Coastguard Worker psp->copySubBuffer = drisw_copy_sub_buffer;
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker if (psc->kopper) {
670*61046927SAndroid Build Coastguard Worker psp->setSwapInterval = driswKopperSetSwapInterval;
671*61046927SAndroid Build Coastguard Worker psp->getSwapInterval = kopperGetSwapInterval;
672*61046927SAndroid Build Coastguard Worker psp->maxSwapInterval = 1;
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker return &psc->base;
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker handle_error:
678*61046927SAndroid Build Coastguard Worker
679*61046927SAndroid Build Coastguard Worker glx_screen_cleanup(&psc->base);
680*61046927SAndroid Build Coastguard Worker free(psc);
681*61046927SAndroid Build Coastguard Worker
682*61046927SAndroid Build Coastguard Worker if (glx_driver & GLX_DRIVER_ZINK_YES && !driver_name_is_inferred)
683*61046927SAndroid Build Coastguard Worker CriticalErrorMessageF("failed to load driver: %s\n", driver);
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker return NULL;
686*61046927SAndroid Build Coastguard Worker }
687*61046927SAndroid Build Coastguard Worker
688*61046927SAndroid Build Coastguard Worker #endif /* GLX_DIRECT_RENDERING */
689