dri2_glx.c revision 385e2896ebf54ac0b016132fe513f21a5b67ba4f
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright © 2008 Red Hat, Inc.
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copy of this software and associated documentation files (the "Soft-
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ware"), to deal in the Software without restriction, including without
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * limitation the rights to use, copy, modify, merge, publish, distribute,
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and/or sell copies of the Software, and to permit persons to whom the
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Software is furnished to do so, provided that the above copyright
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice(s) and this permission notice appear in all copies of the Soft-
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ware and that both the above copyright notice(s) and this permission
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice appear in supporting documentation.
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * MANCE OF THIS SOFTWARE.
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Except as contained in this notice, the name of a copyright holder shall
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * not be used in advertising or otherwise to promote the sale, use or
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * other dealings in this Software without prior written authorization of
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the copyright holder.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Authors:
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *   Kristian Høgsberg (krh@redhat.com)
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef GLX_DIRECT_RENDERING
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <X11/Xlib.h>
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <X11/extensions/Xfixes.h>
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <X11/extensions/Xdamage.h>
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "glapi.h"
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "glxclient.h"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <X11/extensions/dri2proto.h>
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "xf86dri.h"
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <dlfcn.h>
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <fcntl.h>
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <unistd.h>
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/types.h>
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/mman.h>
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "xf86drm.h"
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "dri2.h"
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "dri_common.h"
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "../../mesa/drivers/dri/common/dri_util.h"
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#undef DRI2_MINOR
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define DRI2_MINOR 1
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct __GLXDRIdisplayPrivateRec
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIdisplay base;
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /*
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ** XFree86-DRI version information
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    */
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int driMajor;
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int driMinor;
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int driPatch;
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int swapAvailable;
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int invalidateAvailable;
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct __GLXDRIcontextPrivateRec
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIcontext base;
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __DRIcontext *driContext;
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXscreenConfigs *psc;
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct __GLXDRIdrawablePrivateRec
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIdrawable base;
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __DRIbuffer buffers[5];
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int bufferCount;
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int width, height;
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int have_back;
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int have_fake_front;
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   int swap_interval;
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void dri2WaitX(__GLXDRIdrawable * pdraw);
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2DestroyContext(__GLXDRIcontext * context,
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                   __GLXscreenConfigs * psc, Display * dpy)
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   const __DRIcoreExtension *core = pcp->psc->core;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   (*core->destroyContext) (pcp->driContext);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   Xfree(pcp);
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic Bool
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2BindContext(__GLXDRIcontext * context,
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   const __DRIcoreExtension *core = pcp->psc->core;
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return (*core->bindContext) (pcp->driContext,
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                draw->driDrawable, read->driDrawable);
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2UnbindContext(__GLXDRIcontext * context)
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   const __DRIcoreExtension *core = pcp->psc->core;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   (*core->unbindContext) (pcp->driContext);
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic __GLXDRIcontext *
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2CreateContext(__GLXscreenConfigs * psc,
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                  const __GLcontextModes * mode,
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                  GLXContext gc, GLXContext shareList, int renderType)
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIcontextPrivate *pcp, *pcp_shared;
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __DRIcontext *shared = NULL;
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (shareList) {
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      shared = pcp_shared->driContext;
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   }
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp = Xmalloc(sizeof *pcp);
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (pcp == NULL)
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return NULL;
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp->psc = psc;
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp->driContext =
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      (*psc->dri2->createNewContext) (psc->__driScreen,
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                      config->driConfig, shared, pcp);
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   gc->__driContext = pcp->driContext;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (pcp->driContext == NULL) {
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      Xfree(pcp);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return NULL;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   }
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp->base.destroyContext = dri2DestroyContext;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp->base.bindContext = dri2BindContext;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pcp->base.unbindContext = dri2UnbindContext;
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return &pcp->base;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2DestroyDrawable(__GLXDRIdrawable * pdraw)
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   const __DRIcoreExtension *core = pdraw->psc->core;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   (*core->destroyDrawable) (pdraw->driDrawable);
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   Xfree(pdraw);
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic __GLXDRIdrawable *
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2CreateDrawable(__GLXscreenConfigs * psc,
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                   XID xDrawable,
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                   GLXDrawable drawable, const __GLcontextModes * modes)
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIdrawablePrivate *pdraw;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw = Xmalloc(sizeof(*pdraw));
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (!pdraw)
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return NULL;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->base.destroyDrawable = dri2DestroyDrawable;
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->base.xDrawable = xDrawable;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->base.drawable = drawable;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->base.psc = psc;
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->bufferCount = 0;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->swap_interval = 1;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   DRI2CreateDrawable(psc->dpy, xDrawable);
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /* Create a new drawable */
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   pdraw->base.driDrawable =
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      (*psc->dri2->createNewDrawable) (psc->__driScreen,
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       config->driConfig, pdraw);
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (!pdraw->base.driDrawable) {
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      DRI2DestroyDrawable(psc->dpy, xDrawable);
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      Xfree(pdraw);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return NULL;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   }
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /*
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    * Make sure server has the same swap interval we do for the new
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    * drawable.
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    */
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return &pdraw->base;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef X_DRI2GetMSC
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   int64_t *ust, int64_t *msc, int64_t *sbc)
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return DRI2GetMSC(psc->dpy, pdraw->xDrawable, ust, msc, sbc);
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef X_DRI2WaitMSC
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		      remainder, ust, msc, sbc);
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	       int64_t *msc, int64_t *sbc)
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   return DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable, target_sbc, ust, msc,
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		      sbc);
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* X_DRI2WaitMSC */
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   XRectangle xrect;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   XserverRegion region;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /* Check we have the right attachments */
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (!priv->have_back)
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return;
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   xrect.x = x;
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   xrect.y = priv->height - y - height;
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   xrect.width = width;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   xrect.height = height;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef __DRI2_FLUSH
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (pdraw->psc->f)
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      (*pdraw->psc->f->flush) (pdraw->driDrawable);
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /* should get a fence ID back from here at some point */
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                  DRI2BufferFrontLeft, DRI2BufferBackLeft);
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   XFixesDestroyRegion(pdraw->psc->dpy, region);
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /* Refresh the fake front (if present) after we just damaged the real
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    * front.
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    */
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   dri2WaitX(pdraw);
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectdri2WaitX(__GLXDRIdrawable *pdraw)
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   XRectangle xrect;
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   XserverRegion region;
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   /* Check we have the right attachments */
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   if (!priv->have_fake_front)
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   xrect.x = 0;
288   xrect.y = 0;
289   xrect.width = priv->width;
290   xrect.height = priv->height;
291
292#ifdef __DRI2_FLUSH
293   if (pdraw->psc->f)
294      (*pdraw->psc->f->flush) (pdraw->driDrawable);
295#endif
296
297   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
298   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
299                  DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
300   XFixesDestroyRegion(pdraw->psc->dpy, region);
301}
302
303static void
304dri2WaitGL(__GLXDRIdrawable * pdraw)
305{
306   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
307   XRectangle xrect;
308   XserverRegion region;
309
310   if (!priv->have_fake_front)
311      return;
312
313   xrect.x = 0;
314   xrect.y = 0;
315   xrect.width = priv->width;
316   xrect.height = priv->height;
317
318#ifdef __DRI2_FLUSH
319   if (pdraw->psc->f)
320      (*pdraw->psc->f->flush) (pdraw->driDrawable);
321#endif
322
323   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
324   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
325                  DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
326   XFixesDestroyRegion(pdraw->psc->dpy, region);
327}
328
329static void
330dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
331{
332   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
333   __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy);
334   __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display;
335
336   /* Old servers don't send invalidate events */
337   if (!pdp->invalidateAvailable)
338       dri2InvalidateBuffers(priv->dpy, pdraw->base.drawable);
339
340   dri2WaitGL(loaderPrivate);
341}
342
343
344static void
345dri2DestroyScreen(__GLXscreenConfigs * psc)
346{
347   /* Free the direct rendering per screen data */
348   (*psc->core->destroyScreen) (psc->__driScreen);
349   close(psc->fd);
350   psc->__driScreen = NULL;
351}
352
353/**
354 * Process list of buffer received from the server
355 *
356 * Processes the list of buffers received in a reply from the server to either
357 * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
358 */
359static void
360process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers,
361                unsigned count)
362{
363   int i;
364
365   pdraw->bufferCount = count;
366   pdraw->have_fake_front = 0;
367   pdraw->have_back = 0;
368
369   /* This assumes the DRI2 buffer attachment tokens matches the
370    * __DRIbuffer tokens. */
371   for (i = 0; i < count; i++) {
372      pdraw->buffers[i].attachment = buffers[i].attachment;
373      pdraw->buffers[i].name = buffers[i].name;
374      pdraw->buffers[i].pitch = buffers[i].pitch;
375      pdraw->buffers[i].cpp = buffers[i].cpp;
376      pdraw->buffers[i].flags = buffers[i].flags;
377      if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
378         pdraw->have_fake_front = 1;
379      if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
380         pdraw->have_back = 1;
381   }
382
383}
384
385static int64_t
386dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
387		int64_t remainder)
388{
389    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
390    __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
391    __GLXDRIdisplayPrivate *pdp =
392	(__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
393    int64_t ret;
394
395#ifdef __DRI2_FLUSH
396    if (pdraw->psc->f)
397    	(*pdraw->psc->f->flush)(pdraw->driDrawable);
398#endif
399
400    /* Old servers don't send invalidate events */
401    if (!pdp->invalidateAvailable)
402       dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable);
403
404    /* Old servers can't handle swapbuffers */
405    if (!pdp->swapAvailable) {
406       dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
407       return 0;
408    }
409
410#ifdef X_DRI2SwapBuffers
411    DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
412		    remainder, &ret);
413#endif
414
415    return ret;
416}
417
418static __DRIbuffer *
419dri2GetBuffers(__DRIdrawable * driDrawable,
420               int *width, int *height,
421               unsigned int *attachments, int count,
422               int *out_count, void *loaderPrivate)
423{
424   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
425   DRI2Buffer *buffers;
426
427   buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
428                            width, height, attachments, count, out_count);
429   if (buffers == NULL)
430      return NULL;
431
432   pdraw->width = *width;
433   pdraw->height = *height;
434   process_buffers(pdraw, buffers, *out_count);
435
436   Xfree(buffers);
437
438   return pdraw->buffers;
439}
440
441static __DRIbuffer *
442dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
443                         int *width, int *height,
444                         unsigned int *attachments, int count,
445                         int *out_count, void *loaderPrivate)
446{
447   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
448   DRI2Buffer *buffers;
449
450   buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
451                                      pdraw->base.xDrawable,
452                                      width, height, attachments,
453                                      count, out_count);
454   if (buffers == NULL)
455      return NULL;
456
457   pdraw->width = *width;
458   pdraw->height = *height;
459   process_buffers(pdraw, buffers, *out_count);
460
461   Xfree(buffers);
462
463   return pdraw->buffers;
464}
465
466#ifdef X_DRI2SwapInterval
467
468static void
469dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
470{
471   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
472
473   DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval);
474   priv->swap_interval = interval;
475}
476
477static unsigned int
478dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
479{
480   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
481
482  return priv->swap_interval;
483}
484
485#endif /* X_DRI2SwapInterval */
486
487static const __DRIdri2LoaderExtension dri2LoaderExtension = {
488   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
489   dri2GetBuffers,
490   dri2FlushFrontBuffer,
491   dri2GetBuffersWithFormat,
492};
493
494static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
495   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
496   dri2GetBuffers,
497   dri2FlushFrontBuffer,
498   NULL,
499};
500
501static const __DRIextension *loader_extensions[] = {
502   &dri2LoaderExtension.base,
503   &systemTimeExtension.base,
504   NULL
505};
506
507static const __DRIextension *loader_extensions_old[] = {
508   &dri2LoaderExtension_old.base,
509   &systemTimeExtension.base,
510   NULL
511};
512
513_X_HIDDEN void
514dri2InvalidateBuffers(Display *dpy, XID drawable)
515{
516   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
517
518#if __DRI2_FLUSH_VERSION >= 3
519   if (pdraw && pdraw->psc->f)
520       pdraw->psc->f->invalidate(pdraw->driDrawable);
521#endif
522}
523
524static __GLXDRIscreen *
525dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
526                 __GLXdisplayPrivate * priv)
527{
528   const __DRIconfig **driver_configs;
529   const __DRIextension **extensions;
530   const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
531      priv->dri2Display;
532   __GLXDRIscreen *psp;
533   char *driverName, *deviceName;
534   drm_magic_t magic;
535   int i;
536
537   psp = Xmalloc(sizeof *psp);
538   if (psp == NULL)
539      return NULL;
540
541   if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
542		    &driverName, &deviceName)) {
543      XFree(psp);
544      return NULL;
545   }
546
547   psc->driver = driOpenDriver(driverName);
548   if (psc->driver == NULL) {
549      ErrorMessageF("driver pointer missing\n");
550      goto handle_error;
551   }
552
553   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
554   if (extensions == NULL) {
555      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
556      goto handle_error;
557   }
558
559   for (i = 0; extensions[i]; i++) {
560      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
561	 psc->core = (__DRIcoreExtension *) extensions[i];
562      if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
563	 psc->dri2 = (__DRIdri2Extension *) extensions[i];
564   }
565
566   if (psc->core == NULL || psc->dri2 == NULL) {
567      ErrorMessageF("core dri or dri2 extension not found\n");
568      goto handle_error;
569   }
570
571   psc->fd = open(deviceName, O_RDWR);
572   if (psc->fd < 0) {
573      ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
574      goto handle_error;
575   }
576
577   if (drmGetMagic(psc->fd, &magic)) {
578      ErrorMessageF("failed to get magic\n");
579      goto handle_error;
580   }
581
582   if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
583      ErrorMessageF("failed to authenticate magic %d\n", magic);
584      goto handle_error;
585   }
586
587   /* If the server does not support the protocol for
588    * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
589    */
590   psc->__driScreen =
591      psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
592						   ? loader_extensions_old
593						   : loader_extensions),
594				 &driver_configs, psc);
595
596   if (psc->__driScreen == NULL) {
597      ErrorMessageF("failed to create dri screen\n");
598      goto handle_error;
599   }
600
601   driBindCommonExtensions(psc);
602   dri2BindExtensions(psc);
603
604   psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
605   psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
606
607   psc->driver_configs = driver_configs;
608
609   psp->destroyScreen = dri2DestroyScreen;
610   psp->createContext = dri2CreateContext;
611   psp->createDrawable = dri2CreateDrawable;
612   psp->swapBuffers = dri2SwapBuffers;
613   psp->waitGL = dri2WaitGL;
614   psp->waitX = dri2WaitX;
615   psp->getDrawableMSC = NULL;
616   psp->waitForMSC = NULL;
617   psp->waitForSBC = NULL;
618   psp->setSwapInterval = NULL;
619   psp->getSwapInterval = NULL;
620
621   if (pdp->driMinor >= 2) {
622#ifdef X_DRI2GetMSC
623      psp->getDrawableMSC = dri2DrawableGetMSC;
624#endif
625#ifdef X_DRI2WaitMSC
626      psp->waitForMSC = dri2WaitForMSC;
627      psp->waitForSBC = dri2WaitForSBC;
628#endif
629#ifdef X_DRI2SwapInterval
630      psp->setSwapInterval = dri2SetSwapInterval;
631      psp->getSwapInterval = dri2GetSwapInterval;
632#endif
633#if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
634      __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
635#endif
636   }
637
638   /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
639    * available.*/
640   psp->copySubBuffer = dri2CopySubBuffer;
641   __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
642
643   Xfree(driverName);
644   Xfree(deviceName);
645
646   return psp;
647
648handle_error:
649   Xfree(driverName);
650   Xfree(deviceName);
651   XFree(psp);
652
653   /* FIXME: clean up here */
654
655   return NULL;
656}
657
658/* Called from __glXFreeDisplayPrivate.
659 */
660static void
661dri2DestroyDisplay(__GLXDRIdisplay * dpy)
662{
663   Xfree(dpy);
664}
665
666/*
667 * Allocate, initialize and return a __DRIdisplayPrivate object.
668 * This is called from __glXInitialize() when we are given a new
669 * display pointer.
670 */
671_X_HIDDEN __GLXDRIdisplay *
672dri2CreateDisplay(Display * dpy)
673{
674   __GLXDRIdisplayPrivate *pdp;
675   int eventBase, errorBase;
676
677   if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
678      return NULL;
679
680   pdp = Xmalloc(sizeof *pdp);
681   if (pdp == NULL)
682      return NULL;
683
684   if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) {
685      Xfree(pdp);
686      return NULL;
687   }
688
689   pdp->driPatch = 0;
690   pdp->swapAvailable = (pdp->driMinor >= 2);
691   pdp->invalidateAvailable = (pdp->driMinor >= 3);
692
693   pdp->base.destroyDisplay = dri2DestroyDisplay;
694   pdp->base.createScreen = dri2CreateScreen;
695
696   return &pdp->base;
697}
698
699#endif /* GLX_DIRECT_RENDERING */
700