platform_wayland.c revision c0f8c9911c82c576cdd82dabad4a2370ac53565c
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
4351f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
4451f2820922b669af3947fcedd17109524644bb94Benjamin Franzkesync_callback(void *data)
4551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
4651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int *done = data;
4751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
4851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   *done = 1;
4951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
5051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
5151f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
5251f2820922b669af3947fcedd17109524644bb94Benjamin Franzkeforce_roundtrip(struct wl_display *display)
5351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
5451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int done = 0;
5551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
5651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   wl_display_sync_callback(display, sync_callback, &done);
5751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   wl_display_iterate(display, WL_DISPLAY_WRITABLE);
5851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   while (!done)
5951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      wl_display_iterate(display, WL_DISPLAY_READABLE);
6051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
6151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
6251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
6393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
6493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
6593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
6693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
6793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
6893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    _EGLConfig *conf, EGLNativeWindowType window,
6993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    const EGLint *attrib_list)
7093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
7193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
7293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
7393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf;
7493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
7593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
7693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
7893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf = malloc(sizeof *dri2_surf);
8093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_surf) {
8193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
8293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
8393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
8493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
8693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
8793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
8893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
8993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_drm_buffer[i] = NULL;
9093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
9193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
9293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[i] = NULL;
9393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
9451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
9593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_FALSE;
9693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
9793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (type) {
9893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_WINDOW_BIT:
9993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win = (struct wl_egl_window *) window;
10093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->type = DRI2_WINDOW_SURFACE;
10193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
10293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width =  -1;
10393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = -1;
10493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
10593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_PIXMAP_BIT:
10693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix = (struct wl_egl_pixmap *) window;
10793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->type = DRI2_PIXMAP_SURFACE;
10893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
10993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_pix->width;
11093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_pix->height;
11193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
112c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      if (dri2_surf->wl_pix->driver_private) {
11393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_buf = dri2_surf->wl_pix->driver_private;
11493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_buf->dri_buffer;
11593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
11693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
11793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
11893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
11993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
12093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->dri_drawable =
12293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
12387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    type == EGL_WINDOW_BIT ?
12487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_double_config :
12587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_single_config,
12687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_surf);
12793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->dri_drawable == NULL) {
12893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
12993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dri_drawable;
13093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
13193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return &dri2_surf->base;
13393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dri_drawable:
13593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
13693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_surf:
13793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_surf);
13893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return NULL;
14093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
14193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
14293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
14393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
14493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
14593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
14693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
14793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativeWindowType window,
14893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
14993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
15093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
15193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      window, attrib_list);
15293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
15393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
15493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
15593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
15693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativePixmapType pixmap,
15793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
15893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
15993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
16093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      pixmap, attrib_list);
16193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
16293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
16393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
16493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglDestroySurface(), drv->API.DestroySurface().
16593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
16693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
16793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
16893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
16993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
17093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
17193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
17293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
17493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglPutSurface(surf))
17693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return EGL_TRUE;
17793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
17993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < WL_BUFFER_COUNT; ++i)
18193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->wl_drm_buffer[i])
18293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
18393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
18593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->dri_buffers[i] && !(i == __DRI_BUFFER_FRONT_LEFT &&
18693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke          dri2_surf->type == DRI2_PIXMAP_SURFACE))
18793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
18893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                       dri2_surf->dri_buffers[i]);
18993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(surf);
19193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
19393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
19493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
19693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
19793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
19893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf = egl_pixmap->driver_private;
19993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   assert(dri2_buf);
20193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri2_dpy->dri2->releaseBuffer(dri2_buf->dri2_dpy->dri_screen,
20393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                           dri2_buf->dri_buffer);
20493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_buf);
20693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   egl_pixmap->driver_private = NULL;
20893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   egl_pixmap->destroy = NULL;
20993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
21093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
21287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkedri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
21393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
21493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
21593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
21693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   (void) format;
21887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
21993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (dri2_surf->type) {
22093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case DRI2_WINDOW_SURFACE:
22187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      /* allocate a front buffer for our double-buffered window*/
22287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
22393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
22487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke               __DRI_BUFFER_FRONT_LEFT, format,
22593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke               dri2_surf->base.Width, dri2_surf->base.Height);
22693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
22787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   default:
22887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      break;
22987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   }
23087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke}
23187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
23287dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkestatic void
23387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzkedri2_process_front_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
23487dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke{
23587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
23687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
23787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
23887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
23987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   switch (dri2_surf->type) {
24093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case DRI2_PIXMAP_SURFACE:
24193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf = malloc(sizeof *dri2_buf);
24293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (!dri2_buf)
24393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         return;
24493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
24593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf->dri_buffer = dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT];
24693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_buf->dri2_dpy   = dri2_dpy;
24793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
24893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix->driver_private = dri2_buf;
24993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_pix->destroy        = dri2_wl_egl_pixmap_destroy;
25093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
25193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
25293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
25393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
25493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
25593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
25651f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
25751f2820922b669af3947fcedd17109524644bb94Benjamin Franzkedri2_release_pending_buffer(void *data)
25851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
25951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
26051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
26151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
26251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
26351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   /* FIXME: print internal error */
26451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   if (!dri2_surf->pending_buffer)
26551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      return;
26651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
26751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
26851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                 dri2_surf->pending_buffer);
26951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   dri2_surf->pending_buffer = NULL;
27051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
27151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
27251f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
27351f2820922b669af3947fcedd17109524644bb94Benjamin Franzkedri2_release_buffers(struct dri2_egl_surface *dri2_surf)
27451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
27551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
27651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
27751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int i;
27851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
27951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
28051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      if (dri2_surf->dri_buffers[i]) {
28151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         switch (i) {
28251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         case __DRI_BUFFER_FRONT_LEFT:
28351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            if (dri2_surf->pending_buffer)
284c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg               force_roundtrip(dri2_dpy->wl_dpy);
28551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_surf->pending_buffer = dri2_surf->dri_buffers[i];
286c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg            wl_display_sync_callback(dri2_dpy->wl_dpy,
28751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                     dri2_release_pending_buffer, dri2_surf);
28851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
28951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         default:
29051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
29151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke                                          dri2_surf->dri_buffers[i]);
29251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke            break;
29351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         }
29451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke         dri2_surf->dri_buffers[i] = NULL;
29551f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      }
29651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   }
29751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
29851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
29993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
30093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers_with_format(__DRIdrawable * driDrawable,
30193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *width, int *height,
30293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     unsigned int *attachments, int count,
30393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *out_count, void *loaderPrivate)
30493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
30593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
30693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
30793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
30893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
30993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
31093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->type == DRI2_WINDOW_SURFACE &&
31193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
31293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
31351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
31451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_release_buffers(dri2_surf);
31593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
31693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_win->width;
31793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_win->height;
31893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = dri2_surf->wl_win->dx;
31993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = dri2_surf->wl_win->dy;
32093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
32193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      for (i = 0; i < WL_BUFFER_COUNT; ++i) {
32293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (dri2_surf->wl_drm_buffer[i])
32393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
32493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->wl_drm_buffer[i]  = NULL;
32593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
32693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
32793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
32893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->buffer_count = 0;
32993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < 2*count; i+=2) {
33093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(attachments[i] < __DRI_BUFFER_COUNT);
33193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      assert(dri2_surf->buffer_count < 5);
33293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
33393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
33493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
33593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_surf->dri_buffers[attachments[i]] =
33693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
33793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  attachments[i], attachments[i+1],
33893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                  dri2_surf->base.Width, dri2_surf->base.Height);
33993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
34093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (!dri2_surf->dri_buffers[attachments[i]])
34193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            continue;
34293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
34393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         if (attachments[i] == __DRI_BUFFER_FRONT_LEFT)
34493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke            dri2_process_front_buffer(dri2_surf, attachments[i+1]);
34587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke         else if (attachments[i] == __DRI_BUFFER_BACK_LEFT)
34687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke            dri2_process_back_buffer(dri2_surf, attachments[i+1]);
34793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
34893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
34993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
35093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             dri2_surf->dri_buffers[attachments[i]],
35193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke             sizeof(__DRIbuffer));
35293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
35393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->buffer_count++;
35493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
35593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
35693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   assert(dri2_surf->type == DRI2_PIXMAP_SURFACE ||
35793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke          dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
35893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
35993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *out_count = dri2_surf->buffer_count;
36093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->buffer_count == 0)
36193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	   return NULL;
36293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
36393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *width = dri2_surf->base.Width;
36493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *height = dri2_surf->base.Height;
36593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
36693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_surf->buffers;
36793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
36893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
36993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
37093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers(__DRIdrawable * driDrawable,
37193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *width, int *height,
37293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 unsigned int *attachments, int count,
37393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *out_count, void *loaderPrivate)
37493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
37593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   unsigned int *attachments_with_format;
37693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   __DRIbuffer *buffer;
37793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   const unsigned int format = 32;
37893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
37993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
38093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
38193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!attachments_with_format) {
38293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      *out_count = 0;
38393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
38493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
38593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
38693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < count; ++i) {
38793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i] = attachments[i];
38893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i + 1] = format;
38993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
39093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
39193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   buffer =
39293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format(driDrawable,
39393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   width, height,
39493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   attachments_with_format, count,
39593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   out_count, loaderPrivate);
39693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
39793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(attachments_with_format);
39893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
39993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return buffer;
40093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
40193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
40293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
40393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
40493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
40593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
40693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) driDrawable;
40793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
40893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* FIXME: Does EGL support front buffer rendering at all? */
40993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#if 0
41193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
41293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2WaitGL(dri2_surf);
41493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#else
41593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) loaderPrivate;
41693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#endif
41793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
41893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic struct wl_buffer *
42093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkewayland_create_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
42193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
42293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
42393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
42493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
425c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   return wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
42693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                               dri2_surf->base.Width, dri2_surf->base.Height,
42793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                               buffer->pitch, dri2_surf->wl_win->visual);
42893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
42993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
43093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
431f05751aa2af1a8ec83c2d110385aab1b7e735238Benjamin Franzkewayland_frame_callback(struct wl_surface *surface, void *data, uint32_t time)
43293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
43393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
43493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
43593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_FALSE;
43693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
43793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
43893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic inline void
43993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkepointer_swap(const void **p1, const void **p2)
44093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
44193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   const void *tmp = *p1;
44293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *p1 = *p2;
44393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *p2 = tmp;
44493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
44593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
44793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglSwapBuffers(), drv->API.SwapBuffers().
44893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
44993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
45093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
45193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
45293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
45393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
45493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
45593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   while (dri2_surf->block_swap_buffers)
457c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE);
45893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->block_swap_buffers = EGL_TRUE;
460c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_display_frame_callback(dri2_dpy->wl_dpy,
461f05751aa2af1a8ec83c2d110385aab1b7e735238Benjamin Franzke	 		     dri2_surf->wl_win->surface,
462f05751aa2af1a8ec83c2d110385aab1b7e735238Benjamin Franzke			     wayland_frame_callback, dri2_surf);
46393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->type == DRI2_WINDOW_SURFACE) {
46593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      pointer_swap(
46693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
46793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
46893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
46993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =
47093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_FRONT_LEFT;
47193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
47293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 __DRI_BUFFER_BACK_LEFT;
47393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      pointer_swap((const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
47593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		   (const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_BACK]);
47693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
47893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
47993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    wayland_create_buffer(dri2_surf,
48087dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke		  dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
48193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_attach(dri2_surf->wl_win->surface,
48393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
48493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->dx, dri2_surf->dy);
48593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
48793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
48893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      /* reset resize growing parameters */
48993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = 0;
49093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = 0;
49193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
49393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	    dri2_surf->base.Width, dri2_surf->base.Height);
49493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
49593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _EGLContext *ctx;
49793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_drv->glFlush) {
49893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      ctx = _eglGetCurrentContext();
49993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      if (ctx && ctx->DrawSurface == &dri2_surf->base)
50093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_drv->glFlush();
50193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
50293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
50493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
50593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
50793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
50893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
51093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateImageKHR(), drv->API.CreateImageKHR().
51193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
51293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLImage *
51393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
51493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     EGLClientBuffer buffer, const EGLint *attr_list)
51593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
51693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
51793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct wl_egl_pixmap *wl_egl_pixmap = (struct wl_egl_pixmap *) buffer;
51893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_buffer *dri2_buf;
51993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   EGLint wl_attr_list[] = {
52093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_WIDTH,		0,
52193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_HEIGHT,		0,
52293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_DRM_BUFFER_STRIDE_MESA,	0,
52393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
52493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		EGL_NONE
52593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   };
52693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
52793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf = malloc(sizeof *dri2_buf);
52893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_buf)
52993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke           return NULL;
53093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri2_dpy = dri2_dpy;
53293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_buf->dri_buffer =
53393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
53493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     __DRI_BUFFER_FRONT_LEFT, 32,
53593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     wl_egl_pixmap->width,
53693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				     wl_egl_pixmap->height);
53793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
53893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_egl_pixmap->destroy = dri2_wl_egl_pixmap_destroy;
53993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_egl_pixmap->driver_private = dri2_buf;
54093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
541c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_egl_pixmap->buffer =
542c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      wl_drm_create_buffer(dri2_dpy->wl_drm,
543c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   dri2_buf->dri_buffer->name,
544c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   wl_egl_pixmap->width,
545c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   wl_egl_pixmap->height,
546c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   dri2_buf->dri_buffer->pitch,
547c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg			   wl_egl_pixmap->visual);
548c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
54993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_attr_list[1] = wl_egl_pixmap->width;
55093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   wl_attr_list[3] = wl_egl_pixmap->height;
551c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_attr_list[5] = dri2_buf->dri_buffer->pitch / 4;
55293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_image_khr(disp->Driver, disp, ctx, EGL_DRM_BUFFER_MESA,
554c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	(EGLClientBuffer)(intptr_t) dri2_buf->dri_buffer->name, wl_attr_list);
55593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
55693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLImage *
55893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_wayland_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
55993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      _EGLContext *ctx, EGLenum target,
56093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      EGLClientBuffer buffer, const EGLint *attr_list)
56193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
56293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
56393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
56493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (target) {
56593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_NATIVE_PIXMAP_KHR:
56693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
56793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
56893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
56993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
57093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
57193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5726b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
5736b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
5746b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
5756b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
5766b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
5776b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
578c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->authenticated = false;
5796b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
580c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, id);
581c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   force_roundtrip(dri2_dpy->wl_dpy);
5826b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
583c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
5846b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
5856b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5866b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /* reset authenticated */
587c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->authenticated = true;
5886b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5896b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
5906b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
5916b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
59293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
59393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglTerminate(), drv->API.Terminate().
59493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
59593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
59693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
59793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
59893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
59993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
60093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglReleaseDisplayResources(drv, disp);
60193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglCleanupDisplay(disp);
60293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
60393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
60493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
60593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
60693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
60793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
60893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = NULL;
60993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
61093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
61193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
61293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
613c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
614c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
615c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
616c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
617c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drm_magic_t magic;
618c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
619c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->device_name = strdup(device);
620c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->device_name)
621c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
622c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
623c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
624c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1) {
625c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
626c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	      dri2_dpy->device_name, strerror(errno));
627c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
628c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   }
629c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
630c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drmGetMagic(dri2_dpy->fd, &magic);
631c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
632c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
633c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
634c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
635c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_authenticated(void *data, struct wl_drm *drm)
636c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
637c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
638c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
639c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->authenticated = true;
640c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
641c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
642c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic const struct wl_drm_listener drm_listener = {
643c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_device,
644c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_authenticated
645c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg};
646c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
64793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin FranzkeEGLBoolean
64893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
64993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
65093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy;
651c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   uint32_t id;
65293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
65393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
65493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateWindowSurface = dri2_create_window_surface;
65593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
65693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.DestroySurface = dri2_destroy_surface;
65793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.SwapBuffers = dri2_swap_buffers;
65893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateImageKHR = dri2_wayland_create_image_khr;
65993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.Terminate = dri2_terminate;
66093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
66193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy = malloc(sizeof *dri2_dpy);
66293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_dpy)
66393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
66493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
665f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng   memset(dri2_dpy, 0, sizeof *dri2_dpy);
666f55d027ac2e0423eba5d0664cc36668520597703Haitao Feng
66793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = (void *) dri2_dpy;
66893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->wl_dpy = disp->PlatformDisplay;
66993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
670c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   id = wl_display_get_global(dri2_dpy->wl_dpy, "drm", 1);
671c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (id == 0)
672c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE);
673c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   id = wl_display_get_global(dri2_dpy->wl_dpy, "drm", 1);
674c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (id == 0)
67556758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg      goto cleanup_dpy;
676c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->wl_drm = wl_drm_create(dri2_dpy->wl_dpy, id, 1);
677c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->wl_drm)
67893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dpy;
679c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
680c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   force_roundtrip(dri2_dpy->wl_dpy);
681c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1)
682c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_drm;
68356758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg
684c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   force_roundtrip(dri2_dpy->wl_dpy);
685c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
686c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_fd;
68793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
68893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
68993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_dpy->driver_name == NULL) {
69093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
69193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_fd;
69293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
69393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6946b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (!dri2_load_driver(disp))
695c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_driver_name;
69693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6973104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
6983104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.base.version = 3;
6993104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
7003104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
7013104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
70293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format;
70393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7043104e5cb4f8524e9852300aa1e112d7fe31545caHaitao Feng   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
70593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->extensions[1] = &image_lookup_extension.base;
70693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->extensions[2] = NULL;
70793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
70893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_create_screen(disp))
70993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_driver;
71093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
71193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; dri2_dpy->driver_configs[i]; i++)
71293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0,
71387dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke		      EGL_WINDOW_BIT | EGL_PIXMAP_BIT, NULL);
71493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
71593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
71693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
71793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7186b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
7196b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   dri2_dpy->authenticate = dri2_wayland_authenticate;
7206b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
72193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* we're supporting EGL 1.4 */
72293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMajor = 1;
72393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMinor = 4;
72493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
72593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
72693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
72793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver:
72893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
72993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver_name:
73093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
73193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_fd:
73293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
733c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg cleanup_drm:
734c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   free(dri2_dpy->device_name);
735c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_destroy(dri2_dpy->wl_drm);
73693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dpy:
73793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
73893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
73993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_FALSE;
74093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
741