platform_wayland.c revision 2a58453e25899e726f02db005de0e1296c326845
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 {
447b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   HAS_ARGB32 = 1,
457b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   HAS_PREMUL_ARGB32 = 2,
467b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   HAS_XRGB32 = 4
477b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg};
487b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
4951f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
500cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkewl_buffer_release(void *data, struct wl_buffer *buffer)
510cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
520cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
530cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int i;
540cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
550cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
560cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      if (dri2_surf->wl_drm_buffer[i] == buffer)
570cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
580cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
590cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   assert(i <= WL_BUFFER_COUNT);
600cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
610cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   /* not found? */
620cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (i == WL_BUFFER_COUNT)
630cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
640cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
650cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[i] = 0;
660cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
670cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
680cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
690cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic struct wl_buffer_listener wl_buffer_listener = {
700cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   wl_buffer_release
710cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke};
7251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
7393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
7493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
7593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
7693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
7793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
7893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    _EGLConfig *conf, EGLNativeWindowType window,
7993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    const EGLint *attrib_list)
8093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
8193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
8293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
8393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf;
8493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
8593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
8693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
8893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf = malloc(sizeof *dri2_surf);
9093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_surf) {
9193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
9293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
9393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
9493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
9593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
9693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
9793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i) {
9993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_drm_buffer[i] = NULL;
1000cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->wl_buffer_lock[i] = 0;
1010cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
10293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
10393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
10493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[i] = NULL;
10593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
10651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
1070cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->third_buffer = NULL;
10893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_FALSE;
10993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1107b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   if (conf->AlphaSize == 0)
1117b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_XRGB32;
1127b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   else if (dri2_surf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE)
1137b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_PREMULTIPLIED_ARGB32;
1147b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   else
1157b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_ARGB32;
1167b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
11793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (type) {
11893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_WINDOW_BIT:
11993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win = (struct wl_egl_window *) window;
12093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width =  -1;
12293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = -1;
12393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
12493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_PIXMAP_BIT:
12593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix = (struct wl_egl_pixmap *) window;
12693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_pix->width;
12893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_pix->height;
12993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
130c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      if (dri2_surf->wl_pix->driver_private) {
13193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_buf = dri2_surf->wl_pix->driver_private;
13293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_buf->dri_buffer;
13393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
13493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
13593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
13693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
13793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
13893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->dri_drawable =
14093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
14187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    type == EGL_WINDOW_BIT ?
14287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_double_config :
14387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_single_config,
14487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_surf);
14593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->dri_drawable == NULL) {
14693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
14793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dri_drawable;
14893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
14993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
15093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return &dri2_surf->base;
15193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
15293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dri_drawable:
15393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
15493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_surf:
15593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_surf);
15693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
15793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return NULL;
15893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
15993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
16093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
16193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
16293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
16393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
16493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
16593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativeWindowType window,
16693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
16793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
16893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
16993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      window, attrib_list);
17093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
17193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
17393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
17493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativePixmapType pixmap,
17593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
17693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
17793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
17893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      pixmap, attrib_list);
17993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
18093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
18293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglDestroySurface(), drv->API.DestroySurface().
18393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
18493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
18593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
18693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
18793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
18893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
18993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
19093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
19293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglPutSurface(surf))
19493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return EGL_TRUE;
19593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
19793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
19993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->wl_drm_buffer[i])
20093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
20193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
20393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->dri_buffers[i] && !(i == __DRI_BUFFER_FRONT_LEFT &&
204f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke          dri2_surf->base.Type == EGL_PIXMAP_BIT))
20593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
20693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                       dri2_surf->dri_buffers[i]);
20793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
2080cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer) {
2090cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
2100cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                    dri2_surf->third_buffer);
2110cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
2120cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
21393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(surf);
21493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
21693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
21793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
21993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
22093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
22193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf = egl_pixmap->driver_private;
22293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
22393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   assert(dri2_buf);
22493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
22593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri2_dpy->dri2->releaseBuffer(dri2_buf->dri2_dpy->dri_screen,
22693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                           dri2_buf->dri_buffer);
22793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
22893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_buf);
22993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
23093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   egl_pixmap->driver_private = NULL;
23193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   egl_pixmap->destroy = NULL;
23293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
23393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
234f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzkestatic struct wl_buffer *
235f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzkewayland_create_buffer(struct dri2_egl_surface *dri2_surf,
2367b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg                      __DRIbuffer *buffer)
237f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke{
238f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
239f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
2400cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct wl_buffer *buf;
241f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
2420cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
2430cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                              dri2_surf->base.Width, dri2_surf->base.Height,
2447b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg                              buffer->pitch, dri2_surf->format);
2450cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf);
2460cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
2470cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   return buf;
248f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke}
249f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
25093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
25187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkedri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
25293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
25393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
25493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
25593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
25687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   (void) format;
25787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
258f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   switch (dri2_surf->base.Type) {
259f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   case EGL_WINDOW_BIT:
26087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      /* allocate a front buffer for our double-buffered window*/
2610cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL)
2620cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
26387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
26493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
26587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke               __DRI_BUFFER_FRONT_LEFT, format,
26693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke               dri2_surf->base.Width, dri2_surf->base.Height);
26793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
26887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   default:
26987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      break;
27087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   }
27187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke}
27287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
27387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkestatic void
27487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkedri2_process_front_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
27587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke{
27687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
27787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
27887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
27987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
280f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   switch (dri2_surf->base.Type) {
281f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   case EGL_PIXMAP_BIT:
28293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf = malloc(sizeof *dri2_buf);
28393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (!dri2_buf)
28493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         return;
28593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
28693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf->dri_buffer = dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT];
28793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf->dri2_dpy   = dri2_dpy;
28893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
28993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix->driver_private = dri2_buf;
29093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix->destroy        = dri2_wl_egl_pixmap_destroy;
29193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
29293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
29393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
29493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
29593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
29693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
29751f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
2986602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergdri2_release_pending_buffer(void *data,
2996602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg			    struct wl_callback *callback, uint32_t time)
30051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
30151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
30251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
30351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
30451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
30551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   /* FIXME: print internal error */
30651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   if (!dri2_surf->pending_buffer)
30751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      return;
30851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
30951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
31051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                 dri2_surf->pending_buffer);
31151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
31211f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke
31311f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke   wl_callback_destroy(callback);
31451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
31551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3166602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergstatic const struct wl_callback_listener release_buffer_listener = {
3176602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   dri2_release_pending_buffer
3186602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
3196602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
32051f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
32151f2820922b669af3947fcedd17109524644bb94Benjamin Franzkedri2_release_buffers(struct dri2_egl_surface *dri2_surf)
32251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
32351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
32451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
3256602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   struct wl_callback *callback;
32651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int i;
32751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3280cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer) {
3290cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
3300cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                    dri2_surf->third_buffer);
3310cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->third_buffer = NULL;
3320cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
3330cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
33451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
33551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      if (dri2_surf->dri_buffers[i]) {
33651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         switch (i) {
33751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         case __DRI_BUFFER_FRONT_LEFT:
33851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            if (dri2_surf->pending_buffer)
3396602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	      wl_display_roundtrip(dri2_dpy->wl_dpy);
34051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_surf->pending_buffer = dri2_surf->dri_buffers[i];
3416602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg            callback = wl_display_sync(dri2_dpy->wl_dpy);
3426602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	    wl_callback_add_listener(callback,
3436602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg				     &release_buffer_listener, dri2_surf);
34451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
34551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         default:
34651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
34751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                          dri2_surf->dri_buffers[i]);
34851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
34951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         }
35051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         dri2_surf->dri_buffers[i] = NULL;
35151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      }
35251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   }
35351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
35451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3550cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic inline void
3560cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkepointer_swap(const void **p1, const void **p2)
3570cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3580cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   const void *tmp = *p1;
3590cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   *p1 = *p2;
3600cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   *p2 = tmp;
3610cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3620cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3630cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3640cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkedestroy_third_buffer(struct dri2_egl_surface *dri2_surf)
3650cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3660cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
3670cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
3680cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3690cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->third_buffer == NULL)
3700cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
3710cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3720cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
3730cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                                 dri2_surf->third_buffer);
3740cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->third_buffer = NULL;
3750cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3760cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD])
3770cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]);
3780cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL;
3790cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0;
3800cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3810cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3820cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkeswap_wl_buffers(struct dri2_egl_surface *dri2_surf,
3840cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                enum wayland_buffer_type a, enum wayland_buffer_type b)
3850cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3860cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int tmp;
3870cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3880cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   tmp = dri2_surf->wl_buffer_lock[a];
3890cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b];
3900cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   dri2_surf->wl_buffer_lock[b] = tmp;
3910cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3920cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a],
3930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                (const void **) &dri2_surf->wl_drm_buffer[b]);
3940cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3950cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
3960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
3970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkeswap_back_and_third(struct dri2_egl_surface *dri2_surf)
3980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
3990cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD])
4000cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      destroy_third_buffer(dri2_surf);
4010cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
4020cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT],
4030cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                (const void **) &dri2_surf->third_buffer);
4040cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
4050cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD);
4060cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
4070cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
4080cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic void
4090cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkedri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf,
4100cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke                           unsigned int type)
4110cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
4120cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   switch (type) {
4130cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   case __DRI_BUFFER_BACK_LEFT:
4140cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK])
4150cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke            swap_back_and_third(dri2_surf);
4160cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         else if (dri2_surf->third_buffer)
4170cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke            destroy_third_buffer(dri2_surf);
4180cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
4190cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   default:
4200cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
4210cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
4220cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   }
4230cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
4240cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
42593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
42693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers_with_format(__DRIdrawable * driDrawable,
42793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *width, int *height,
42893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     unsigned int *attachments, int count,
42993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *out_count, void *loaderPrivate)
43093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
43193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
43293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
43393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
43493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
43593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
436f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
43793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
43893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
43951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
44051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_release_buffers(dri2_surf);
44193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_win->width;
44393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_win->height;
44493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = dri2_surf->wl_win->dx;
44593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = dri2_surf->wl_win->dy;
44693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      for (i = 0; i < WL_BUFFER_COUNT; ++i) {
44893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (dri2_surf->wl_drm_buffer[i])
44993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
45093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->wl_drm_buffer[i]  = NULL;
4510cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         dri2_surf->wl_buffer_lock[i] = 0;
45293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
45393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
45493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->buffer_count = 0;
45693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < 2*count; i+=2) {
45793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(attachments[i] < __DRI_BUFFER_COUNT);
45893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(dri2_surf->buffer_count < 5);
45993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4600cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_prior_buffer_creation(dri2_surf, attachments[i]);
4610cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
46293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
46393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->dri_buffers[attachments[i]] =
46593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
46693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  attachments[i], attachments[i+1],
46793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  dri2_surf->base.Width, dri2_surf->base.Height);
46893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (!dri2_surf->dri_buffers[attachments[i]])
47093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            continue;
47193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (attachments[i] == __DRI_BUFFER_FRONT_LEFT)
47393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            dri2_process_front_buffer(dri2_surf, attachments[i+1]);
47487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke         else if (attachments[i] == __DRI_BUFFER_BACK_LEFT)
47587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke            dri2_process_back_buffer(dri2_surf, attachments[i+1]);
47693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
47793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
47993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             dri2_surf->dri_buffers[attachments[i]],
48093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             sizeof(__DRIbuffer));
48193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->buffer_count++;
48393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
48493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
485f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   assert(dri2_surf->base.Type == EGL_PIXMAP_BIT ||
48693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke          dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
48793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
488f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_PIXMAP_BIT && !dri2_surf->wl_pix->buffer)
489f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke      dri2_surf->wl_pix->buffer =
490f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke         wayland_create_buffer(dri2_surf,
4917b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg			       dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
492f09c66b3cc9542b0a8f795e34b882c2b8f9f26f7Benjamin Franzke
49393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *out_count = dri2_surf->buffer_count;
49493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->buffer_count == 0)
49593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	   return NULL;
49693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *width = dri2_surf->base.Width;
49893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *height = dri2_surf->base.Height;
49993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_surf->buffers;
50193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
50293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
50493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers(__DRIdrawable * driDrawable,
50593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *width, int *height,
50693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 unsigned int *attachments, int count,
50793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *out_count, void *loaderPrivate)
50893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
50993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   unsigned int *attachments_with_format;
51093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   __DRIbuffer *buffer;
51193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   const unsigned int format = 32;
51293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
51393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
51493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
51593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!attachments_with_format) {
51693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      *out_count = 0;
51793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
51893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
51993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < count; ++i) {
52193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i] = attachments[i];
52293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i + 1] = format;
52393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
52493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   buffer =
52693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format(driDrawable,
52793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   width, height,
52893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   attachments_with_format, count,
52993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   out_count, loaderPrivate);
53093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(attachments_with_format);
53293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return buffer;
53493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
53593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
53893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
53993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
54093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) driDrawable;
54193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* FIXME: Does EGL support front buffer rendering at all? */
54393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#if 0
54593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
54693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2WaitGL(dri2_surf);
54893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#else
54993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) loaderPrivate;
55093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#endif
55193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
55293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
5546602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergwayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
55593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
55693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
55793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_FALSE;
5596602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_callback_destroy(callback);
56093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
56193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5626602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergstatic const struct wl_callback_listener frame_listener = {
5636602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	wayland_frame_callback
5646602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
5656602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
56693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
56793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglSwapBuffers(), drv->API.SwapBuffers().
56893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
56993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
57093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
57193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
57293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
57393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
57493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
5756602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   struct wl_callback *callback;
57693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5770763b978eea5f133e43fb223d50c08fcca5397a2Jørgen Lind   if (dri2_surf->block_swap_buffers) {
5780763b978eea5f133e43fb223d50c08fcca5397a2Jørgen Lind      wl_display_flush(dri2_dpy->wl_dpy);
5790763b978eea5f133e43fb223d50c08fcca5397a2Jørgen Lind      while (dri2_surf->block_swap_buffers)
5800763b978eea5f133e43fb223d50c08fcca5397a2Jørgen Lind         wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE);
5810763b978eea5f133e43fb223d50c08fcca5397a2Jørgen Lind   }
58293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
58393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_TRUE;
5846602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   callback = wl_surface_frame(dri2_surf->wl_win->surface);
5856602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_callback_add_listener(callback, &frame_listener, dri2_surf);
58693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
587f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
58893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      pointer_swap(
58993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
59093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
59193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
59293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =
59393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_FRONT_LEFT;
59493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
59593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_BACK_LEFT;
59693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);
59893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
59993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
60093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
60193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    wayland_create_buffer(dri2_surf,
6027b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg		  dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
60393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
604b1a91722773152ea96de79d2b446ae488561bb0cBenjamin Franzke      wl_buffer_damage(dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], 0, 0,
605b1a91722773152ea96de79d2b446ae488561bb0cBenjamin Franzke		       dri2_surf->base.Width, dri2_surf->base.Height);
60693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_attach(dri2_surf->wl_win->surface,
60793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
60893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->dx, dri2_surf->dy);
6090cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;
61093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
61193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
61293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
61393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      /* reset resize growing parameters */
61493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = 0;
61593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = 0;
61693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
61793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
61893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->base.Width, dri2_surf->base.Height);
61993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
62093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
62193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _EGLContext *ctx;
62293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_drv->glFlush) {
62393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      ctx = _eglGetCurrentContext();
62493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (ctx && ctx->DrawSurface == &dri2_surf->base)
62593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_drv->glFlush();
62693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
62793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
62893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
62993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
63093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
63193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
63293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
63393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
63493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
63593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateImageKHR(), drv->API.CreateImageKHR().
63693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
63793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLImage *
63893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
63993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     EGLClientBuffer buffer, const EGLint *attr_list)
64093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
64193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
64293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct wl_egl_pixmap *wl_egl_pixmap = (struct wl_egl_pixmap *) buffer;
64393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
64493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   EGLint wl_attr_list[] = {
64593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_WIDTH,		0,
64693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_HEIGHT,		0,
64793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_DRM_BUFFER_STRIDE_MESA,	0,
64893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
64993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_NONE
65093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   };
65193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
65293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf = malloc(sizeof *dri2_buf);
65393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_buf)
65493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke           return NULL;
65593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
65693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri2_dpy = dri2_dpy;
65793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri_buffer =
65893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
65993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     __DRI_BUFFER_FRONT_LEFT, 32,
66093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     wl_egl_pixmap->width,
66193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     wl_egl_pixmap->height);
66293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
66393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_egl_pixmap->destroy = dri2_wl_egl_pixmap_destroy;
66493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_egl_pixmap->driver_private = dri2_buf;
66593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6667b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   /* FIXME: Get buffer format from attr_list somehow... or from the
6677b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      wl_egl_piaxmap.  */
668c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_egl_pixmap->buffer =
669c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      wl_drm_create_buffer(dri2_dpy->wl_drm,
670c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   dri2_buf->dri_buffer->name,
671c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   wl_egl_pixmap->width,
672c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   wl_egl_pixmap->height,
673c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   dri2_buf->dri_buffer->pitch,
6747b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg			   WL_DRM_FORMAT_PREMULTIPLIED_ARGB32);
675c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
67693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_attr_list[1] = wl_egl_pixmap->width;
67793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_attr_list[3] = wl_egl_pixmap->height;
678c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_attr_list[5] = dri2_buf->dri_buffer->pitch / 4;
67993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
68093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_image_khr(disp->Driver, disp, ctx, EGL_DRM_BUFFER_MESA,
681c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	(EGLClientBuffer)(intptr_t) dri2_buf->dri_buffer->name, wl_attr_list);
68293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
68393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
68493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLImage *
68593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_wayland_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
68693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      _EGLContext *ctx, EGLenum target,
68793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      EGLClientBuffer buffer, const EGLint *attr_list)
68893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
68993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
69093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
69193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (target) {
69293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_NATIVE_PIXMAP_KHR:
69393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
69493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
69593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
69693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
69793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
69893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6996b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
7006b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
7016b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
7026b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
7036b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
7046b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
705aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 0;
7066b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
707c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, id);
7086602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_display_roundtrip(dri2_dpy->wl_dpy);
7096b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
710c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
7116b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
7126b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
7136b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /* reset authenticated */
714aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
7156b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
7166b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
7176b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
7186b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
71993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
72093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglTerminate(), drv->API.Terminate().
72193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
72293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
72393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
72493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
72593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
72693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
72793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglReleaseDisplayResources(drv, disp);
72893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglCleanupDisplay(disp);
72993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
73093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
73193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
73293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
73393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
7342a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   free(dri2_dpy->device_name);
7352a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   wl_drm_destroy(dri2_dpy->wl_drm);
7362a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   if (dri2_dpy->own_device)
7372a58453e25899e726f02db005de0e1296c326845Benjamin Franzke      wl_display_destroy(dri2_dpy->wl_dpy);
73893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
73993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = NULL;
74093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
74193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
74293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
74393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
744c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
745c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
746c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
747c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
748c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drm_magic_t magic;
749c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
750c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->device_name = strdup(device);
751c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->device_name)
752c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
753c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
754c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
755c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1) {
756c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
757c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	      dri2_dpy->device_name, strerror(errno));
758c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
759c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   }
760c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
761c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drmGetMagic(dri2_dpy->fd, &magic);
762c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
763c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
764c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
765c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
7667b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergdrm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
7677b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg{
7687b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
7697b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
7707b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   switch (format) {
7717b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   case WL_DRM_FORMAT_ARGB32:
7727b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_dpy->formats |= HAS_ARGB32;
7737b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
7747b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32:
7757b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_dpy->formats |= HAS_PREMUL_ARGB32;
7767b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
7777b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   case WL_DRM_FORMAT_XRGB32:
7787b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      dri2_dpy->formats |= HAS_XRGB32;
7797b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
7807b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
7817b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg}
7827b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
7837b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergstatic void
784c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_authenticated(void *data, struct wl_drm *drm)
785c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
786c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
787c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
788aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
789c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
790c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
791c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic const struct wl_drm_listener drm_listener = {
792c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_device,
7937b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	drm_handle_format,
794c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_authenticated
795c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg};
796c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
79793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin FranzkeEGLBoolean
79893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
79993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
80093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy;
8017b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   const __DRIconfig *config;
8027b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   uint32_t id, types;
80393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
8047b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int argb_masks[4] =
8057b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      { 0xff0000, 0xff00, 0xff, 0xff000000 };
8067b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
80793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
80893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateWindowSurface = dri2_create_window_surface;
80993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
81093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.DestroySurface = dri2_destroy_surface;
81193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.SwapBuffers = dri2_swap_buffers;
81293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateImageKHR = dri2_wayland_create_image_khr;
81393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.Terminate = dri2_terminate;
81493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
81593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy = malloc(sizeof *dri2_dpy);
81693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_dpy)
81793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
81893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
819f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   memset(dri2_dpy, 0, sizeof *dri2_dpy);
820f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
82193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = (void *) dri2_dpy;
822b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   if (disp->PlatformDisplay == NULL) {
823b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = wl_display_connect(NULL);
824b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      if (dri2_dpy->wl_dpy == NULL)
825b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke         goto cleanup_dpy;
8262a58453e25899e726f02db005de0e1296c326845Benjamin Franzke      dri2_dpy->own_device = 1;
827b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   } else {
828b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = disp->PlatformDisplay;
829b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   }
83093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8312225397d1cf5e4f4a1293495f3a26bd33e5d7ac3Benjamin Franzke   id = wl_display_get_global(dri2_dpy->wl_dpy, "wl_drm", 1);
832c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (id == 0)
8336602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg      wl_display_roundtrip(dri2_dpy->wl_dpy);
8342225397d1cf5e4f4a1293495f3a26bd33e5d7ac3Benjamin Franzke   id = wl_display_get_global(dri2_dpy->wl_dpy, "wl_drm", 1);
835c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (id == 0)
83656758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg      goto cleanup_dpy;
837c661ecce1089000c3fca9a543713f8264221be50Kristian Høgsberg   dri2_dpy->wl_drm = wl_display_bind(dri2_dpy->wl_dpy, id, &wl_drm_interface);
838c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->wl_drm)
83993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dpy;
840c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
8416602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_display_roundtrip(dri2_dpy->wl_dpy);
842c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1)
843c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_drm;
84456758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg
8456602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_display_roundtrip(dri2_dpy->wl_dpy);
846c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
847c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_fd;
84893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
84993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
85093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_dpy->driver_name == NULL) {
85193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
85293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_fd;
85393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
85493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8556b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (!dri2_load_driver(disp))
856c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_driver_name;
85793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8583104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
8593104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.version = 3;
8603104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
8613104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
8623104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
86393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format;
86493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8653104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
86693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->extensions[1] = &image_lookup_extension.base;
86716a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[2] = &use_invalidate.base;
86816a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[3] = NULL;
86993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
87093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_create_screen(disp))
87193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_driver;
87293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8737b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   types = EGL_WINDOW_BIT | EGL_PIXMAP_BIT;
8747b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   if (dri2_dpy->formats & HAS_PREMUL_ARGB32)
8757b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      types |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
87693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8777b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
8787b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      config = dri2_dpy->driver_configs[i];
8797b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      if (dri2_dpy->formats & HAS_XRGB32)
8807b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, rgb_masks);
8817b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      if (dri2_dpy->formats & (HAS_ARGB32 | HAS_PREMUL_ARGB32))
8827b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks);
8837b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
88493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
88593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
88693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8876b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
8886b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   dri2_dpy->authenticate = dri2_wayland_authenticate;
8896b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
89093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* we're supporting EGL 1.4 */
89193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMajor = 1;
89293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMinor = 4;
89393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
89493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
89593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
89693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver:
89793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
89893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver_name:
89993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
90093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_fd:
90193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
902c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg cleanup_drm:
903c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   free(dri2_dpy->device_name);
904c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_destroy(dri2_dpy->wl_drm);
90593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dpy:
90693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
90793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
90893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_FALSE;
90993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
910