1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2008 Red Hat, Inc.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Soft-
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ware"), to deal in the Software without restriction, including without
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * limitation the rights to use, copy, modify, merge, publish, distribute,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, provided that the above copyright
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * notice(s) and this permission notice appear in all copies of the Soft-
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ware and that both the above copyright notice(s) and this permission
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * notice appear in supporting documentation.
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MANCE OF THIS SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Except as contained in this notice, the name of a copyright holder shall
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not be used in advertising or otherwise to promote the sale, use or
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other dealings in this Software without prior written authorization of
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the copyright holder.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   Kristian Høgsberg (krh@redhat.com)
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlib.h>
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/extensions/Xfixes.h>
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glapi.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glxclient.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/extensions/dri2proto.h>
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xf86dri.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <dlfcn.h>
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <fcntl.h>
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <unistd.h>
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/types.h>
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/mman.h>
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/time.h>
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xf86drm.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri2.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri_common.h"
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* From xmlpool/options.h, user exposed so should be stable */
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DRI_CONF_VBLANK_NEVER 0
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef DRI2_MINOR
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DRI2_MINOR 1
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri2_display
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdisplay base;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ** XFree86-DRI version information
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driMajor;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driMinor;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driPatch;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int swapAvailable;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int invalidateAvailable;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glxHashTable *dri2Hash;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIextension *loader_extensions[4];
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri2_screen {
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_screen base;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIscreen *driScreen;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIscreen vtable;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIdri2Extension *dri2;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIcoreExtension *core;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRI2flushExtension *f;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRI2configQueryExtension *config;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRItexBufferExtension *texBuffer;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRI2throttleExtension *throttle;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIconfig **driver_configs;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *driver;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int fd;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Bool show_fps;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri2_context
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_context base;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIcontext *driContext;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri2_drawable
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable base;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIdrawable *driDrawable;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIbuffer buffers[5];
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int bufferCount;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int width, height;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int have_back;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int have_fake_front;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int swap_interval;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double previous_time;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned frames;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_context_vtable dri2_context_vtable;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_destroy_context(struct glx_context *context)
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = (struct dri2_context *) context;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) context->psc;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driReleaseDrawables(&pcp->base);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (context->extensions)
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XFree((char *) context->extensions);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->destroyContext) (pcp->driContext);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(pcp);
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic Bool
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_bind_context(struct glx_context *context, struct glx_context *old,
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLXDrawable draw, GLXDrawable read)
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = (struct dri2_context *) context;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw, *pread;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pread = (struct dri2_drawable *) driFetchDrawable(context, read);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driReleaseDrawables(&pcp->base);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw == NULL || pread == NULL)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GLXBadDrawable;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(*psc->core->bindContext) (pcp->driContext,
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   pdraw->driDrawable, pread->driDrawable))
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GLXBadContext;
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the server doesn't send invalidate events, we may miss a
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * resize before the rendering starts.  Invalidate the buffers now
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * so the driver will recheck before rendering starts. */
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = (struct dri2_display *) psc->base.display;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdp->invalidateAvailable) {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2InvalidateBuffers(psc->base.dpy, pdraw->base.xDrawable);
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pread != pdraw)
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dri2InvalidateBuffers(psc->base.dpy, pread->base.xDrawable);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return Success;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_unbind_context(struct glx_context *context, struct glx_context *new)
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = (struct dri2_context *) context;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->unbindContext) (pcp->driContext);
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct glx_context *
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_create_context(struct glx_screen *base,
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct glx_config *config_base,
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct glx_context *shareList, int renderType)
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp, *pcp_shared;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) base;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIcontext *shared = NULL;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shareList) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the shareList context is not a DRI2 context, we cannot possibly
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * create a DRI2 context that shares it.
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shareList->vtable->destroy != dri2_destroy_context) {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return NULL;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pcp_shared = (struct dri2_context *) shareList;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shared = pcp_shared->driContext;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp = Xmalloc(sizeof *pcp);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp == NULL)
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(pcp, 0, sizeof *pcp);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->driContext =
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->dri2->createNewContext) (psc->driScreen,
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      config->driConfig, shared, pcp);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp->driContext == NULL) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->base.vtable = &dri2_context_vtable;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pcp->base;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct glx_context *
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_create_context_attribs(struct glx_screen *base,
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    struct glx_config *config_base,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    struct glx_context *shareList,
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    unsigned num_attribs,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    const uint32_t *attribs,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    unsigned *error)
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = NULL;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp_shared = NULL;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) base;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIcontext *shared = NULL;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t minor_ver = 1;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t major_ver = 2;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t flags = 0;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned api;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t ctx_attribs[2 * 5];
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_ctx_attribs = 0;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->dri2->base.version < 3) {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = __DRI_CTX_ERROR_NO_MEMORY;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error_exit;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Remap the GLX tokens to DRI2 tokens.
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_convert_glx_attribs(num_attribs, attribs,
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 &major_ver, &minor_ver, &flags, &api, &reset,
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 error))
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error_exit;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shareList) {
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pcp_shared = (struct dri2_context *) shareList;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shared = pcp_shared->driContext;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp = Xmalloc(sizeof *pcp);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp == NULL) {
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *error = __DRI_CTX_ERROR_NO_MEMORY;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error_exit;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(pcp, 0, sizeof *pcp);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!glx_context_init(&pcp->base, &psc->base, &config->base))
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error_exit;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_attribs[num_ctx_attribs++] = major_ver;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_attribs[num_ctx_attribs++] = minor_ver;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Only send a value when the non-default value is requested.  By doing
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * this we don't have to check the driver's DRI2 version before sending the
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * default value.
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) {
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_attribs[num_ctx_attribs++] = reset;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (flags != 0) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The current __DRI_CTX_FLAG_* values are identical to the
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * GLX_CONTEXT_*_BIT values.
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_attribs[num_ctx_attribs++] = flags;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->driContext =
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->dri2->createContextAttribs) (psc->driScreen,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  api,
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  config->driConfig,
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  shared,
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  num_ctx_attribs / 2,
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  ctx_attribs,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  error,
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  pcp);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp->driContext == NULL)
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error_exit;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->base.vtable = &dri2_context_vtable;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pcp->base;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror_exit:
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp != NULL)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2DestroyDrawable(__GLXDRIdrawable *base)
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) base->psc;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *dpyPriv = psc->base.display;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glxHashDelete(pdp->dri2Hash, pdraw->base.xDrawable);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->destroyDrawable) (pdraw->driDrawable);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If it's a GLX 1.3 drawables, we can destroy the DRI2 drawable
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * now, as the application explicitly asked to destroy the GLX
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * drawable.  Otherwise, for legacy drawables, we let the DRI2
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * drawable linger on the server, since there's no good way of
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * knowing when the application is done with it.  The server will
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * destroy the DRI2 drawable when it destroys the X drawable or the
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * client exits anyway. */
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw->base.xDrawable != pdraw->base.drawable)
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DRI2DestroyDrawable(psc->base.dpy, pdraw->base.xDrawable);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(pdraw);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __GLXDRIdrawable *
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2CreateDrawable(struct glx_screen *base, XID xDrawable,
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLXDrawable drawable, struct glx_config *config_base)
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) base;
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *dpyPriv;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw = Xmalloc(sizeof(*pdraw));
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdraw)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(pdraw, 0, sizeof *pdraw);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->base.destroyDrawable = dri2DestroyDrawable;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->base.xDrawable = xDrawable;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->base.drawable = drawable;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->base.psc = &psc->base;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->bufferCount = 0;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->swap_interval = 1; /* default may be overridden below */
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->have_back = 0;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->config)
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->config->configQueryi(psc->driScreen,
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"vblank_mode", &vblank_mode);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (vblank_mode) {
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_NEVER:
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_DEF_INTERVAL_0:
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->swap_interval = 0;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_DEF_INTERVAL_1:
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_ALWAYS_SYNC:
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->swap_interval = 1;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2CreateDrawable(psc->base.dpy, xDrawable);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dpyPriv = __glXInitialize(psc->base.dpy);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = (struct dri2_display *)dpyPriv->dri2Display;;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Create a new drawable */
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->driDrawable =
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->dri2->createNewDrawable) (psc->driScreen,
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       config->driConfig, pdraw);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdraw->driDrawable) {
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdraw);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (__glxHashInsert(pdp->dri2Hash, xDrawable, pdraw)) {
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->core->destroyDrawable) (pdraw->driDrawable);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdraw);
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return None;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2SwapInterval
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Make sure server has the same swap interval we do for the new
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * drawable.
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp->swapAvailable)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DRI2SwapInterval(psc->base.dpy, xDrawable, pdraw->swap_interval);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pdraw->base;
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2GetMSC
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2DrawableGetMSC(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   int64_t *ust, int64_t *msc, int64_t *sbc)
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CARD64 dri2_ust, dri2_msc, dri2_sbc;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = DRI2GetMSC(psc->dpy, pdraw->xDrawable,
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    &dri2_ust, &dri2_msc, &dri2_sbc);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *ust = dri2_ust;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *msc = dri2_msc;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *sbc = dri2_sbc;
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2WaitMSC
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CARD64 dri2_ust, dri2_msc, dri2_sbc;
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     remainder, &dri2_ust, &dri2_msc, &dri2_sbc);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *ust = dri2_ust;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *msc = dri2_msc;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *sbc = dri2_sbc;
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       int64_t *msc, int64_t *sbc)
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CARD64 dri2_ust, dri2_msc, dri2_sbc;
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable,
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     target_sbc, &dri2_ust, &dri2_msc, &dri2_sbc);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *ust = dri2_ust;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *msc = dri2_msc;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *sbc = dri2_sbc;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* X_DRI2WaitMSC */
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dri2Throttle - Request driver throttling
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function uses the DRI2 throttle extension to give the
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * driver the opportunity to throttle on flush front, copysubbuffer
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and swapbuffers.
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2Throttle(struct dri2_screen *psc,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     struct dri2_drawable *draw,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     enum __DRI2throttleReason reason)
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->throttle) {
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct glx_context *gc = __glXGetCurrentContext();
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct dri2_context *dri2Ctx = (struct dri2_context *)gc;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __DRIcontext *ctx =
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 (dri2Ctx) ? dri2Ctx->driContext : NULL;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->throttle->throttle(ctx, draw->driDrawable, reason);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org__dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    int width, int height,
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    enum __DRI2throttleReason reason)
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XRectangle xrect;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XserverRegion region;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check we have the right attachments */
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!priv->have_back)
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.x = x;
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.y = priv->height - y - height;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.width = width;
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.height = height;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI2_FLUSH
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->f)
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->f->flush) (priv->driDrawable);
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2Throttle(psc, priv, reason);
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  DRI2BufferFrontLeft, DRI2BufferBackLeft);
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Refresh the fake front (if present) after we just damaged the real
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * front.
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (priv->have_fake_front)
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFixesDestroyRegion(psc->base.dpy, region);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  int width, int height)
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __dri2CopySubBuffer(pdraw, x, y, width, height,
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       __DRI2_THROTTLE_COPYSUBBUFFER);
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_copy_drawable(struct dri2_drawable *priv, int dest, int src)
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XRectangle xrect;
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XserverRegion region;
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.x = 0;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.y = 0;
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.width = priv->width;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrect.height = priv->height;
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI2_FLUSH
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->f)
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->f->flush) (priv->driDrawable);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2CopyRegion(psc->base.dpy, priv->base.xDrawable, region, dest, src);
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFixesDestroyRegion(psc->base.dpy, region);
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_wait_x(struct glx_context *gc)
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *priv = (struct dri2_drawable *)
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (priv == NULL || !priv->have_fake_front)
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_copy_drawable(priv, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_wait_gl(struct glx_context *gc)
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *priv = (struct dri2_drawable *)
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (priv == NULL || !priv->have_fake_front)
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_copy_drawable(priv, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *priv;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_context *gc;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = loaderPrivate;
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc;
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdraw)
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdraw->base.psc)
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc = (struct dri2_screen *) pdraw->base.psc;
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   priv = __glXInitialize(psc->base.dpy);
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = (struct dri2_display *) priv->dri2Display;
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gc = __glXGetCurrentContext();
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2Throttle(psc, pdraw, __DRI2_THROTTLE_FLUSHFRONT);
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Old servers don't send invalidate events */
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdp->invalidateAvailable)
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_wait_gl(gc);
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2DestroyScreen(struct glx_screen *base)
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) base;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Free the direct rendering per screen data */
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->destroyScreen) (psc->driScreen);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driDestroyConfigs(psc->driver_configs);
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   close(psc->fd);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(psc);
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Process list of buffer received from the server
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Processes the list of buffers received in a reply from the server to either
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprocess_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers,
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                unsigned count)
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->bufferCount = count;
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->have_fake_front = 0;
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->have_back = 0;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This assumes the DRI2 buffer attachment tokens matches the
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * __DRIbuffer tokens. */
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->buffers[i].attachment = buffers[i].attachment;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->buffers[i].name = buffers[i].name;
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->buffers[i].pitch = buffers[i].pitch;
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->buffers[i].cpp = buffers[i].cpp;
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw->buffers[i].flags = buffers[i].flags;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pdraw->have_fake_front = 1;
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pdraw->have_back = 1;
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned dri2GetSwapEventType(Display* dpy, XID drawable)
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct glx_display *glx_dpy = __glXInitialize(dpy);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __GLXDRIdrawable *pdraw;
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!pdraw || !(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return 0;
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return glx_dpy->codes->first_event + GLX_BufferSwapComplete;
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void show_fps(struct dri2_drawable *draw)
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct timeval tv;
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double current_time;
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gettimeofday(&tv, 0);
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   current_time = (double)tv.tv_sec + (double)tv.tv_usec * 0.000001;
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw->frames++;
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (draw->previous_time + 1 < current_time) {
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (draw->previous_time) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "libGL: FPS = %.1f\n",
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 draw->frames / (current_time - draw->previous_time));
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      draw->frames = 0;
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      draw->previous_time = current_time;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int64_t
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int64_t remainder)
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct glx_display *dpyPriv = __glXInitialize(priv->base.psc->dpy);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct dri2_display *pdp =
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	(struct dri2_display *)dpyPriv->dri2Display;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CARD64 ret = 0;
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Check we have the right attachments */
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!priv->have_back)
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ret;
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Old servers can't handle swapbuffers */
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!pdp->swapAvailable) {
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       __dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height,
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   __DRI2_THROTTLE_SWAPBUFFER);
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2SwapBuffers
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI2_FLUSH
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (psc->f) {
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       struct glx_context *gc = __glXGetCurrentContext();
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (gc) {
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  (*psc->f->flush)(priv->driDrawable);
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       dri2Throttle(psc, priv, __DRI2_THROTTLE_SWAPBUFFER);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       DRI2SwapBuffers(psc->base.dpy, pdraw->xDrawable,
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       target_msc, divisor, remainder, &ret);
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (psc->show_fps) {
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       show_fps(priv);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Old servers don't send invalidate events */
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!pdp->invalidateAvailable)
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable);
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ret;
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __DRIbuffer *
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2GetBuffers(__DRIdrawable * driDrawable,
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int *width, int *height,
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               unsigned int *attachments, int count,
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int *out_count, void *loaderPrivate)
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = loaderPrivate;
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2Buffer *buffers;
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            width, height, attachments, count, out_count);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (buffers == NULL)
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->width = *width;
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->height = *height;
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   process_buffers(pdraw, buffers, *out_count);
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(buffers);
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pdraw->buffers;
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __DRIbuffer *
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         int *width, int *height,
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         unsigned int *attachments, int count,
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         int *out_count, void *loaderPrivate)
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = loaderPrivate;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2Buffer *buffers;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      pdraw->base.xDrawable,
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      width, height, attachments,
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      count, out_count);
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (buffers == NULL)
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->width = *width;
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw->height = *height;
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   process_buffers(pdraw, buffers, *out_count);
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(buffers);
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return pdraw->buffers;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2SwapInterval
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->config)
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->config->configQueryi(psc->driScreen,
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				"vblank_mode", &vblank_mode);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (vblank_mode) {
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_NEVER:
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GLX_BAD_VALUE;
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case DRI_CONF_VBLANK_ALWAYS_SYNC:
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (interval <= 0)
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return GLX_BAD_VALUE;
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI2SwapInterval(priv->base.psc->dpy, priv->base.xDrawable, interval);
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   priv->swap_interval = interval;
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2GetSwapInterval(__GLXDRIdrawable *pdraw)
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return priv->swap_interval;
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* X_DRI2SwapInterval */
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIdri2LoaderExtension dri2LoaderExtension = {
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2GetBuffers,
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2FlushFrontBuffer,
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2GetBuffersWithFormat,
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2GetBuffers,
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2FlushFrontBuffer,
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI_USE_INVALIDATE
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIuseInvalidateExtension dri2UseInvalidate = {
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { __DRI_USE_INVALIDATE, __DRI_USE_INVALIDATE_VERSION }
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_HIDDEN void
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2InvalidateBuffers(Display *dpy, XID drawable)
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *pdraw =
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc;
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdraw)
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc = (struct dri2_screen *) pdraw->psc;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if __DRI2_FLUSH_VERSION >= 3
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw && psc->f && psc->f->base.version >= 3 && psc->f->invalidate)
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       psc->f->invalidate(pdp->driDrawable);
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_bind_tex_image(Display * dpy,
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    GLXDrawable drawable,
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    int buffer, const int *attrib_list)
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_context *gc = __glXGetCurrentContext();
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = (struct dri2_context *) gc;
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *dpyPriv = __glXInitialize(dpy);
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp =
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct dri2_display *) dpyPriv->dri2Display;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc;
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw != NULL) {
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc = (struct dri2_screen *) base->psc;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if __DRI2_FLUSH_VERSION >= 3
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!pdp->invalidateAvailable && psc->f &&
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           psc->f->base.version >= 3 && psc->f->invalidate)
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->f->invalidate(pdraw->driDrawable);
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (psc->texBuffer->base.version >= 2 &&
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  psc->texBuffer->setTexBuffer2 != NULL) {
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   pdraw->base.textureTarget,
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   pdraw->base.textureFormat,
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   pdraw->driDrawable);
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 (*psc->texBuffer->setTexBuffer) (pcp->driContext,
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  pdraw->base.textureTarget,
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  pdraw->driDrawable);
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if __DRI_TEX_BUFFER_VERSION >= 3
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_context *gc = __glXGetCurrentContext();
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_context *pcp = (struct dri2_context *) gc;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *dpyPriv = __glXInitialize(dpy);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp =
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct dri2_display *) dpyPriv->dri2Display;
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc;
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw != NULL) {
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc = (struct dri2_screen *) base->psc;
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (psc->texBuffer->base.version >= 3 &&
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          psc->texBuffer->releaseTexBuffer != NULL) {
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           pdraw->base.textureTarget,
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           pdraw->driDrawable);
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_context_vtable dri2_context_vtable = {
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_destroy_context,
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_bind_context,
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_unbind_context,
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_wait_gl,
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_wait_x,
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI_glXUseXFont,
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_bind_tex_image,
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_release_tex_image,
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL, /* get_proc_address */
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions,
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const char *driverName)
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * GLX_INTEL_swap_event is broken on the server side, where it's
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * currently unconditionally enabled. This completely breaks
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * systems running on drivers which don't support that extension.
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * There's no way to test for its presence on this side, so instead
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * of disabling it uncondtionally, just disable it for drivers
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * which are known to not support it.
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strcmp(driverName, "vmwgfx") != 0) {
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __glXEnableDirectExtension(&psc->base, "GLX_INTEL_swap_event");
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->dri2->base.version >= 3) {
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned mask = psc->dri2->getAPIMask(psc->driScreen);
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context");
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context_profile");
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((mask & (1 << __DRI_API_GLES2)) != 0)
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base,
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    "GLX_EXT_create_context_es2_profile");
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; extensions[i]; i++) {
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->f = (__DRI2flushExtension *) extensions[i];
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* internal driver extension, no GL extension exposed */
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0))
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->config = (__DRI2configQueryExtension *) extensions[i];
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (((strcmp(extensions[i]->name, __DRI2_THROTTLE) == 0)))
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->throttle = (__DRI2throttleExtension *) extensions[i];
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* DRI2 version 3 is also required because
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * GLX_ARB_create_context_robustness requires GLX_ARB_create_context.
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (psc->dri2->base.version >= 3
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0)
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         __glXEnableDirectExtension(&psc->base,
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "GLX_ARB_create_context_robustness");
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_screen_vtable dri2_screen_vtable = {
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_create_context,
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_create_context_attribs
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct glx_screen *
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2CreateScreen(int screen, struct glx_display * priv)
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIconfig **driver_configs;
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIextension **extensions;
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct dri2_display *const pdp = (struct dri2_display *)
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      priv->dri2Display;
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_screen *psc;
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIscreen *psp;
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_config *configs = NULL, *visuals = NULL;
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char *driverName, *deviceName, *tmp;
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_magic_t magic;
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc = Xmalloc(sizeof *psc);
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc == NULL)
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(psc, 0, sizeof *psc);
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->fd = -1;
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!glx_screen_init(&psc->base, screen, priv)) {
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(psc);
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!DRI2Connect(priv->dpy, RootWindow(priv->dpy, screen),
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    &driverName, &deviceName)) {
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glx_screen_cleanup(&psc->base);
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XFree(psc);
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      InfoMessageF("screen %d does not appear to be DRI2 capable\n", screen);
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driver = driOpenDriver(driverName);
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driver == NULL) {
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("driver pointer missing\n");
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (extensions == NULL) {
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; extensions[i]; i++) {
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->core = (__DRIcoreExtension *) extensions[i];
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->dri2 = (__DRIdri2Extension *) extensions[i];
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->core == NULL || psc->dri2 == NULL) {
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("core dri or dri2 extension not found\n");
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef O_CLOEXEC
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->fd = open(deviceName, O_RDWR | O_CLOEXEC);
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->fd == -1 && errno == EINVAL)
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->fd = open(deviceName, O_RDWR);
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (psc->fd != -1)
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fcntl(psc->fd, F_SETFD, fcntl(psc->fd, F_GETFD) | FD_CLOEXEC);
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->fd < 0) {
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (drmGetMagic(psc->fd, &magic)) {
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("failed to get magic\n");
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!DRI2Authenticate(priv->dpy, RootWindow(priv->dpy, screen), magic)) {
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("failed to authenticate magic %d\n", magic);
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the server does not support the protocol for
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driScreen =
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->dri2->createNewScreen(screen, psc->fd,
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 (const __DRIextension **)
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 &pdp->loader_extensions[0],
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 &driver_configs, psc);
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driScreen == NULL) {
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("failed to create dri screen\n");
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   extensions = psc->core->getExtensions(psc->driScreen);
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2BindExtensions(psc, extensions, driverName);
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!configs || !visuals)
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       goto handle_error;
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_config_destroy_list(psc->base.configs);
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.configs = configs;
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_config_destroy_list(psc->base.visuals);
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.visuals = visuals;
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driver_configs = driver_configs;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.vtable = &dri2_screen_vtable;
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp = &psc->vtable;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.driScreen = psp;
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->destroyScreen = dri2DestroyScreen;
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->createDrawable = dri2CreateDrawable;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->swapBuffers = dri2SwapBuffers;
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->getDrawableMSC = NULL;
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->waitForMSC = NULL;
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->waitForSBC = NULL;
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->setSwapInterval = NULL;
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->getSwapInterval = NULL;
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp->driMinor >= 2) {
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2GetMSC
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->getDrawableMSC = dri2DrawableGetMSC;
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2WaitMSC
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->waitForMSC = dri2WaitForMSC;
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->waitForSBC = dri2WaitForSBC;
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef X_DRI2SwapInterval
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->setSwapInterval = dri2SetSwapInterval;
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->getSwapInterval = dri2GetSwapInterval;
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      __glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * available.*/
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->copySubBuffer = dri2CopySubBuffer;
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(driverName);
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(deviceName);
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp = getenv("LIBGL_SHOW_FPS");
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->show_fps = tmp && strcmp(tmp, "1") == 0;
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &psc->base;
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orghandle_error:
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CriticalErrorMessageF("failed to load driver: %s\n", driverName);
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (configs)
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       glx_config_destroy_list(configs);
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visuals)
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       glx_config_destroy_list(visuals);
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driScreen)
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       psc->core->destroyScreen(psc->driScreen);
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driScreen = NULL;
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->fd >= 0)
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      close(psc->fd);
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driver)
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dlclose(psc->driver);
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(driverName);
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(deviceName);
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_screen_cleanup(&psc->base);
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFree(psc);
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Called from __glXFreeDisplayPrivate.
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2DestroyDisplay(__GLXDRIdisplay * dpy)
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp = (struct dri2_display *) dpy;
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glxHashDestroy(pdp->dri2Hash);
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(dpy);
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_HIDDEN __GLXDRIdrawable *
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_display *d = __glXInitialize(dpy);
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp = (struct dri2_display *) d->dri2Display;
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *pdraw;
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (__glxHashLookup(pdp->dri2Hash, id, (void *) &pdraw) == 0)
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return pdraw;
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate, initialize and return a __DRIdisplayPrivate object.
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is called from __glXInitialize() when we are given a new
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * display pointer.
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_HIDDEN __GLXDRIdisplay *
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2CreateDisplay(Display * dpy)
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_display *pdp;
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int eventBase, errorBase, i;
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = Xmalloc(sizeof *pdp);
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp == NULL)
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) {
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdp);
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->driPatch = 0;
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->swapAvailable = (pdp->driMinor >= 2);
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->invalidateAvailable = (pdp->driMinor >= 3);
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->base.destroyDisplay = dri2DestroyDisplay;
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->base.createScreen = dri2CreateScreen;
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = 0;
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp->driMinor < 1)
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdp->loader_extensions[i++] = &dri2LoaderExtension_old.base;
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pdp->loader_extensions[i++] = &dri2LoaderExtension.base;
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->loader_extensions[i++] = &systemTimeExtension.base;
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI_USE_INVALIDATE
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->loader_extensions[i++] = NULL;
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->dri2Hash = __glxHashCreate();
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp->dri2Hash == NULL) {
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdp);
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pdp->base;
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* GLX_DIRECT_RENDERING */
1274