12889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg/*
22889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Copyright © 2011 Intel Corporation
32889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *
42889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Permission is hereby granted, free of charge, to any person obtaining a
52889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * copy of this software and associated documentation files (the "Software"),
62889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * to deal in the Software without restriction, including without limitation
72889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
82889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * and/or sell copies of the Software, and to permit persons to whom the
92889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Software is furnished to do so, subject to the following conditions:
102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *
112889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * The above copyright notice and this permission notice (including the next
122889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * paragraph) shall be included in all copies or substantial portions of the
132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Software.
142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *
152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
162889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
182889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
192889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
222889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * DEALINGS IN THE SOFTWARE.
232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *
242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Authors:
252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *    Kristian Høgsberg <krh@bitplanet.net>
262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg */
272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <stdlib.h>
292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <string.h>
302889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <stdio.h>
312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <limits.h>
322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <dlfcn.h>
332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <fcntl.h>
342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <errno.h>
352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <unistd.h>
362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <xf86drm.h>
372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <sys/types.h>
382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include <sys/stat.h>
392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#include "egl_dri2.h"
412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
42f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic void
43f55d027ac2e0423eba5d0664cc36668520597703Haitao FengswrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
44f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                     struct dri2_egl_surface * dri2_surf,
45f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                     int depth)
46f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
47f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   uint32_t           mask;
48f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   const uint32_t     function = GXcopy;
49f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   uint32_t           valgc[2];
50f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
51f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   /* create GC's */
52f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_surf->gc = xcb_generate_id(dri2_dpy->conn);
53f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   mask = XCB_GC_FUNCTION;
54f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_create_gc(dri2_dpy->conn, dri2_surf->gc, dri2_surf->drawable, mask, &function);
55f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
56f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_surf->swapgc = xcb_generate_id(dri2_dpy->conn);
57f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   mask = XCB_GC_FUNCTION | XCB_GC_GRAPHICS_EXPOSURES;
58f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   valgc[0] = function;
59f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   valgc[1] = False;
60f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_create_gc(dri2_dpy->conn, dri2_surf->swapgc, dri2_surf->drawable, mask, valgc);
61f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_surf->depth = depth;
62f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   switch (depth) {
63f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      case 32:
64f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      case 24:
65f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         dri2_surf->bytes_per_pixel = 4;
66f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         break;
67f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      case 16:
68f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         dri2_surf->bytes_per_pixel = 2;
69f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         break;
70f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      case 8:
71f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         dri2_surf->bytes_per_pixel = 1;
72f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         break;
73f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      case 0:
74f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         dri2_surf->bytes_per_pixel = 0;
75f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         break;
76f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      default:
77f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         _eglLog(_EGL_WARNING, "unsupported depth %d", depth);
78f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
79f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
80f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
81f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic void
82f55d027ac2e0423eba5d0664cc36668520597703Haitao FengswrastDestroyDrawable(struct dri2_egl_display * dri2_dpy,
83f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                      struct dri2_egl_surface * dri2_surf)
84f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
85f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_free_gc(dri2_dpy->conn, dri2_surf->gc);
86f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_free_gc(dri2_dpy->conn, dri2_surf->swapgc);
87f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
88f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
89f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic void
90f55d027ac2e0423eba5d0664cc36668520597703Haitao FengswrastGetDrawableInfo(__DRIdrawable * draw,
91f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                      int *x, int *y, int *w, int *h,
92f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                      void *loaderPrivate)
93f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
94f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_surface *dri2_surf = loaderPrivate;
95f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
96f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
97f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_get_geometry_cookie_t cookie;
98f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_get_geometry_reply_t *reply;
99f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_generic_error_t *error;
100f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
101f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   *w = *h = 0;
102f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
103f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
104f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (reply == NULL)
105f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      return;
106f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
107f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (error != NULL) {
108f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "error in xcb_get_geometry");
109f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      free(error);
110f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
111f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      *w = reply->width;
112f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      *h = reply->height;
113f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
114f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   free(reply);
115f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
116f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
117f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic void
118f55d027ac2e0423eba5d0664cc36668520597703Haitao FengswrastPutImage(__DRIdrawable * draw, int op,
119f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng               int x, int y, int w, int h,
120f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng               char *data, void *loaderPrivate)
121f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
122f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_surface *dri2_surf = loaderPrivate;
123f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
124f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
125f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_gcontext_t gc;
126f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
127f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   switch (op) {
128f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   case __DRI_SWRAST_IMAGE_OP_DRAW:
129f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      gc = dri2_surf->gc;
130f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      break;
131f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   case __DRI_SWRAST_IMAGE_OP_SWAP:
132f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      gc = dri2_surf->swapgc;
133f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      break;
134f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   default:
135f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      return;
136f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
137f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
138f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_put_image(dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, dri2_surf->drawable,
139f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                 gc, w, h, x, y, 0, dri2_surf->depth,
140f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                 w*h*dri2_surf->bytes_per_pixel, (const uint8_t *)data);
141f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
142f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
143f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic void
144f55d027ac2e0423eba5d0664cc36668520597703Haitao FengswrastGetImage(__DRIdrawable * read,
145f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng               int x, int y, int w, int h,
146f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng               char *data, void *loaderPrivate)
147f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
148f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_surface *dri2_surf = loaderPrivate;
149f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
150f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
151f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_get_image_cookie_t cookie;
152f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_get_image_reply_t *reply;
153f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   xcb_generic_error_t *error;
154f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
155f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   cookie = xcb_get_image (dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
156f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng                           dri2_surf->drawable, x, y, w, h, ~0);
157f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   reply = xcb_get_image_reply (dri2_dpy->conn, cookie, &error);
158f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (reply == NULL)
159f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      return;
160f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
161f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (error != NULL) {
162f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "error in xcb_get_image");
163f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      free(error);
164f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
165f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      uint32_t bytes = xcb_get_image_data_length(reply);
166f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      uint8_t *idata = xcb_get_image_data(reply);
167f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      memcpy(data, idata, bytes);
168f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
169f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   free(reply);
170f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
171f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
172f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg/**
1742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
1752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg */
1762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLSurface *
1772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
1782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		    _EGLConfig *conf, EGLNativeWindowType window,
1792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		    const EGLint *attrib_list)
1802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
1812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
1822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
1832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf;
1842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_get_geometry_cookie_t cookie;
1852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_get_geometry_reply_t *reply;
1862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_screen_iterator_t s;
1872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_generic_error_t *error;
1882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) drv;
1902889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf = malloc(sizeof *dri2_surf);
1922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!dri2_surf) {
1932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
1942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
1952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
1962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1972889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
1982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_surf;
1992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->region = XCB_NONE;
2012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (type == EGL_PBUFFER_BIT) {
2022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn);
2032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
2042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize,
2052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			dri2_surf->drawable, s.data->root,
2062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			dri2_surf->base.Width, dri2_surf->base.Height);
2072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   } else {
2082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->drawable = window;
2092889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
2102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
211f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (dri2_dpy->dri2) {
212f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      dri2_surf->dri_drawable =
213f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng	 (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
214f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng					       type == EGL_WINDOW_BIT ?
215f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng					       dri2_conf->dri_double_config :
216f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng					       dri2_conf->dri_single_config,
217f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng					       dri2_surf);
218f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
219f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      assert(dri2_dpy->swrast);
220f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      dri2_surf->dri_drawable =
221f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng	 (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
222f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng						 dri2_conf->dri_double_config,
223f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng						 dri2_surf);
224f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
225f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
2262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_surf->dri_drawable == NULL) {
2272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
2282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_pixmap;
2292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
230f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
231f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (dri2_dpy->dri2) {
232f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
233f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
23458f95f9d01f1fe2c260ca87f1ee74d9710947c12Feng, Haitao      swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_BUFFER_SIZE));
235f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
2362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (type != EGL_PBUFFER_BIT) {
2382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
2392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
2402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      if (reply == NULL || error != NULL) {
2412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
2422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 free(error);
2432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 goto cleanup_dri_drawable;
2442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      }
2452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->base.Width = reply->width;
2472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->base.Height = reply->height;
2482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(reply);
2492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
2502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
251eb7d1b9474b021769e2d1f1b64901c64130e53d8Chia-I Wu   /* we always copy the back buffer to front */
252eb7d1b9474b021769e2d1f1b64901c64130e53d8Chia-I Wu   dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE;
25371b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund
2542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return &dri2_surf->base;
2552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_dri_drawable:
2572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
2582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_pixmap:
2592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (type == EGL_PBUFFER_BIT)
2602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable);
2612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_surf:
2622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(dri2_surf);
2632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return NULL;
2652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
2662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg/**
2682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
2692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg */
2702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLSurface *
2712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
2722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			   _EGLConfig *conf, EGLNativeWindowType window,
2732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			   const EGLint *attrib_list)
2742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
2752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
2762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			      window, attrib_list);
2772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
2782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLSurface *
2802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
2812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			   _EGLConfig *conf, EGLNativePixmapType pixmap,
2822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			   const EGLint *attrib_list)
2832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
2842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
2852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			      pixmap, attrib_list);
2862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
2872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLSurface *
2892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
2902889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			    _EGLConfig *conf, const EGLint *attrib_list)
2912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
2922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return dri2_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
2932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			      XCB_WINDOW_NONE, attrib_list);
2942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
2952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
2962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
2972889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
2982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
2992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
3002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
3012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) drv;
3032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!_eglPutSurface(surf))
3052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_TRUE;
3062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
3082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
309f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (dri2_dpy->dri2) {
310f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable);
311f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
312f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      assert(dri2_dpy->swrast);
313f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      swrastDestroyDrawable(dri2_dpy, dri2_surf);
314f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
3152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3162889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (surf->Type == EGL_PBUFFER_BIT)
3172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);
3182889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3192889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(surf);
3202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
3222889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
3232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg/**
3252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Process list of buffer received from the server
3262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg *
3272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * Processes the list of buffers received in a reply from the server to either
3282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
3292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg */
3302889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic void
3312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_process_buffers(struct dri2_egl_surface *dri2_surf,
3322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		     xcb_dri2_dri2_buffer_t *buffers, unsigned count)
3332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
3342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy =
3352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
3362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_rectangle_t rectangle;
3372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   unsigned i;
3382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->buffer_count = count;
3402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->have_fake_front = 0;
3412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   /* This assumes the DRI2 buffer attachment tokens matches the
3432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg    * __DRIbuffer tokens. */
3442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   for (i = 0; i < count; i++) {
3452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->buffers[i].attachment = buffers[i].attachment;
3462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->buffers[i].name = buffers[i].name;
3472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->buffers[i].pitch = buffers[i].pitch;
3482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->buffers[i].cpp = buffers[i].cpp;
3492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_surf->buffers[i].flags = buffers[i].flags;
3502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      /* We only use the DRI drivers single buffer configs.  This
3522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       * means that if we try to render to a window, DRI2 will give us
3532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       * the fake front buffer, which we'll use as a back buffer.
3542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       * Note that EGL doesn't require that several clients rendering
3552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       * to the same window must see the same aux buffers. */
3562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
3572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg         dri2_surf->have_fake_front = 1;
3582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
3592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_surf->region != XCB_NONE)
3612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_xfixes_destroy_region(dri2_dpy->conn, dri2_surf->region);
3622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   rectangle.x = 0;
3642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   rectangle.y = 0;
3652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   rectangle.width = dri2_surf->base.Width;
3662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   rectangle.height = dri2_surf->base.Height;
3672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->region = xcb_generate_id(dri2_dpy->conn);
3682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_create_region(dri2_dpy->conn, dri2_surf->region, 1, &rectangle);
3692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
3702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic __DRIbuffer *
3722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_get_buffers(__DRIdrawable * driDrawable,
3732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		int *width, int *height,
3742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		unsigned int *attachments, int count,
3752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		int *out_count, void *loaderPrivate)
3762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
3772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = loaderPrivate;
3782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy =
3792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
3802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_dri2_buffer_t *buffers;
3812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_reply_t *reply;
3822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_cookie_t cookie;
3832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) driDrawable;
3852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
3872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					    dri2_surf->drawable,
3882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					    count, count, attachments);
3892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL);
3902889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   buffers = xcb_dri2_get_buffers_buffers (reply);
3912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (buffers == NULL)
3922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
3932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   *out_count = reply->count;
3952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->base.Width = *width = reply->width;
3962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->base.Height = *height = reply->height;
3972889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_process_buffers(dri2_surf, buffers, *out_count);
3982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
3992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(reply);
4002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return dri2_surf->buffers;
4022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
4032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic __DRIbuffer *
4052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_get_buffers_with_format(__DRIdrawable * driDrawable,
4062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			     int *width, int *height,
4072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			     unsigned int *attachments, int count,
4082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			     int *out_count, void *loaderPrivate)
4092889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
4102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = loaderPrivate;
4112889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy =
4122889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
4132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_dri2_buffer_t *buffers;
4142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_with_format_reply_t *reply;
4152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_with_format_cookie_t cookie;
4162889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_attach_format_t *format_attachments;
4172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4182889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) driDrawable;
4192889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   format_attachments = (xcb_dri2_attach_format_t *) attachments;
4212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   cookie = xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy->conn,
4222889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg							dri2_surf->drawable,
4232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg							count, count,
4242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg							format_attachments);
4252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   reply = xcb_dri2_get_buffers_with_format_reply (dri2_dpy->conn,
4272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg						   cookie, NULL);
4282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (reply == NULL)
4292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
4302889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   buffers = xcb_dri2_get_buffers_with_format_buffers (reply);
4322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->base.Width = *width = reply->width;
4332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_surf->base.Height = *height = reply->height;
4342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   *out_count = reply->count;
4352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_process_buffers(dri2_surf, buffers, *out_count);
4362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(reply);
4382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return dri2_surf->buffers;
4402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
4412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic void
4432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
4442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
4452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) driDrawable;
4462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   /* FIXME: Does EGL support front buffer rendering at all? */
4482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#if 0
4502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = loaderPrivate;
4512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2WaitGL(dri2_surf);
4532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#else
4542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) loaderPrivate;
4552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#endif
4562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
4572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic char *
4592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_strndup(const char *s, int length)
4602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
4612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   char *d;
4622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   d = malloc(length + 1);
4642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (d == NULL)
4652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
4662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   memcpy(d, s, length);
4682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   d[length] = '\0';
4692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return d;
4712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
4722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
4742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_connect(struct dri2_egl_display *dri2_dpy)
4752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
4762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_query_version_reply_t *xfixes_query;
4772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
4782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_query_version_reply_t *dri2_query;
4792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_query_version_cookie_t dri2_query_cookie;
4802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_connect_reply_t *connect;
4812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_connect_cookie_t connect_cookie;
4822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_generic_error_t *error;
4832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_screen_iterator_t s;
4844ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke   char *driver_name, *device_name;
48580636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke   const xcb_query_extension_reply_t *extension;
4862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
4872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id);
4882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id);
4892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
49080636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke   extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id);
49180636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke   if (!(extension && extension->present))
49280636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke      return EGL_FALSE;
49380636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke
49480636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke   extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id);
49580636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke   if (!(extension && extension->present))
49680636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke      return EGL_FALSE;
49780636ff2da374ca417db5afaaa0ab0cc5de9272dBenjamin Franzke
4982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn,
4992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg						  XCB_XFIXES_MAJOR_VERSION,
5002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg						  XCB_XFIXES_MINOR_VERSION);
5012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn,
5032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					       XCB_DRI2_MAJOR_VERSION,
5042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					       XCB_DRI2_MINOR_VERSION);
5052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
5072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   connect_cookie = xcb_dri2_connect_unchecked (dri2_dpy->conn,
5082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg						s.data->root,
5092889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg						XCB_DRI2_DRIVER_TYPE_DRI);
5102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5112889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xfixes_query =
5122889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_xfixes_query_version_reply (dri2_dpy->conn,
5132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg				      xfixes_query_cookie, &error);
5142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (xfixes_query == NULL ||
5152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       error != NULL || xfixes_query->major_version < 2) {
516f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: failed to query xfixes version");
5172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(error);
5182889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
5192889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
5202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(xfixes_query);
5212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5222889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_query =
5232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error);
5242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_query == NULL || error != NULL) {
525f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: failed to query version");
5262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(error);
5272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
5282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
5292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->dri2_major = dri2_query->major_version;
5302889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->dri2_minor = dri2_query->minor_version;
5312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(dri2_query);
5322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL);
5342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (connect == NULL ||
5352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg       connect->driver_name_length + connect->device_name_length == 0) {
536f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
5372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
5382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
5392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5404ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke   driver_name = xcb_dri2_connect_driver_name (connect);
5412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->driver_name =
5424ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke      dri2_strndup(driver_name,
5432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		   xcb_dri2_connect_driver_name_length (connect));
5442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5454ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke#if XCB_DRI2_CONNECT_DEVICE_NAME_BROKEN
5464ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke   device_name = driver_name + ((connect->driver_name_length + 3) & ~3);
5474ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke#else
5484ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke   device_name = xcb_dri2_connect_device_name (connect);
5494ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke#endif
5504ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke
5514ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke   dri2_dpy->device_name =
5524ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke      dri2_strndup(device_name,
5534ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke		   xcb_dri2_connect_device_name_length (connect));
5544ca075ac4f047141d5e5ef865991650e0ac488e4Benjamin Franzke
5552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->device_name == NULL || dri2_dpy->driver_name == NULL) {
5562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(dri2_dpy->device_name);
5572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(dri2_dpy->driver_name);
5582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(connect);
5592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
5602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
5612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(connect);
5622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
5642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
5652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5666b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
5676b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_x11_authenticate(_EGLDisplay *disp, uint32_t id)
5682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
5696b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
5702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_authenticate_reply_t *authenticate;
5712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_authenticate_cookie_t authenticate_cookie;
5722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_screen_iterator_t s;
5736b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
5746b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5756b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
5766b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   authenticate_cookie =
5776b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      xcb_dri2_authenticate_unchecked(dri2_dpy->conn, s.data->root, id);
5786b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   authenticate =
5796b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
5806b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5816b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (authenticate == NULL || !authenticate->authenticated)
5826b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
5836b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5846b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (authenticate)
5856b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      free(authenticate);
5866b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5876b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
5886b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
5896b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5906b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic EGLBoolean
5916b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_authenticate(_EGLDisplay *disp)
5926b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
5936b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
5942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drm_magic_t magic;
5952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
5962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (drmGetMagic(dri2_dpy->fd, &magic)) {
597f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: failed to get drm magic");
5982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
5992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
6006b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
6016b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (dri2_x11_authenticate(disp, magic) < 0) {
602f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
6032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
6042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
6052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
6072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
6082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6092889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
6102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
6112889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			     _EGLDisplay *disp)
6122889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
6132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_screen_iterator_t s;
6142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_depth_iterator_t d;
6152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_visualtype_t *visuals;
6162889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   int i, j, id;
6172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   EGLint surface_type;
61887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   EGLint config_attrs[] = {
61987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke	   EGL_NATIVE_VISUAL_ID,   0,
62087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke	   EGL_NATIVE_VISUAL_TYPE, 0,
62187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke	   EGL_NONE
62287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   };
6232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
6252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   d = xcb_screen_allowed_depths_iterator(s.data);
6262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   id = 1;
6272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   surface_type =
6292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      EGL_WINDOW_BIT |
6302889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      EGL_PIXMAP_BIT |
6312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      EGL_PBUFFER_BIT |
6322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
6332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   while (d.rem > 0) {
6352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      EGLBoolean class_added[6] = { 0, };
6362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      visuals = xcb_depth_visuals(d.data);
6382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      for (i = 0; i < xcb_depth_visuals_length(d.data); i++) {
6392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 if (class_added[visuals[i]._class])
6402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	    continue;
6412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 class_added[visuals[i]._class] = EGL_TRUE;
6432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 for (j = 0; dri2_dpy->driver_configs[j]; j++) {
64487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke            config_attrs[1] = visuals[i].visual_id;
64587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke            config_attrs[3] = visuals[i]._class;
64687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
64787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke	    dri2_add_config(disp, dri2_dpy->driver_configs[j], id++,
64858911b86a15676f116c693e84ea6b9ebabb906edChia-I Wu			    d.data->depth, surface_type, config_attrs, NULL);
6492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 }
6502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      }
6512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_depth_next(&d);
6532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
6542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!_eglGetArraySize(disp->Configs)) {
6562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglLog(_EGL_WARNING, "DRI2: failed to create any config");
6572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_FALSE;
6582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
6592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
6612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
6622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
6642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
6652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		 _EGLSurface *draw, xcb_xfixes_region_t region)
6662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
6672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
6682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
66987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   enum xcb_dri2_attachment_t render_attachment;
6702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_copy_region_cookie_t cookie;
6712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
672352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   /* No-op for a pixmap or pbuffer surface */
673352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
674352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      return EGL_TRUE;
6752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
676352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#ifdef __DRI2_FLUSH
677352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (dri2_dpy->flush)
678352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
6792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg#endif
6802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
68187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   if (dri2_surf->have_fake_front)
68287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT;
68387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   else
68487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT;
6852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
6872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   dri2_surf->drawable,
6882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   region,
6892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
69087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					   render_attachment);
6912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
6922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
6932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
6942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
6952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
696352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglundstatic int64_t
697352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglunddri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
698352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund                      int64_t msc, int64_t divisor, int64_t remainder)
699352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund{
700352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#if XCB_DRI2_MINOR_VERSION >= 3
701352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
702352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
703352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t msc_hi = msc >> 32;
704352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t msc_lo = msc & 0xffffffff;
705352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t divisor_hi = divisor >> 32;
706352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t divisor_lo = divisor & 0xffffffff;
707352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t remainder_hi = remainder >> 32;
708352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   uint32_t remainder_lo = remainder & 0xffffffff;
709352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   xcb_dri2_swap_buffers_cookie_t cookie;
710352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   xcb_dri2_swap_buffers_reply_t *reply;
711352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   int64_t swap_count = -1;
712352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
713352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   /* No-op for a pixmap or pbuffer surface */
714352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
715352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      return 0;
716352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
717352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available)
718352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1;
719352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
720352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#ifdef __DRI2_FLUSH
721352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (dri2_dpy->flush)
722352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
723352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#endif
724352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
725352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable,
726352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund                  msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo);
727352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
728352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL);
729352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
730352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (reply) {
731352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo;
732352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      free(reply);
733352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   }
734352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
735352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#if __DRI2_FLUSH_VERSION >= 3
736352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   /* If the server doesn't send invalidate events */
737352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (dri2_dpy->invalidate_available && dri2_dpy->flush &&
738352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund       dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate)
739352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
740352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund#endif
741352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
742352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   return swap_count;
743636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#else
744352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
745352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
746636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg   return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1;
747636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#endif /* XCB_DRI2_MINOR_VERSION >= 3 */
748352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
749352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund}
750352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
7512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
7522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
7532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
754f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
7552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
7562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
757352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   if (dri2_dpy->dri2) {
758352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund      return dri2_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1;
759f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
760f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      assert(dri2_dpy->swrast);
761352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund
762f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
763f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      return EGL_TRUE;
764f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
7652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
7662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
7682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
7692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			 EGLint numRects, const EGLint *rects)
7702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
7712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
7722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
7732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   EGLBoolean ret;
7742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_region_t region;
7752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_rectangle_t rectangles[16];
7762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   int i;
7772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (numRects > (int)ARRAY_SIZE(rectangles))
7792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return dri2_copy_region(drv, disp, draw, dri2_surf->region);
7802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   for (i = 0; i < numRects; i++) {
7822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      rectangles[i].x = rects[i * 4];
783e1cb50b15dbb75d1ba0fe184d05be7d302b058eeRobert Bragg      rectangles[i].y = dri2_surf->base.Height - rects[i * 4 + 1] - rects[i * 4 + 3];
7842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      rectangles[i].width = rects[i * 4 + 2];
7852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      rectangles[i].height = rects[i * 4 + 3];
7862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
7872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   region = xcb_generate_id(dri2_dpy->conn);
7892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles);
7902889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   ret = dri2_copy_region(drv, disp, draw, region);
7912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_xfixes_destroy_region(dri2_dpy->conn, region);
7922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return ret;
7942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
7952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
7962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic EGLBoolean
79771b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglunddri2_post_sub_buffer(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
79871b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund		     EGLint x, EGLint y, EGLint width, EGLint height)
79971b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund{
800d26890688fc4efdec64e8fef33b54049f9c690bfFredrik Höglund   const EGLint rect[4] = { x, y, width, height };
80171b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund
802eb7d1b9474b021769e2d1f1b64901c64130e53d8Chia-I Wu   if (x < 0 || y < 0 || width < 0 || height < 0)
803eb7d1b9474b021769e2d1f1b64901c64130e53d8Chia-I Wu      _eglError(EGL_BAD_PARAMETER, "eglPostSubBufferNV");
804eb7d1b9474b021769e2d1f1b64901c64130e53d8Chia-I Wu
80571b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund   return dri2_swap_buffers_region(drv, disp, draw, 1, rect);
80671b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund}
80771b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund
80871b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglundstatic EGLBoolean
809655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglunddri2_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
810655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund{
811655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund#if XCB_DRI2_MINOR_VERSION >= 3
812655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
813655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
814636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#endif
815655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
816655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   /* XXX Check vblank_mode here? */
817655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
818655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   if (interval > surf->Config->MaxSwapInterval)
819655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund      interval = surf->Config->MaxSwapInterval;
820655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   else if (interval < surf->Config->MinSwapInterval)
821655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund      interval = surf->Config->MinSwapInterval;
822655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
823636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#if XCB_DRI2_MINOR_VERSION >= 3
824655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   if (interval != surf->SwapInterval && dri2_dpy->swap_available)
825655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund      xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval);
826636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#endif
827655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
828655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   surf->SwapInterval = interval;
829655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
830655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   return EGL_TRUE;
831655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund}
832655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
833655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglundstatic EGLBoolean
8342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
8352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  EGLNativePixmapType target)
8362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
8372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
8382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
8392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_gcontext_t gc;
8402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) drv;
8422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
8442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   gc = xcb_generate_id(dri2_dpy->conn);
8462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL);
8472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_copy_area(dri2_dpy->conn,
8482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  dri2_surf->drawable,
8492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  target,
8502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  gc,
8512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  0, 0,
8522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  0, 0,
8532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  dri2_surf->base.Width,
8542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		  dri2_surf->base.Height);
8552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_free_gc(dri2_dpy->conn, gc);
8562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
8582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
8592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLImage *
8612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
8622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			     EGLClientBuffer buffer, const EGLint *attr_list)
8632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
8642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
8652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_image *dri2_img;
8662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   unsigned int attachments[1];
8672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_drawable_t drawable;
8682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_cookie_t buffers_cookie;
8692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_get_buffers_reply_t *buffers_reply;
8702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_dri2_buffer_t *buffers;
8712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_get_geometry_cookie_t geometry_cookie;
8722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_get_geometry_reply_t *geometry_reply;
8732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_generic_error_t *error;
8742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   int stride, format;
8752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) ctx;
8772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8786a661895e946f38b21775bf9cb45ef6b22fab85aJosé Fonseca   drawable = (xcb_drawable_t) (uintptr_t) buffer;
8792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   xcb_dri2_create_drawable (dri2_dpy->conn, drawable);
8802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT;
8812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   buffers_cookie =
8822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
8832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg				      drawable, 1, 1, attachments);
8842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable);
8852889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn,
8862889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					       buffers_cookie, NULL);
8872889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   buffers = xcb_dri2_get_buffers_buffers (buffers_reply);
8882889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (buffers == NULL) {
8892889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
8902889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
8912889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
8922889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn,
8932889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					    geometry_cookie, &error);
8942889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (geometry_reply == NULL || error != NULL) {
8952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
8962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(error);
8972889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(buffers_reply);
898bf0c56522e21bd45ad3385e3115ef7eb71a7b8bfChia-I Wu      return NULL;
8992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
9002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   switch (geometry_reply->depth) {
9022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   case 16:
9032889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      format = __DRI_IMAGE_FORMAT_RGB565;
9042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      break;
9052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   case 24:
9062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      format = __DRI_IMAGE_FORMAT_XRGB8888;
9072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      break;
9082889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   case 32:
9092889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      format = __DRI_IMAGE_FORMAT_ARGB8888;
9102889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      break;
9112889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   default:
9122889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglError(EGL_BAD_PARAMETER,
9132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg		"dri2_create_image_khr: unsupported pixmap depth");
9142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(buffers_reply);
9152889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(geometry_reply);
9162889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return NULL;
9172889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
9182889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9192889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_img = malloc(sizeof *dri2_img);
9202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!dri2_img) {
9212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(buffers_reply);
9222889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(geometry_reply);
9232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
9242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_NO_IMAGE_KHR;
9252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
9262889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9272889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!_eglInitImage(&dri2_img->base, disp)) {
9282889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(buffers_reply);
9292889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      free(geometry_reply);
930f747d03b1d3aa4e63417bd8486909f63b4a33be4Völgyes Dávid      free(dri2_img);
9312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return EGL_NO_IMAGE_KHR;
9322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
9332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   stride = buffers[0].pitch / buffers[0].cpp;
9352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_img->dri_image =
9362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
9372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   buffers_reply->width,
9382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   buffers_reply->height,
9392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   format,
9402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   buffers[0].name,
9412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   stride,
9422889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg					   dri2_img);
9432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9442889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(buffers_reply);
9452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(geometry_reply);
9462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return &dri2_img->base;
9482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
9492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergstatic _EGLImage *
9512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsbergdri2_x11_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
9522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			  _EGLContext *ctx, EGLenum target,
9532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg			  EGLClientBuffer buffer, const EGLint *attr_list)
9542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
9552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   (void) drv;
9562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
9572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   switch (target) {
9582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   case EGL_NATIVE_PIXMAP_KHR:
9592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
9602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   default:
9612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
9622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
9632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
9642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
965f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic EGLBoolean
966f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengdri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
967f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
968f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   struct dri2_egl_display *dri2_dpy;
969f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
970f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CreateWindowSurface = dri2_create_window_surface;
971f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
972f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
973f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.DestroySurface = dri2_destroy_surface;
974f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.SwapBuffers = dri2_swap_buffers;
975f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CopyBuffers = dri2_copy_buffers;
976f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
977f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.SwapBuffersRegionNOK = NULL;
978f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CreateImageKHR  = NULL;
979f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.DestroyImageKHR = NULL;
980f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.CreateDRMImageMESA = NULL;
981f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   drv->API.ExportDRMImageMESA = NULL;
982f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
983f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy = malloc(sizeof *dri2_dpy);
984f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (!dri2_dpy)
985f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
986f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
987f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   memset(dri2_dpy, 0, sizeof *dri2_dpy);
988f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
989f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   disp->DriverData = (void *) dri2_dpy;
990f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (disp->PlatformDisplay == NULL) {
991f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      dri2_dpy->conn = xcb_connect(0, 0);
992f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
993f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
994f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
995f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
996f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (xcb_connection_has_error(dri2_dpy->conn)) {
997f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
998f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      goto cleanup_dpy;
999f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
1000f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1001cf69eeacc6931e833e7894a379af4fae085881e9Chia-I Wu   if (!dri2_load_driver_swrast(disp))
1002f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      goto cleanup_conn;
1003f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1004f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
1005f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
1006f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
1007f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
1008f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
1009f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1010f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
1011f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->extensions[1] = NULL;
1012f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->extensions[2] = NULL;
1013f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1014f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (!dri2_create_screen(disp))
1015f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      goto cleanup_driver;
1016f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1017f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (dri2_dpy->conn) {
1018f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
1019f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         goto cleanup_configs;
1020f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
1021f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1022f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   /* we're supporting EGL 1.4 */
1023f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   disp->VersionMajor = 1;
1024f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   disp->VersionMinor = 4;
1025f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1026f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   return EGL_TRUE;
1027f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1028f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng cleanup_configs:
1029f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   _eglCleanupDisplay(disp);
1030f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
1031f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng cleanup_driver:
1032f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   dlclose(dri2_dpy->driver);
1033f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng cleanup_conn:
1034f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (disp->PlatformDisplay == NULL)
1035f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      xcb_disconnect(dri2_dpy->conn);
1036f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng cleanup_dpy:
1037f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   free(dri2_dpy);
1038f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1039f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   return EGL_FALSE;
1040f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
1041f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1042f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1043f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengstatic EGLBoolean
1044f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengdri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
10452889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg{
10462889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy;
10472889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
10482889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.CreateWindowSurface = dri2_create_window_surface;
10492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
10502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
10512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.DestroySurface = dri2_destroy_surface;
10522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.SwapBuffers = dri2_swap_buffers;
10532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.CopyBuffers = dri2_copy_buffers;
10542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.CreateImageKHR = dri2_x11_create_image_khr;
10552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   drv->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
105671b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund   drv->API.PostSubBufferNV = dri2_post_sub_buffer;
1057655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   drv->API.SwapInterval = dri2_swap_interval;
10582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
10592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy = malloc(sizeof *dri2_dpy);
10602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!dri2_dpy)
10612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
10622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1063f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   memset(dri2_dpy, 0, sizeof *dri2_dpy);
1064f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
10652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->DriverData = (void *) dri2_dpy;
10662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (disp->PlatformDisplay == NULL) {
10672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_dpy->conn = xcb_connect(0, 0);
10682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   } else {
10692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
10702889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
10712889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
10722889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (xcb_connection_has_error(dri2_dpy->conn)) {
10732889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
10742889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_dpy;
10752889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
10762889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
10772889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->conn) {
10782889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      if (!dri2_connect(dri2_dpy))
10792889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 goto cleanup_conn;
10802889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
10812889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
10822889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!dri2_load_driver(disp))
10832889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_conn;
10842889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1085b60120608f6ddf4098bc324363197c979ee04cb7David Fries#ifdef O_CLOEXEC
108655a629cee5c20b357cca5c767a14fb27d9691e16Kristian Høgsberg   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
1087b60120608f6ddf4098bc324363197c979ee04cb7David Fries   if (dri2_dpy->fd == -1 && errno == EINVAL)
1088b60120608f6ddf4098bc324363197c979ee04cb7David Fries#endif
1089b60120608f6ddf4098bc324363197c979ee04cb7David Fries   {
1090b60120608f6ddf4098bc324363197c979ee04cb7David Fries      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
1091b60120608f6ddf4098bc324363197c979ee04cb7David Fries      if (dri2_dpy->fd != -1)
1092b60120608f6ddf4098bc324363197c979ee04cb7David Fries         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
1093b60120608f6ddf4098bc324363197c979ee04cb7David Fries            FD_CLOEXEC);
1094b60120608f6ddf4098bc324363197c979ee04cb7David Fries   }
10952889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->fd == -1) {
10962889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      _eglLog(_EGL_WARNING,
10972889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	      "DRI2: could not open %s (%s)", dri2_dpy->device_name,
10982889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg              strerror(errno));
10992889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_driver;
11002889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
11012889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11022889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->conn) {
11036b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      if (!dri2_authenticate(disp))
11042889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 goto cleanup_fd;
11052889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
11062889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11072889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->dri2_minor >= 1) {
11083104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
11093104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.base.version = 3;
11103104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
11113104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
11123104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
11132889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 dri2_get_buffers_with_format;
11142889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   } else {
11153104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
11163104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.base.version = 2;
11173104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
11183104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
11193104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng      dri2_dpy->dri2_loader_extension.getBuffersWithFormat = NULL;
11202889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
11212889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11223104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
11232889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->extensions[1] = &image_lookup_extension.base;
11242889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->extensions[2] = NULL;
11252889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
1126636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#if XCB_DRI2_MINOR_VERSION >= 3
1127655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund   dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2);
1128352c889c10d8d104551ef6657e03b77996bffc39Fredrik Höglund   dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3);
1129636f2fc46c83d471b60b96bca1ced0c78b3415b5Kristian Høgsberg#endif
1130655f2c1d6593064b83f64a527798f48cd300fa16Fredrik Höglund
11312889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (!dri2_create_screen(disp))
11322889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      goto cleanup_fd;
11332889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11342889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (dri2_dpy->conn) {
11352889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
11362889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg	 goto cleanup_configs;
11372889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   }
11382889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11392889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
11402889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->Extensions.NOK_swap_region = EGL_TRUE;
11412889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
114271b8fc9872077d30307329b27ffc135d2d460dc9Fredrik Höglund   disp->Extensions.NV_post_sub_buffer = EGL_TRUE;
11432889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11446b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#ifdef HAVE_WAYLAND_PLATFORM
11456b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
11466b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#endif
11476b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   dri2_dpy->authenticate = dri2_x11_authenticate;
11486b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
11492889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   /* we're supporting EGL 1.4 */
11502889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->VersionMajor = 1;
11512889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   disp->VersionMinor = 4;
11522889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11532889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_TRUE;
11542889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11552889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_configs:
11562889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   _eglCleanupDisplay(disp);
11572889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
11582889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_fd:
11592889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   close(dri2_dpy->fd);
11602889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_driver:
11612889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   dlclose(dri2_dpy->driver);
11622889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_conn:
11632889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   if (disp->PlatformDisplay == NULL)
11642889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg      xcb_disconnect(dri2_dpy->conn);
11652889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg cleanup_dpy:
11662889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   free(dri2_dpy);
11672889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg
11682889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg   return EGL_FALSE;
11692889d9640fa98b690c6a89593572bbc9ea5640e3Kristian Høgsberg}
1170f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1171f55d027ac2e0423eba5d0664cc36668520597703Haitao FengEGLBoolean
1172f55d027ac2e0423eba5d0664cc36668520597703Haitao Fengdri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
1173f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng{
1174f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   EGLBoolean initialized = EGL_TRUE;
1175f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1176f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   int x11_dri2_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
1177f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1178f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   if (x11_dri2_accel) {
1179f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      if (!dri2_initialize_x11_dri2(drv, disp)) {
1180f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng         initialized = dri2_initialize_x11_swrast(drv, disp);
1181f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      }
1182f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   } else {
1183f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng      initialized = dri2_initialize_x11_swrast(drv, disp);
1184f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   }
1185f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1186f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   return initialized;
1187f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng}
1188f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
1189