platform_wayland.c revision 56758c839ff29bd168529535a4816bff3b79cde5
1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2011 Intel Corporation
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch * copy of this software and associated documentation files (the "Software"),
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to deal in the Software without restriction, including without limitation
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * the rights to use, copy, modify, merge, publish, distribute, sublicense,
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software is furnished to do so, subject to the following conditions:
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the next
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * paragraph) shall be included in all copies or substantial portions of the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DEALINGS IN THE SOFTWARE.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Authors:
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *    Kristian Høgsberg <krh@bitplanet.net>
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *    Benjamin Franzke <benjaminfranzke@googlemail.com>
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <stdlib.h>
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string.h>
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <limits.h>
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <dlfcn.h>
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <errno.h>
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <unistd.h>
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "egl_dri2.h"
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/**
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static _EGLSurface *
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		    _EGLConfig *conf, EGLNativeWindowType window,
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		    const EGLint *attrib_list)
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles){
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct dri2_egl_surface *dri2_surf;
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct dri2_egl_buffer *dri2_buf;
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   int i;
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   (void) drv;
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   dri2_surf = malloc(sizeof *dri2_surf);
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   if (!dri2_surf) {
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return NULL;
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   }
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      goto cleanup_surf;
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   for (i = 0; i < WL_BUFFER_COUNT; ++i)
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->wl_drm_buffer[i] = NULL;
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->dri_buffers[i] = NULL;
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   dri2_surf->block_swap_buffers = EGL_FALSE;
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   switch (type) {
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   case EGL_WINDOW_BIT:
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->wl_win = (struct wl_egl_window *) window;
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->type = DRI2_WINDOW_SURFACE;
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->base.Width =  -1;
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->base.Height = -1;
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   case EGL_PIXMAP_BIT:
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->wl_pix = (struct wl_egl_pixmap *) window;
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->type = DRI2_PIXMAP_SURFACE;
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->base.Width  = dri2_surf->wl_pix->width;
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_surf->base.Height = dri2_surf->wl_pix->height;
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (dri2_surf->wl_pix->name > 0) {
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         dri2_buf = dri2_surf->wl_pix->driver_private;
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_buf->dri_buffer;
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   default:
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      goto cleanup_surf;
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   }
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   dri2_surf->dri_drawable =
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)					    dri2_conf->dri_config, dri2_surf);
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   if (dri2_surf->dri_drawable == NULL) {
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      goto cleanup_dri_drawable;
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   }
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   return &dri2_surf->base;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cleanup_dri_drawable:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cleanup_surf:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   free(dri2_surf);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return NULL;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static _EGLSurface *
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   _EGLConfig *conf, EGLNativeWindowType window,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   const EGLint *attrib_list)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			      window, attrib_list);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static _EGLSurface *
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   _EGLConfig *conf, EGLNativePixmapType pixmap,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   const EGLint *attrib_list)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch			      pixmap, attrib_list);
132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called via eglDestroySurface(), drv->API.DestroySurface().
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static EGLBoolean
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   int i;
143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   (void) drv;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (!_eglPutSurface(surf))
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return EGL_TRUE;
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   for (i = 0; i < WL_BUFFER_COUNT; ++i)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (dri2_surf->wl_drm_buffer[i])
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dri2_surf->dri_buffers[i] && !(i == __DRI_BUFFER_FRONT_LEFT &&
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          dri2_surf->type == DRI2_PIXMAP_SURFACE))
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       dri2_surf->dri_buffers[i]);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   free(surf);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return EGL_TRUE;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct dri2_egl_buffer *dri2_buf = egl_pixmap->driver_private;
170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   assert(dri2_buf);
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   dri2_buf->dri2_dpy->dri2->releaseBuffer(dri2_buf->dri2_dpy->dri_screen,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           dri2_buf->dri_buffer);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   free(dri2_buf);
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   egl_pixmap->driver_private = NULL;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   egl_pixmap->destroy = NULL;
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   egl_pixmap->name = 0;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_process_front_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy =
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_egl_display(dri2_surf->base.Resource.Display);
188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   struct dri2_egl_buffer *dri2_buf;
189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   /* allocate a back buffer for our double-buffered window*/
191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   switch (dri2_surf->type) {
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)   case DRI2_WINDOW_SURFACE:
193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT] =
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               __DRI_BUFFER_BACK_LEFT, format,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               dri2_surf->base.Width, dri2_surf->base.Height);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case DRI2_PIXMAP_SURFACE:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_buf = malloc(sizeof *dri2_buf);
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!dri2_buf)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         return;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_buf->dri_buffer = dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT];
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_buf->dri2_dpy   = dri2_dpy;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_pix->name           = dri2_buf->dri_buffer->name;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_pix->stride         = dri2_buf->dri_buffer->pitch;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_pix->driver_private = dri2_buf;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_pix->destroy        = dri2_wl_egl_pixmap_destroy;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static __DRIbuffer *
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch			     int *width, int *height,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     unsigned int *attachments, int count,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     int *out_count, void *loaderPrivate)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   struct dri2_egl_surface *dri2_surf = loaderPrivate;
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy =
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_egl_display(dri2_surf->base.Resource.Display);
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   int i;
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   if (dri2_surf->type == DRI2_WINDOW_SURFACE &&
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         if (dri2_surf->dri_buffers[i]) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  dri2_surf->dri_buffers[i]);
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            dri2_surf->dri_buffers[i] = NULL;
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         }
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->base.Width  = dri2_surf->wl_win->width;
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->base.Height = dri2_surf->wl_win->height;
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->dx = dri2_surf->wl_win->dx;
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->dy = dri2_surf->wl_win->dy;
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      for (i = 0; i < WL_BUFFER_COUNT; ++i) {
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         if (dri2_surf->wl_drm_buffer[i])
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         dri2_surf->wl_drm_buffer[i]  = NULL;
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   dri2_surf->buffer_count = 0;
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   for (i = 0; i < 2*count; i+=2) {
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      assert(attachments[i] < __DRI_BUFFER_COUNT);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert(dri2_surf->buffer_count < 5);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         dri2_surf->dri_buffers[attachments[i]] =
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  attachments[i], attachments[i+1],
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  dri2_surf->base.Width, dri2_surf->base.Height);
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         if (!dri2_surf->dri_buffers[attachments[i]])
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            continue;
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         if (attachments[i] == __DRI_BUFFER_FRONT_LEFT)
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            dri2_process_front_buffer(dri2_surf, attachments[i+1]);
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)             dri2_surf->dri_buffers[attachments[i]],
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)             sizeof(__DRIbuffer));
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      dri2_surf->buffer_count++;
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   }
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   assert(dri2_surf->type == DRI2_PIXMAP_SURFACE ||
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   *out_count = dri2_surf->buffer_count;
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   if (dri2_surf->buffer_count == 0)
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	   return NULL;
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   *width = dri2_surf->base.Width;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *height = dri2_surf->base.Height;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   return dri2_surf->buffers;
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static __DRIbuffer *
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)dri2_get_buffers(__DRIdrawable * driDrawable,
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		 int *width, int *height,
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		 unsigned int *attachments, int count,
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		 int *out_count, void *loaderPrivate)
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles){
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   unsigned int *attachments_with_format;
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   __DRIbuffer *buffer;
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   const unsigned int format = 32;
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   int i;
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   if (!attachments_with_format) {
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      *out_count = 0;
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return NULL;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   for (i = 0; i < count; ++i) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attachments_with_format[2*i] = attachments[i];
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      attachments_with_format[2*i + 1] = format;
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   buffer =
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dri2_get_buffers_with_format(driDrawable,
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				   width, height,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   attachments_with_format, count,
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)				   out_count, loaderPrivate);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   free(attachments_with_format);
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   return buffer;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static void
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles){
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   (void) driDrawable;
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   /* FIXME: Does EGL support front buffer rendering at all? */
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if 0
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   struct dri2_egl_surface *dri2_surf = loaderPrivate;
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   dri2WaitGL(dri2_surf);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   (void) loaderPrivate;
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static struct wl_buffer *
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)wayland_create_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy =
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dri2_egl_display(dri2_surf->base.Resource.Display);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return wl_drm_create_buffer(dri2_dpy->wl_dpy->drm, buffer->name,
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               dri2_surf->base.Width, dri2_surf->base.Height,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               buffer->pitch, dri2_surf->wl_win->visual);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wayland_frame_callback(void *data, uint32_t time)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct dri2_egl_surface *dri2_surf = data;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   dri2_surf->block_swap_buffers = EGL_FALSE;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void
359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochpointer_swap(const void **p1, const void **p2)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   const void *tmp = *p1;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *p1 = *p2;
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch   *p2 = tmp;
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Called via eglSwapBuffers(), drv->API.SwapBuffers().
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static EGLBoolean
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   while (dri2_surf->block_swap_buffers)
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      wl_display_iterate(dri2_dpy->wl_dpy->display, WL_DISPLAY_READABLE);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   dri2_surf->block_swap_buffers = EGL_TRUE;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   wl_display_frame_callback(dri2_dpy->wl_dpy->display,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 wayland_frame_callback, dri2_surf);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dri2_surf->type == DRI2_WINDOW_SURFACE) {
384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      pointer_swap(
385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 __DRI_BUFFER_FRONT_LEFT;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 __DRI_BUFFER_BACK_LEFT;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pointer_swap((const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_BACK]);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    wayland_create_buffer(dri2_surf,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		  dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wl_surface_attach(dri2_surf->wl_win->surface,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    dri2_surf->dx, dri2_surf->dy);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* reset resize growing parameters */
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->dx = 0;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dri2_surf->dy = 0;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    dri2_surf->base.Width, dri2_surf->base.Height);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   _EGLContext *ctx;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (dri2_drv->glFlush) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx = _eglGetCurrentContext();
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ctx && ctx->DrawSurface == &dri2_surf->base)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         dri2_drv->glFlush();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   return EGL_TRUE;
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/**
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * Called via eglCreateImageKHR(), drv->API.CreateImageKHR().
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static _EGLImage *
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)			     EGLClientBuffer buffer, const EGLint *attr_list)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   struct wl_egl_pixmap *wl_egl_pixmap = (struct wl_egl_pixmap *) buffer;
437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   struct dri2_egl_buffer *dri2_buf;
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   EGLint wl_attr_list[] = {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		EGL_WIDTH,		0,
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		EGL_HEIGHT,		0,
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		EGL_DRM_BUFFER_STRIDE_MESA,	0,
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		EGL_NONE
444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   };
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   dri2_buf = malloc(sizeof *dri2_buf);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (!dri2_buf)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           return NULL;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   dri2_buf->dri2_dpy = dri2_dpy;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   dri2_buf->dri_buffer =
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)				     __DRI_BUFFER_FRONT_LEFT, 32,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     wl_egl_pixmap->width,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     wl_egl_pixmap->height);
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   wl_egl_pixmap->name    = dri2_buf->dri_buffer->name;
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   wl_egl_pixmap->stride  = dri2_buf->dri_buffer->pitch;
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   wl_egl_pixmap->destroy = dri2_wl_egl_pixmap_destroy;
460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   wl_egl_pixmap->driver_private = dri2_buf;
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   wl_attr_list[1] = wl_egl_pixmap->width;
463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   wl_attr_list[3] = wl_egl_pixmap->height;
464f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   wl_attr_list[5] = wl_egl_pixmap->stride / 4;
465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   return dri2_create_image_khr(disp->Driver, disp, ctx, EGL_DRM_BUFFER_MESA,
468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	       (EGLClientBuffer)(intptr_t) wl_egl_pixmap->name, wl_attr_list);
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static _EGLImage *
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)dri2_wayland_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			      _EGLContext *ctx, EGLenum target,
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)			      EGLClientBuffer buffer, const EGLint *attr_list)
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   (void) drv;
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   switch (target) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   case EGL_NATIVE_PIXMAP_KHR:
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   default:
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called via eglTerminate(), drv->API.Terminate().
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static EGLBoolean
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   _eglReleaseDisplayResources(drv, disp);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   _eglCleanupDisplay(disp);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
498   close(dri2_dpy->fd);
499   dlclose(dri2_dpy->driver);
500   free(dri2_dpy->driver_name);
501   free(dri2_dpy);
502   disp->DriverData = NULL;
503
504   return EGL_TRUE;
505}
506
507static void
508sync_callback(void *data)
509{
510   int *done = data;
511
512   *done = 1;
513}
514
515static void
516force_roundtrip(struct wl_display *display)
517{
518   int done = 0;
519
520   wl_display_sync_callback(display, sync_callback, &done);
521   wl_display_iterate(display, WL_DISPLAY_WRITABLE);
522   while (!done)
523      wl_display_iterate(display, WL_DISPLAY_READABLE);
524}
525
526EGLBoolean
527dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
528{
529   struct dri2_egl_display *dri2_dpy;
530   int i;
531
532   drv->API.CreateWindowSurface = dri2_create_window_surface;
533   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
534   drv->API.DestroySurface = dri2_destroy_surface;
535   drv->API.SwapBuffers = dri2_swap_buffers;
536   drv->API.CreateImageKHR = dri2_wayland_create_image_khr;
537   drv->API.Terminate = dri2_terminate;
538
539   dri2_dpy = malloc(sizeof *dri2_dpy);
540   if (!dri2_dpy)
541      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
542
543   disp->DriverData = (void *) dri2_dpy;
544   dri2_dpy->wl_dpy = disp->PlatformDisplay;
545
546   if (dri2_dpy->wl_dpy->fd == -1)
547      force_roundtrip(dri2_dpy->wl_dpy->display);
548   if (dri2_dpy->wl_dpy->fd == -1)
549      goto cleanup_dpy;
550
551   dri2_dpy->fd = dup(dri2_dpy->wl_dpy->fd);
552   if (dri2_dpy->fd < 0) {
553      _eglError(EGL_BAD_ALLOC, "DRI2: failed to dup fd");
554      goto cleanup_dpy;
555   }
556
557   if (!dri2_dpy->wl_dpy->authenticated)
558      force_roundtrip(dri2_dpy->wl_dpy->display);
559   if (!dri2_dpy->wl_dpy->authenticated)
560      goto cleanup_dpy;
561
562   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
563   if (dri2_dpy->driver_name == NULL) {
564      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
565      goto cleanup_fd;
566   }
567
568   if (!dri2_load_driver(disp))
569      goto cleanup_driver_name;
570
571   dri2_dpy->loader_extension.base.name = __DRI_DRI2_LOADER;
572   dri2_dpy->loader_extension.base.version = 3;
573   dri2_dpy->loader_extension.getBuffers = dri2_get_buffers;
574   dri2_dpy->loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
575   dri2_dpy->loader_extension.getBuffersWithFormat =
576      dri2_get_buffers_with_format;
577
578   dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base;
579   dri2_dpy->extensions[1] = &image_lookup_extension.base;
580   dri2_dpy->extensions[2] = NULL;
581
582   if (!dri2_create_screen(disp))
583      goto cleanup_driver;
584
585   for (i = 0; dri2_dpy->driver_configs[i]; i++)
586      dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0,
587		      EGL_WINDOW_BIT | EGL_PIXMAP_BIT);
588
589
590   disp->Extensions.MESA_drm_image = EGL_TRUE;
591   disp->Extensions.KHR_image_base = EGL_TRUE;
592   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
593   disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
594   disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
595
596   /* we're supporting EGL 1.4 */
597   disp->VersionMajor = 1;
598   disp->VersionMinor = 4;
599
600   return EGL_TRUE;
601
602 cleanup_driver:
603   dlclose(dri2_dpy->driver);
604 cleanup_driver_name:
605   free(dri2_dpy->driver_name);
606 cleanup_fd:
607   close(dri2_dpy->fd);
608 cleanup_dpy:
609   free(dri2_dpy);
610
611   return EGL_FALSE;
612}
613