platform_wayland.c revision f2da7e720f60e8df96bf2530f35e3e79897e0cb7
193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/*
293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Copyright © 2011 Intel Corporation
393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Permission is hereby granted, free of charge, to any person obtaining a
593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * copy of this software and associated documentation files (the "Software"),
693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * to deal in the Software without restriction, including without limitation
793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * the rights to use, copy, modify, merge, publish, distribute, sublicense,
893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * and/or sell copies of the Software, and to permit persons to whom the
993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software is furnished to do so, subject to the following conditions:
1093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * The above copyright notice and this permission notice (including the next
1293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * paragraph) shall be included in all copies or substantial portions of the
1393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software.
1493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * DEALINGS IN THE SOFTWARE.
2393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
2493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Authors:
2593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Kristian Høgsberg <krh@bitplanet.net>
2693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Benjamin Franzke <benjaminfranzke@googlemail.com>
2793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
2893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
2993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <stdlib.h>
3093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <string.h>
3193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <limits.h>
3293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <dlfcn.h>
3393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <errno.h>
3493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <unistd.h>
35c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <fcntl.h>
36c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <xf86drm.h>
3793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
3893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include "egl_dri2.h"
3993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
406b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include <wayland-client.h>
416b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include "wayland-drm-client-protocol.h"
426b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
437b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergenum wl_drm_format_flags {
4458dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   HAS_ARGB8888 = 1,
4558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   HAS_XRGB8888 = 2
467b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg};
477b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
4851f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
49a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergsync_callback(void *data, struct wl_callback *callback, uint32_t serial)
50a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg{
51a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   int *done = data;
52a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
53a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   *done = 1;
54a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_callback_destroy(callback);
55a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg}
56a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
57a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergstatic const struct wl_callback_listener sync_listener = {
58a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   sync_callback
59a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg};
60a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
61a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergstatic int
62a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergroundtrip(struct dri2_egl_display *dri2_dpy)
63a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg{
64a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   struct wl_callback *callback;
65a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   int done = 0, ret = 0;
66a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
67a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   callback = wl_display_sync(dri2_dpy->wl_dpy);
68a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_callback_add_listener(callback, &sync_listener, &done);
69a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) callback, dri2_dpy->wl_queue);
70a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   while (ret != -1 && !done)
71a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
72a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
73f2da7e720f60e8df96bf2530f35e3e79897e0cb7Jonas Ådahl   if (!done)
74f2da7e720f60e8df96bf2530f35e3e79897e0cb7Jonas Ådahl      wl_callback_destroy(callback);
75f2da7e720f60e8df96bf2530f35e3e79897e0cb7Jonas Ådahl
76a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   return ret;
77a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg}
78a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
79a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergstatic void
800cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkewl_buffer_release(void *data, struct wl_buffer *buffer)
810cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
820cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int i;
840cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
850cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
860cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      if (dri2_surf->wl_drm_buffer[i] == buffer)
870cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
880cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
890cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   assert(i <= WL_BUFFER_COUNT);
900cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
910cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   /* not found? */
920cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (i == WL_BUFFER_COUNT)
930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
940cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
950cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[i] = 0;
960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
990cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic struct wl_buffer_listener wl_buffer_listener = {
1000cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   wl_buffer_release
1010cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke};
10251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
103eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveirastatic void
104eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveiraresize_callback(struct wl_egl_window *wl_win, void *data)
105eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira{
106eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira   struct dri2_egl_surface *dri2_surf = data;
107eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira   struct dri2_egl_display *dri2_dpy =
108eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira      dri2_egl_display(dri2_surf->base.Resource.Display);
109eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira
110eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
111eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira}
112eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira
11393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
11493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
11593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
11693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
11793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
11893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    _EGLConfig *conf, EGLNativeWindowType window,
11993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    const EGLint *attrib_list)
12093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
12193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
12293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
12393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf;
12493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
12593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
12793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf = malloc(sizeof *dri2_surf);
12993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_surf) {
13093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
13193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
13293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
13393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
13593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
13693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1370cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i) {
13893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_drm_buffer[i] = NULL;
1390cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->wl_buffer_lock[i] = 0;
1400cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
14193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
14293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
14393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[i] = NULL;
14493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
14551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
1460cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->third_buffer = NULL;
147a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   dri2_surf->frame_callback = NULL;
14893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1497b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   if (conf->AlphaSize == 0)
15058dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
1517b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   else
15258dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
1537b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
15493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (type) {
15593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_WINDOW_BIT:
15693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win = (struct wl_egl_window *) window;
15793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
158eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira      dri2_surf->wl_win->private = dri2_surf;
159eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira      dri2_surf->wl_win->resize_callback = resize_callback;
160eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira
16193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width =  -1;
16293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = -1;
16393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
16493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
16593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
16693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
16793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
16893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->dri_drawable =
16993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
17087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    type == EGL_WINDOW_BIT ?
17187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_double_config :
17287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_single_config,
17387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_surf);
17493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->dri_drawable == NULL) {
17593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
17693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dri_drawable;
17793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
17893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return &dri2_surf->base;
18093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dri_drawable:
18293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
18393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_surf:
18493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_surf);
18593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return NULL;
18793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
18893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
19093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
19193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
19293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
19393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
19493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativeWindowType window,
19593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
19693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
19793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
19893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      window, attrib_list);
19993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
20093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
20293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglDestroySurface(), drv->API.DestroySurface().
20393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
20493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
20593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
20693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
20793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
20893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
20993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
21093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
21293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglPutSurface(surf))
21493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return EGL_TRUE;
21593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
21793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
21993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->wl_drm_buffer[i])
22093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
22193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
22293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
2232a81037439afb04d4170f674646cdae59619707dKristian Høgsberg      if (dri2_surf->dri_buffers[i])
22493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
22593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                       dri2_surf->dri_buffers[i]);
22693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
2270cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer) {
2280cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
2290cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                    dri2_surf->third_buffer);
2300cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
2310cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
2322332bc26d435e465a6f6571ab267db2a33ce05d2Jonas Ådahl   if (dri2_surf->frame_callback)
2332332bc26d435e465a6f6571ab267db2a33ce05d2Jonas Ådahl      wl_callback_destroy(dri2_surf->frame_callback);
2342332bc26d435e465a6f6571ab267db2a33ce05d2Jonas Ådahl
235eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira
236eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
237eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira      dri2_surf->wl_win->private = NULL;
238eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira      dri2_surf->wl_win->resize_callback = NULL;
239eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira   }
240eaf6884621661288624fc060974c3aa485771324Ander Conselvan de Oliveira
24193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(surf);
24293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
24393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
24493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
24593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
246f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzkestatic struct wl_buffer *
247f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzkewayland_create_buffer(struct dri2_egl_surface *dri2_surf,
2487b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg                      __DRIbuffer *buffer)
249f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke{
250f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
251f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
2520cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct wl_buffer *buf;
253f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
2540cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
2550cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                              dri2_surf->base.Width, dri2_surf->base.Height,
2567b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg                              buffer->pitch, dri2_surf->format);
2570cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf);
2580cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
2590cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   return buf;
260f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke}
261f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
26293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
26387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkedri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
26493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
26593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
26693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
26793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
26887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   (void) format;
26987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
270f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   switch (dri2_surf->base.Type) {
271f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   case EGL_WINDOW_BIT:
27287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      /* allocate a front buffer for our double-buffered window*/
2730cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL)
2740cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
27587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
27693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
27787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke               __DRI_BUFFER_FRONT_LEFT, format,
27893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke               dri2_surf->base.Width, dri2_surf->base.Height);
27993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
28087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   default:
28187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      break;
28287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   }
28387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke}
28487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
28587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkestatic void
2866602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergdri2_release_pending_buffer(void *data,
2876602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg			    struct wl_callback *callback, uint32_t time)
28851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
28951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
29051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
29151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
29251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
29351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   /* FIXME: print internal error */
29451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   if (!dri2_surf->pending_buffer)
29551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      return;
29651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
29751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
29851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                 dri2_surf->pending_buffer);
29951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
30011f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke
30111f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke   wl_callback_destroy(callback);
30251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
30351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3046602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergstatic const struct wl_callback_listener release_buffer_listener = {
3056602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   dri2_release_pending_buffer
3066602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
3076602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
30851f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
30951f2820922b669af3947fcedd17109524644bb94Benjamin Franzkedri2_release_buffers(struct dri2_egl_surface *dri2_surf)
31051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
31151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
31251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
3136602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   struct wl_callback *callback;
31451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int i;
31551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3160cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer) {
3170cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
3180cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                    dri2_surf->third_buffer);
3190cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->third_buffer = NULL;
3200cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
3210cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
32251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
32351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      if (dri2_surf->dri_buffers[i]) {
32451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         switch (i) {
32551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         case __DRI_BUFFER_FRONT_LEFT:
32651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            if (dri2_surf->pending_buffer)
327a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg               roundtrip(dri2_dpy);
32851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_surf->pending_buffer = dri2_surf->dri_buffers[i];
3296602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg            callback = wl_display_sync(dri2_dpy->wl_dpy);
3306602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	    wl_callback_add_listener(callback,
3316602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg				     &release_buffer_listener, dri2_surf);
332a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg            wl_proxy_set_queue((struct wl_proxy *) callback,
333a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg                               dri2_dpy->wl_queue);
33451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
33551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         default:
33651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
33751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                          dri2_surf->dri_buffers[i]);
33851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
33951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         }
34051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         dri2_surf->dri_buffers[i] = NULL;
34151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      }
34251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   }
34351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
34451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3450cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic inline void
3460cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkepointer_swap(const void **p1, const void **p2)
3470cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3480cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   const void *tmp = *p1;
3490cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   *p1 = *p2;
3500cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   *p2 = tmp;
3510cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3520cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3530cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3540cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkedestroy_third_buffer(struct dri2_egl_surface *dri2_surf)
3550cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3560cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
3570cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
3580cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3590cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer == NULL)
3600cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
3610cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3620cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
3630cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                 dri2_surf->third_buffer);
3640cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->third_buffer = NULL;
3650cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3660cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD])
3670cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]);
3680cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL;
3690cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0;
3700cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3710cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3720cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3730cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkeswap_wl_buffers(struct dri2_egl_surface *dri2_surf,
3740cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                enum wayland_buffer_type a, enum wayland_buffer_type b)
3750cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3760cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int tmp;
3770cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3780cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   tmp = dri2_surf->wl_buffer_lock[a];
3790cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b];
3800cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[b] = tmp;
3810cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3820cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a],
3830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                (const void **) &dri2_surf->wl_drm_buffer[b]);
3840cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3850cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3860cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3870cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkeswap_back_and_third(struct dri2_egl_surface *dri2_surf)
3880cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3890cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD])
3900cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      destroy_third_buffer(dri2_surf);
3910cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3920cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT],
3930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                (const void **) &dri2_surf->third_buffer);
3940cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3950cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD);
3960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3990cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkedri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf,
4000cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                           unsigned int type)
4010cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
4020cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   switch (type) {
4030cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   case __DRI_BUFFER_BACK_LEFT:
4040cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK])
4050cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke            swap_back_and_third(dri2_surf);
4060cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         else if (dri2_surf->third_buffer)
4070cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke            destroy_third_buffer(dri2_surf);
4080cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
4090cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   default:
4100cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
4110cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
4120cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
4130cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
4140cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
41593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
41693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers_with_format(__DRIdrawable * driDrawable,
41793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *width, int *height,
41893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     unsigned int *attachments, int count,
41993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *out_count, void *loaderPrivate)
42093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
42193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
42293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
42393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
42493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
42593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
426f9d8d0c3b5e11c4ae08b078dca2aa48a3218f8d9Ander Conselvan de Oliveira   /* There might be a buffer release already queued that wasn't processed */
427f9d8d0c3b5e11c4ae08b078dca2aa48a3218f8d9Ander Conselvan de Oliveira   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
428f9d8d0c3b5e11c4ae08b078dca2aa48a3218f8d9Ander Conselvan de Oliveira
429f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
43093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
43193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
43251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
43351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_release_buffers(dri2_surf);
43493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
43593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_win->width;
43693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_win->height;
43793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = dri2_surf->wl_win->dx;
43893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = dri2_surf->wl_win->dy;
43993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      for (i = 0; i < WL_BUFFER_COUNT; ++i) {
44193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (dri2_surf->wl_drm_buffer[i])
44293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
44393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->wl_drm_buffer[i]  = NULL;
4440cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         dri2_surf->wl_buffer_lock[i] = 0;
44593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
44693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
44793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->buffer_count = 0;
44993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < 2*count; i+=2) {
45093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(attachments[i] < __DRI_BUFFER_COUNT);
45193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(dri2_surf->buffer_count < 5);
45293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4530cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_prior_buffer_creation(dri2_surf, attachments[i]);
4540cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
45593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
45693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->dri_buffers[attachments[i]] =
45893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
45993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  attachments[i], attachments[i+1],
46093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  dri2_surf->base.Width, dri2_surf->base.Height);
46193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (!dri2_surf->dri_buffers[attachments[i]])
46393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            continue;
46493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4652a81037439afb04d4170f674646cdae59619707dKristian Høgsberg         if (attachments[i] == __DRI_BUFFER_BACK_LEFT)
46687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke            dri2_process_back_buffer(dri2_surf, attachments[i+1]);
46793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
46893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
47093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             dri2_surf->dri_buffers[attachments[i]],
47193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             sizeof(__DRIbuffer));
47293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->buffer_count++;
47493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
47593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4762a81037439afb04d4170f674646cdae59619707dKristian Høgsberg   assert(dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
477f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
47893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *out_count = dri2_surf->buffer_count;
47993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->buffer_count == 0)
48093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	   return NULL;
48193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *width = dri2_surf->base.Width;
48393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *height = dri2_surf->base.Height;
48493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_surf->buffers;
48693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
48793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
48993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers(__DRIdrawable * driDrawable,
49093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *width, int *height,
49193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 unsigned int *attachments, int count,
49293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *out_count, void *loaderPrivate)
49393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
49493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   unsigned int *attachments_with_format;
49593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   __DRIbuffer *buffer;
49693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   const unsigned int format = 32;
49793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
49893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
50093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!attachments_with_format) {
50193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      *out_count = 0;
50293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
50393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
50493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < count; ++i) {
50693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i] = attachments[i];
50793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i + 1] = format;
50893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
50993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
51093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   buffer =
51193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format(driDrawable,
51293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   width, height,
51393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   attachments_with_format, count,
51493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   out_count, loaderPrivate);
51593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
51693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(attachments_with_format);
51793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
51893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return buffer;
51993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
52093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
52393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
52493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
52593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) driDrawable;
52693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* FIXME: Does EGL support front buffer rendering at all? */
52893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#if 0
53093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
53193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2WaitGL(dri2_surf);
53393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#else
53493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) loaderPrivate;
53593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#endif
53693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
53793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
5396602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergwayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
54093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
54193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
54293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
543a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   dri2_surf->frame_callback = NULL;
5446602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_callback_destroy(callback);
54593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
54693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5476602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergstatic const struct wl_callback_listener frame_listener = {
5486602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	wayland_frame_callback
5496602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
5506602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
55193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
55293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglSwapBuffers(), drv->API.SwapBuffers().
55393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
55493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
55593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
55693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
55793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
55893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
55993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
560a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   int ret = 0;
56193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
562a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   while (dri2_surf->frame_callback && ret != -1)
563a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
564a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (ret < 0)
565a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      return EGL_FALSE;
56693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
567a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   dri2_surf->frame_callback = wl_surface_frame(dri2_surf->wl_win->surface);
568a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_callback_add_listener(dri2_surf->frame_callback,
569a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg                            &frame_listener, dri2_surf);
570a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) dri2_surf->frame_callback,
571a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg                      dri2_dpy->wl_queue);
57293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
573f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
57493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      pointer_swap(
57593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
57693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
57793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
57893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =
57993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_FRONT_LEFT;
58093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
58193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_BACK_LEFT;
58293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);
58493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
58593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
58693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
58793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    wayland_create_buffer(dri2_surf,
5887b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg		  dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
58993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
59093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_attach(dri2_surf->wl_win->surface,
59193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
59293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->dx, dri2_surf->dy);
5930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;
59493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
59593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
59693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
59793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      /* reset resize growing parameters */
59893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = 0;
59993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = 0;
60093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
60193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
60293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->base.Width, dri2_surf->base.Height);
603a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
604a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      wl_surface_commit(dri2_surf->wl_win->surface);
60593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
60693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
60793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _EGLContext *ctx;
60893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_drv->glFlush) {
60993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      ctx = _eglGetCurrentContext();
61093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (ctx && ctx->DrawSurface == &dri2_surf->base)
61193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_drv->glFlush();
61293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
61393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
61493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
615b49d9338d7e79752e886eede34db08e37c34f8edKristian Høgsberg   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
61693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
61793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
61893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
61993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6206b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
6216b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
6226b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
6236b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
6246b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
6256b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
626aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 0;
6276b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
628c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, id);
629a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (roundtrip(dri2_dpy) < 0)
630a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      ret = -1;
6316b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
632c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
6336b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
6346b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
6356b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /* reset authenticated */
636aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
6376b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
6386b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
6396b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
6406b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
64193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
64293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglTerminate(), drv->API.Terminate().
64393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
64493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
64593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
64693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
64793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
64893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
64993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglReleaseDisplayResources(drv, disp);
65093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglCleanupDisplay(disp);
65193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
65293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
65393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
65493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
65593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
6562a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   free(dri2_dpy->device_name);
6572a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   wl_drm_destroy(dri2_dpy->wl_drm);
6582a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   if (dri2_dpy->own_device)
659e6aa32ac7f8d7b843f4d4f8bf9d8e9db790b0868Benjamin Franzke      wl_display_disconnect(dri2_dpy->wl_dpy);
66093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
66193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = NULL;
66293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
66393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
66493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
66593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
666c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
667c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
668c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
669c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
670c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drm_magic_t magic;
671c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
672c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->device_name = strdup(device);
673c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->device_name)
674c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
675c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
676b60120608f6ddf4098bc324363197c979ee04cb7David Fries#ifdef O_CLOEXEC
677b60120608f6ddf4098bc324363197c979ee04cb7David Fries   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
678b60120608f6ddf4098bc324363197c979ee04cb7David Fries   if (dri2_dpy->fd == -1 && errno == EINVAL)
679b60120608f6ddf4098bc324363197c979ee04cb7David Fries#endif
680b60120608f6ddf4098bc324363197c979ee04cb7David Fries   {
681b60120608f6ddf4098bc324363197c979ee04cb7David Fries      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
682b60120608f6ddf4098bc324363197c979ee04cb7David Fries      if (dri2_dpy->fd != -1)
683b60120608f6ddf4098bc324363197c979ee04cb7David Fries         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
684b60120608f6ddf4098bc324363197c979ee04cb7David Fries            FD_CLOEXEC);
685b60120608f6ddf4098bc324363197c979ee04cb7David Fries   }
686c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1) {
687c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
688c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	      dri2_dpy->device_name, strerror(errno));
689c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
690c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   }
691c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
692c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drmGetMagic(dri2_dpy->fd, &magic);
693c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
694c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
695c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
696c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
6977b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergdrm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
6987b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg{
6997b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
7007b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
7017b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   switch (format) {
70258dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_ARGB8888:
70358dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_ARGB8888;
7047b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
70558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_XRGB8888:
70658dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_XRGB8888;
7077b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
7087b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
7097b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg}
7107b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
7117b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergstatic void
712c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_authenticated(void *data, struct wl_drm *drm)
713c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
714c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
715c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
716aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
717c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
718c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
719c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic const struct wl_drm_listener drm_listener = {
720c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_device,
7217b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	drm_handle_format,
722c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_authenticated
723c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg};
724c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
725a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergstatic void
726a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergregistry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
727a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg		       const char *interface, uint32_t version)
728a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg{
729a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
730a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
731a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (strcmp(interface, "wl_drm") == 0) {
732a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      dri2_dpy->wl_drm =
733a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg         wl_registry_bind(registry, name, &wl_drm_interface, 1);
734a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg      wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
735a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   }
736a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg}
737a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
738a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsbergstatic const struct wl_registry_listener registry_listener = {
739a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg	registry_handle_global
740a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg};
741a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
74293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin FranzkeEGLBoolean
74393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
74493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
74593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy;
7467b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   const __DRIconfig *config;
747a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   uint32_t types;
74893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
7497b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int argb_masks[4] =
7507b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      { 0xff0000, 0xff00, 0xff, 0xff000000 };
7517b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
75293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
75393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateWindowSurface = dri2_create_window_surface;
75493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.DestroySurface = dri2_destroy_surface;
75593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.SwapBuffers = dri2_swap_buffers;
75693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.Terminate = dri2_terminate;
75793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
75893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy = malloc(sizeof *dri2_dpy);
75993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_dpy)
76093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
76193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
762f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   memset(dri2_dpy, 0, sizeof *dri2_dpy);
763f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
76493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = (void *) dri2_dpy;
765b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   if (disp->PlatformDisplay == NULL) {
766b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = wl_display_connect(NULL);
767b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      if (dri2_dpy->wl_dpy == NULL)
768b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke         goto cleanup_dpy;
7692a58453e25899e726f02db005de0e1296c326845Benjamin Franzke      dri2_dpy->own_device = 1;
770b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   } else {
771b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = disp->PlatformDisplay;
772b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   }
77393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
774a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
775a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy);
776a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry,
777a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg                      dri2_dpy->wl_queue);
778a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   wl_registry_add_listener(dri2_dpy->wl_registry,
779a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg                            &registry_listener, dri2_dpy);
780a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL)
78193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dpy;
782a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg
783a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1)
784c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_drm;
78556758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg
786a5776ac0b8c015bf5d6a8513cefec5920895cc8eKristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated)
787c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_fd;
78893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
78993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
79093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_dpy->driver_name == NULL) {
79193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
79293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_fd;
79393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
79493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7956b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (!dri2_load_driver(disp))
796c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_driver_name;
79793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7983104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
7993104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.version = 3;
8003104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
8013104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
8023104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
80393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format;
80493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8053104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
80693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->extensions[1] = &image_lookup_extension.base;
80716a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[2] = &use_invalidate.base;
80816a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[3] = NULL;
80993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
81093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_create_screen(disp))
81193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_driver;
81293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8132a81037439afb04d4170f674646cdae59619707dKristian Høgsberg   types = EGL_WINDOW_BIT;
8147b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
8157b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      config = dri2_dpy->driver_configs[i];
81658dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      if (dri2_dpy->formats & HAS_XRGB8888)
8177b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, rgb_masks);
81858dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      if (dri2_dpy->formats & HAS_ARGB8888)
8197b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks);
8207b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
82193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8226b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
8236b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   dri2_dpy->authenticate = dri2_wayland_authenticate;
8246b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
82593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* we're supporting EGL 1.4 */
82693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMajor = 1;
82793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMinor = 4;
82893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
82993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
83093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
83193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver:
83293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
83393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver_name:
83493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
83593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_fd:
83693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
837c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg cleanup_drm:
838c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   free(dri2_dpy->device_name);
839c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_destroy(dri2_dpy->wl_drm);
84093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dpy:
84193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
84293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
84393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_FALSE;
84493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
845