platform_wayland.c revision 6d4d4b00ddfbd3257ecd129fec5b813be7e36fe9
193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/*
290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg * Copyright © 2011-2012 Intel Corporation
393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Permission is hereby granted, free of charge, to any person obtaining a
593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * copy of this software and associated documentation files (the "Software"),
693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * to deal in the Software without restriction, including without limitation
793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * the rights to use, copy, modify, merge, publish, distribute, sublicense,
893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * and/or sell copies of the Software, and to permit persons to whom the
993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software is furnished to do so, subject to the following conditions:
1093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * The above copyright notice and this permission notice (including the next
1293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * paragraph) shall be included in all copies or substantial portions of the
1393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software.
1493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * DEALINGS IN THE SOFTWARE.
2393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
2493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Authors:
2593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Kristian Høgsberg <krh@bitplanet.net>
2693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Benjamin Franzke <benjaminfranzke@googlemail.com>
2793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
2893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
2993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <stdlib.h>
3093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <string.h>
3193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <limits.h>
3293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <dlfcn.h>
3393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <errno.h>
3493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <unistd.h>
35c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <fcntl.h>
36c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <xf86drm.h>
3793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
3893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include "egl_dri2.h"
3993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
406b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include <wayland-client.h>
416b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include "wayland-drm-client-protocol.h"
426b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
437b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergenum wl_drm_format_flags {
4458dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   HAS_ARGB8888 = 1,
4558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   HAS_XRGB8888 = 2
467b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg};
477b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
4851f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
490229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergsync_callback(void *data, struct wl_callback *callback, uint32_t serial)
500229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
510229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   int *done = data;
520229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
530229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   *done = 1;
540229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_callback_destroy(callback);
550229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
560229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
570229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic const struct wl_callback_listener sync_listener = {
580229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   sync_callback
590229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg};
600229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
610229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic int
620229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergroundtrip(struct dri2_egl_display *dri2_dpy)
630229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
640229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   struct wl_callback *callback;
650229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   int done = 0, ret = 0;
660229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
670229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   callback = wl_display_sync(dri2_dpy->wl_dpy);
680229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_callback_add_listener(callback, &sync_listener, &done);
690229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) callback, dri2_dpy->wl_queue);
700229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   while (ret != -1 && !done)
710229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
720229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
73800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl   if (!done)
74800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl      wl_callback_destroy(callback);
75800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl
760229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   return ret;
770229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
780229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
790229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic void
800cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkewl_buffer_release(void *data, struct wl_buffer *buffer)
810cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
820cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int i;
840cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
8590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); ++i)
8690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer == buffer)
870cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
880cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
8990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (i == ARRAY_SIZE(dri2_surf->color_buffers)) {
9090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      wl_buffer_destroy(buffer);
910cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
9290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
9490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->color_buffers[i].locked = 0;
950cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkestatic struct wl_buffer_listener wl_buffer_listener = {
980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   wl_buffer_release
990cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke};
10051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
101ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveirastatic void
102ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveiraresize_callback(struct wl_egl_window *wl_win, void *data)
103ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira{
104ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   struct dri2_egl_surface *dri2_surf = data;
105ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   struct dri2_egl_display *dri2_dpy =
106ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_egl_display(dri2_surf->base.Resource.Display);
107ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
108ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
109ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira}
110ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
11193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
11293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
11393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
11493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
11593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
11693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    _EGLConfig *conf, EGLNativeWindowType window,
11793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		    const EGLint *attrib_list)
11893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
11993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
12093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
12193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf;
12293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
12493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
12593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf = malloc(sizeof *dri2_surf);
12693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_surf) {
12793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
12893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
12993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
13093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
13190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   memset(dri2_surf, 0, sizeof *dri2_surf);
13293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
13393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
13493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1357b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   if (conf->AlphaSize == 0)
13658dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
1377b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   else
13858dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
1397b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
14093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   switch (type) {
14193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   case EGL_WINDOW_BIT:
14293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->wl_win = (struct wl_egl_window *) window;
14393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
144ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_surf->wl_win->private = dri2_surf;
145ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_surf->wl_win->resize_callback = resize_callback;
146ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
14793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width =  -1;
14893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = -1;
14993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      break;
15093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   default:
15193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
15293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
15393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
15493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_surf->dri_drawable =
15593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
15687dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    type == EGL_WINDOW_BIT ?
15787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_double_config :
15887dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_conf->dri_single_config,
15987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke					    dri2_surf);
16093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_surf->dri_drawable == NULL) {
16193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
16293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dri_drawable;
16393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
16493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
16593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return &dri2_surf->base;
16693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
16793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dri_drawable:
16893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
16993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_surf:
17093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_surf);
17193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return NULL;
17393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
17493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
17593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
17693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
17793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
17893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
17993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
18093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   _EGLConfig *conf, EGLNativeWindowType window,
18193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			   const EGLint *attrib_list)
18293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
18393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
18493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			      window, attrib_list);
18593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
18693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
18793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
18893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglDestroySurface(), drv->API.DestroySurface().
18993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
19093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
19193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
19293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
19393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
19493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
19593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
19693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
19893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
19993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!_eglPutSurface(surf))
20093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return EGL_TRUE;
20193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
20393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
20590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer)
20690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
20790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].dri_buffer)
20890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
20990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                       dri2_surf->color_buffers[i].dri_buffer);
21090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
21193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
21290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < __DRI_BUFFER_COUNT; i++)
21390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->dri_buffers[i] &&
21490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
21593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
21693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke                                       dri2_surf->dri_buffers[i]);
21793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
218a3b6b2d3055070da9bf7054fecfd0b171c398eb7Jonas Ådahl   if (dri2_surf->frame_callback)
219a3b6b2d3055070da9bf7054fecfd0b171c398eb7Jonas Ådahl      wl_callback_destroy(dri2_surf->frame_callback);
220a3b6b2d3055070da9bf7054fecfd0b171c398eb7Jonas Ådahl
221ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
222ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_surf->wl_win->private = NULL;
223ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_surf->wl_win->resize_callback = NULL;
224ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   }
225ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
22693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(surf);
22793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
22893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
22993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
23093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
23193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
23290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergdri2_release_buffers(struct dri2_egl_surface *dri2_surf)
23393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
23493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
23593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
23690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   int i;
23793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
23890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
23990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer &&
24090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          !dri2_surf->color_buffers[i].locked)
24190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
24290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].dri_buffer)
24390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
24490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                       dri2_surf->color_buffers[i].dri_buffer);
24587dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
24690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->color_buffers[i].wl_buffer = NULL;
24790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->color_buffers[i].dri_buffer = NULL;
24890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->color_buffers[i].locked = 0;
24987dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   }
25011f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke
25190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < __DRI_BUFFER_COUNT; i++)
25290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->dri_buffers[i] &&
25390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
25490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
25590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                       dri2_surf->dri_buffers[i]);
25651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
25751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
25890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergstatic int
25990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergget_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
26051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
26151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
26251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
26351f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   int i;
26451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
26590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   /* There might be a buffer release already queued that wasn't processed */
26690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
2670cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
26890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back == NULL) {
26990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
27090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         /* Get an unlocked buffer, preferrably one with a dri_buffer already
27190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          * allocated. */
27290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 if (dri2_surf->color_buffers[i].locked)
27390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg            continue;
27490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         if (dri2_surf->back == NULL)
27590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    dri2_surf->back = &dri2_surf->color_buffers[i];
27690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         else if (dri2_surf->back->dri_buffer == NULL)
27790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    dri2_surf->back = &dri2_surf->color_buffers[i];
27851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      }
27951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   }
2800cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
28190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back == NULL)
28290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
28390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back->dri_buffer == NULL) {
28490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->back->dri_buffer =
28590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
28690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                        __DRI_BUFFER_BACK_LEFT, 32,
28790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                        dri2_surf->base.Width,
28890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                        dri2_surf->base.Height);
2896d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      dri2_surf->back->age = 0;
29090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
29190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back->dri_buffer == NULL)
29290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
2930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
29490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->back->locked = 1;
29590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   memcpy(buffer, dri2_surf->back->dri_buffer, sizeof *buffer);
2960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
29790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   return 0;
2980cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
2990cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
30090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergstatic int
30190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergget_aux_bo(struct dri2_egl_surface *dri2_surf,
30290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	   unsigned int attachment, unsigned int format, __DRIbuffer *buffer)
3030cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
30490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   struct dri2_egl_display *dri2_dpy =
30590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
30690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   __DRIbuffer *b = dri2_surf->dri_buffers[attachment];
30790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg
30890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (b == NULL) {
30990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
31090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 attachment, format,
31190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 dri2_surf->base.Width,
31290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 dri2_surf->base.Height);
31390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->dri_buffers[attachment] = b;
31490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
31590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (b == NULL)
31690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
3170cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
31890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   memcpy(buffer, b, sizeof *buffer);
3190cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
32090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   return 0;
3210cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
3220cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
32393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
32493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers_with_format(__DRIdrawable * driDrawable,
32593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *width, int *height,
32693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     unsigned int *attachments, int count,
32793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke			     int *out_count, void *loaderPrivate)
32893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
32993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = loaderPrivate;
33093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
33193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
33290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   int i, j;
33360a11e295b86475ff334291a5b483e422371b21cAnder Conselvan de Oliveira
334f811c1e6d637a556f36271ee4abeb30aaeb07204Benjamin Franzke   if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
33593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
33693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
33751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
33851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_release_buffers(dri2_surf);
33993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
34093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_win->width;
34193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_win->height;
34293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = dri2_surf->wl_win->dx;
34393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = dri2_surf->wl_win->dy;
34490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
34593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
34690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
34790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      switch (attachments[i]) {
34890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      case __DRI_BUFFER_BACK_LEFT:
34990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {
35090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
35190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    return NULL;
35290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 }
35390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 break;
35490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      default:
35590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
35690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg			&dri2_surf->buffers[j]) < 0) {
35790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
35890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	    return NULL;
35990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 }
36090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	 break;
36193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
36293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
36393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
36490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   /* If we have an extra unlocked buffer at this point, we had to do triple
36590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg    * buffering for a while, but now can go back to just double buffering.
36690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg    * That means we can free any unlocked buffer now. */
36790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
36890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (!dri2_surf->color_buffers[i].locked &&
36990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          dri2_surf->color_buffers[i].wl_buffer) {
37090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
37190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
37290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                                       dri2_surf->color_buffers[i].dri_buffer);
37390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_surf->color_buffers[i].wl_buffer = NULL;
37490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_surf->color_buffers[i].dri_buffer = NULL;
37593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
37693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
37793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
37890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   *out_count = j;
37990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (j == 0)
38093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	   return NULL;
38193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
38293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *width = dri2_surf->base.Width;
38393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *height = dri2_surf->base.Height;
38493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
38593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_surf->buffers;
38693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
38793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
38893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
38993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_get_buffers(__DRIdrawable * driDrawable,
39093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *width, int *height,
39193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 unsigned int *attachments, int count,
39293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke		 int *out_count, void *loaderPrivate)
39393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
39493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   unsigned int *attachments_with_format;
39593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   __DRIbuffer *buffer;
39693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   const unsigned int format = 32;
39793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
39893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
39993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
40093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!attachments_with_format) {
40193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      *out_count = 0;
40293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
40393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
40493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
40593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < count; ++i) {
40693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i] = attachments[i];
40793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i + 1] = format;
40893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
40993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   buffer =
41193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format(driDrawable,
41293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   width, height,
41393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   attachments_with_format, count,
41493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke				   out_count, loaderPrivate);
41593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(attachments_with_format);
41793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
41893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return buffer;
41993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
42093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
42193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
42293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
42393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
42493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) driDrawable;
42593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) loaderPrivate;
42693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
42793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
42893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
4296602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergwayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
43093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
43193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
43293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4330229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   dri2_surf->frame_callback = NULL;
4346602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_callback_destroy(callback);
43593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
43693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4376602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsbergstatic const struct wl_callback_listener frame_listener = {
4386602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg	wayland_frame_callback
4396602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
4406602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
44193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
44293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglSwapBuffers(), drv->API.SwapBuffers().
44393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
44493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
44593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
44693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
44793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
44893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
4496d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   int i, ret = 0;
45093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4510229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   while (dri2_surf->frame_callback && ret != -1)
4520229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
4530229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (ret < 0)
4540229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      return EGL_FALSE;
45593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4560229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   dri2_surf->frame_callback = wl_surface_frame(dri2_surf->wl_win->surface);
4570229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_callback_add_listener(dri2_surf->frame_callback,
4580229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg                            &frame_listener, dri2_surf);
4590229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) dri2_surf->frame_callback,
4600229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg                      dri2_dpy->wl_queue);
46193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4626d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
4636d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      if (dri2_surf->color_buffers[i].age > 0)
4646d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg         dri2_surf->color_buffers[i].age++;
4656d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
4666d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   dri2_surf->back->age = 1;
46790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->current = dri2_surf->back;
46890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->back = NULL;
46990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg
47090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->current->wl_buffer == NULL) {
47190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->current->wl_buffer =
47290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_drm_create_buffer(dri2_dpy->wl_drm,
47390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                              dri2_surf->current->dri_buffer->name,
47490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                              dri2_surf->base.Width,
47590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                              dri2_surf->base.Height,
47690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                              dri2_surf->current->dri_buffer->pitch,
47790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                              dri2_surf->format);
47890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->current->wl_buffer,
47990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                         dri2_dpy->wl_queue);
48090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      wl_buffer_add_listener(dri2_surf->current->wl_buffer,
48190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                             &wl_buffer_listener, dri2_surf);
48290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
48393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   wl_surface_attach(dri2_surf->wl_win->surface,
48590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                     dri2_surf->current->wl_buffer,
48690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                     dri2_surf->dx, dri2_surf->dy);
48793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
48890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
48990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
49090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   /* reset resize growing parameters */
49190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->dx = 0;
49290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->dy = 0;
49393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
49590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                     dri2_surf->base.Width, dri2_surf->base.Height);
4960229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
49790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   wl_surface_commit(dri2_surf->wl_win->surface);
49893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
49993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
50089ba4368fd86778405eea163e2b27812055f0df9Kristian Høgsberg   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
50193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
50393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
50493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5056d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsbergstatic EGLint
5066d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsbergdri2_query_buffer_age(_EGLDriver *drv,
5076d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg                      _EGLDisplay *disp, _EGLSurface *surface)
5086d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg{
5096d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
5106d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   __DRIbuffer buffer;
5116d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
5126d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   if (get_back_bo(dri2_surf, &buffer) < 0) {
5136d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
5146d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      return 0;
5156d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   }
5166d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
5176d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   return dri2_surf->back->age;
5186d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg}
5196d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
5206b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
5216b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkedri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
5226b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
5236b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
5246b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
5256b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
526aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 0;
5276b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
528c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, id);
5290229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0)
5300229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      ret = -1;
5316b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
532c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
5336b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
5346b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5356b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /* reset authenticated */
536aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
5376b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
5386b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
5396b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
5406b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
54193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
54293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglTerminate(), drv->API.Terminate().
54393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
54493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
54593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
54693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
54793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
54893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglReleaseDisplayResources(drv, disp);
55093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   _eglCleanupDisplay(disp);
55193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
55393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
55493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
55593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
5562a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   free(dri2_dpy->device_name);
5572a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   wl_drm_destroy(dri2_dpy->wl_drm);
5582a58453e25899e726f02db005de0e1296c326845Benjamin Franzke   if (dri2_dpy->own_device)
559e6aa32ac7f8d7b843f4d4f8bf9d8e9db790b0868Benjamin Franzke      wl_display_disconnect(dri2_dpy->wl_dpy);
56093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
56193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = NULL;
56293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
56393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
56493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
56593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
566c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
567c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
568c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
569c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
570c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drm_magic_t magic;
571c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
572c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->device_name = strdup(device);
573c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->device_name)
574c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
575c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
576b60120608f6ddf4098bc324363197c979ee04cb7David Fries#ifdef O_CLOEXEC
577b60120608f6ddf4098bc324363197c979ee04cb7David Fries   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
578b60120608f6ddf4098bc324363197c979ee04cb7David Fries   if (dri2_dpy->fd == -1 && errno == EINVAL)
579b60120608f6ddf4098bc324363197c979ee04cb7David Fries#endif
580b60120608f6ddf4098bc324363197c979ee04cb7David Fries   {
581b60120608f6ddf4098bc324363197c979ee04cb7David Fries      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
582b60120608f6ddf4098bc324363197c979ee04cb7David Fries      if (dri2_dpy->fd != -1)
583b60120608f6ddf4098bc324363197c979ee04cb7David Fries         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
584b60120608f6ddf4098bc324363197c979ee04cb7David Fries            FD_CLOEXEC);
585b60120608f6ddf4098bc324363197c979ee04cb7David Fries   }
586c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1) {
587c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
588c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	      dri2_dpy->device_name, strerror(errno));
589c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
590c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   }
591c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
592c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drmGetMagic(dri2_dpy->fd, &magic);
593c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
594c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
595c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
596c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
5977b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergdrm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
5987b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg{
5997b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
6007b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
6017b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   switch (format) {
60258dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_ARGB8888:
60358dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_ARGB8888;
6047b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
60558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_XRGB8888:
60658dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_XRGB8888;
6077b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
6087b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
6097b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg}
6107b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
6117b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergstatic void
612c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_authenticated(void *data, struct wl_drm *drm)
613c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
614c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
615c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
616aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
617c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
618c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
619c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic const struct wl_drm_listener drm_listener = {
620c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_device,
6217b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	drm_handle_format,
622c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	drm_handle_authenticated
623c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg};
624c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
6250229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic void
6260229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergregistry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
6270229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg		       const char *interface, uint32_t version)
6280229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
6290229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
6300229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
6310229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (strcmp(interface, "wl_drm") == 0) {
6320229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      dri2_dpy->wl_drm =
6330229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg         wl_registry_bind(registry, name, &wl_drm_interface, 1);
6340229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
6350229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   }
6360229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
6370229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
6380229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic const struct wl_registry_listener registry_listener = {
6390229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg	registry_handle_global
6400229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg};
6410229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
64293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin FranzkeEGLBoolean
64393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkedri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
64493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
64593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy;
6467b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   const __DRIconfig *config;
6470229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   uint32_t types;
64893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
6497b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int argb_masks[4] =
6507b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      { 0xff0000, 0xff00, 0xff, 0xff000000 };
6517b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
65293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
65393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.CreateWindowSurface = dri2_create_window_surface;
65493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.DestroySurface = dri2_destroy_surface;
65593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.SwapBuffers = dri2_swap_buffers;
65693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   drv->API.Terminate = dri2_terminate;
6576d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   drv->API.QueryBufferAge = dri2_query_buffer_age;
65893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6596bda027e01c15df24d36de5bf3838ea8ed7e9e56Matt Turner   dri2_dpy = calloc(1, sizeof *dri2_dpy);
66093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_dpy)
66193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
66293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
66393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = (void *) dri2_dpy;
664b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   if (disp->PlatformDisplay == NULL) {
665b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = wl_display_connect(NULL);
666b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      if (dri2_dpy->wl_dpy == NULL)
667b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke         goto cleanup_dpy;
6682a58453e25899e726f02db005de0e1296c326845Benjamin Franzke      dri2_dpy->own_device = 1;
669b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   } else {
670b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = disp->PlatformDisplay;
671b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   }
67293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
6730229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
6740229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy);
6750229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry,
6760229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg                      dri2_dpy->wl_queue);
6770229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_registry_add_listener(dri2_dpy->wl_registry,
6780229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg                            &registry_listener, dri2_dpy);
6790229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL)
68093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_dpy;
6810229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
6820229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1)
683c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_drm;
68456758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg
6850229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || !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
6973104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
6983104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->dri2_loader_extension.base.version = 3;
6993104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
7003104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
7013104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
70293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_get_buffers_with_format;
70393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7043104e5cb4f8524e9852300aa1e112d7fe31545caFeng, Haitao   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
70593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dri2_dpy->extensions[1] = &image_lookup_extension.base;
70616a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[2] = &use_invalidate.base;
70716a04e019dcb0f1d50ceab5c8c2eafb56fa60853Kristian Høgsberg   dri2_dpy->extensions[3] = NULL;
70893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
70993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_create_screen(disp))
71093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_driver;
71193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
712e20a0f14b5fdbff9afa5d0d6ee35de8728f6a200Kristian Høgsberg   types = EGL_WINDOW_BIT;
7137b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
7147b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      config = dri2_dpy->driver_configs[i];
71558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      if (dri2_dpy->formats & HAS_XRGB8888)
7167b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, rgb_masks);
71758dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      if (dri2_dpy->formats & HAS_ARGB8888)
7187b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg	 dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks);
7197b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
72093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7216b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
7226d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   disp->Extensions.EXT_buffer_age = EGL_TRUE;
7236b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   dri2_dpy->authenticate = dri2_wayland_authenticate;
7246b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
72593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   /* we're supporting EGL 1.4 */
72693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMajor = 1;
72793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->VersionMinor = 4;
72893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
72993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
73093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
73193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver:
73293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
73393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver_name:
73493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
73593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_fd:
73693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
737c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg cleanup_drm:
738c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   free(dri2_dpy->device_name);
739c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_destroy(dri2_dpy->wl_drm);
74093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dpy:
74193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
74293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
74393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_FALSE;
74493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
745