193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/*
290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg * Copyright © 2011-2012 Intel Corporation
3cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * Copyright © 2012 Collabora, Ltd.
493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Permission is hereby granted, free of charge, to any person obtaining a
693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * copy of this software and associated documentation files (the "Software"),
793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * to deal in the Software without restriction, including without limitation
893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * the rights to use, copy, modify, merge, publish, distribute, sublicense,
993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * and/or sell copies of the Software, and to permit persons to whom the
1093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software is furnished to do so, subject to the following conditions:
1193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * The above copyright notice and this permission notice (including the next
1393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * paragraph) shall be included in all copies or substantial portions of the
1493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Software.
1593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
1693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * DEALINGS IN THE SOFTWARE.
2493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *
2593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Authors:
2693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Kristian Høgsberg <krh@bitplanet.net>
2793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke *    Benjamin Franzke <benjaminfranzke@googlemail.com>
2893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
2993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
30bf0e4d219a8cf396402b46c265eb35afd22a676dEmil Velikov#include <stdint.h>
3193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <stdlib.h>
3293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <string.h>
3393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <limits.h>
3493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <dlfcn.h>
3593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <errno.h>
3693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include <unistd.h>
37c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <fcntl.h>
38c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg#include <xf86drm.h>
39cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy#include <sys/mman.h>
4093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
4193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke#include "egl_dri2.h"
428b9298af0a3bce1360cc2c020b31470b37b660feChad Versace#include "egl_dri2_fallbacks.h"
438d4357b5ba9e224ffe02e2457a2f4ffe2915f608Emil Velikov#include "loader.h"
4493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
456b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include <wayland-client.h>
466b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke#include "wayland-drm-client-protocol.h"
476b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
487b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergenum wl_drm_format_flags {
4958dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   HAS_ARGB8888 = 1,
502efc97d51300849636b4b64ef8dfb5645e3b4e5bSingh, Satyeshwar   HAS_XRGB8888 = 2,
512efc97d51300849636b4b64ef8dfb5645e3b4e5bSingh, Satyeshwar   HAS_RGB565 = 4,
527b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg};
537b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
54a218765478e5207f4337406d98865c6b5cf3784eChad Versacestatic EGLBoolean
55a218765478e5207f4337406d98865c6b5cf3784eChad Versacedri2_wl_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
56a218765478e5207f4337406d98865c6b5cf3784eChad Versace                      EGLint interval);
57a218765478e5207f4337406d98865c6b5cf3784eChad Versace
5851f2820922b669af3947fcedd17109524644bb94Benjamin Franzkestatic void
590229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergsync_callback(void *data, struct wl_callback *callback, uint32_t serial)
600229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
610229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   int *done = data;
620229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
630229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   *done = 1;
640229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_callback_destroy(callback);
650229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
660229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
670229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic const struct wl_callback_listener sync_listener = {
685567494403938940f61d44888c436a20a6635ef3Emil Velikov   .done = sync_callback
690229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg};
700229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
710229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic int
720229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergroundtrip(struct dri2_egl_display *dri2_dpy)
730229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
740229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   struct wl_callback *callback;
750229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   int done = 0, ret = 0;
760229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
7736b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   callback = wl_display_sync(dri2_dpy->wl_dpy_wrapper);
780229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_callback_add_listener(callback, &sync_listener, &done);
790229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   while (ret != -1 && !done)
800229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
810229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
82800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl   if (!done)
83800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl      wl_callback_destroy(callback);
84800ed958c33092d694686fcc25c0283dfba86459Jonas Ådahl
850229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   return ret;
860229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
870229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
880229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic void
890cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzkewl_buffer_release(void *data, struct wl_buffer *buffer)
900cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
910cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
920cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke   int i;
930cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
9490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); ++i)
9590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer == buffer)
960cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke         break;
970cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
9890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (i == ARRAY_SIZE(dri2_surf->color_buffers)) {
9990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      wl_buffer_destroy(buffer);
1000cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke      return;
10190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
1020cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
10390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->color_buffers[i].locked = 0;
1040cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
1050cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
1065567494403938940f61d44888c436a20a6635ef3Emil Velikovstatic const struct wl_buffer_listener wl_buffer_listener = {
1075567494403938940f61d44888c436a20a6635ef3Emil Velikov   .release = wl_buffer_release
1080cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke};
10951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
110ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveirastatic void
111ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveiraresize_callback(struct wl_egl_window *wl_win, void *data)
112ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira{
113ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   struct dri2_egl_surface *dri2_surf = data;
114ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira   struct dri2_egl_display *dri2_dpy =
115ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira      dri2_egl_display(dri2_surf->base.Resource.Display);
116ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
117868ae3e31b0e479b299188d0047c88f0d260c6ecBoyan Ding   dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
118ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira}
119ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
1202e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joannastatic void
1212e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joannadestroy_window_callback(void *data)
1222e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna{
1232e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna   struct dri2_egl_surface *dri2_surf = data;
1242e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna   dri2_surf->wl_win = NULL;
1252e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna}
1262e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna
12793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
12893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
12993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
13093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic _EGLSurface *
131cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikovdri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
132cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov                              _EGLConfig *conf, void *native_window,
133cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov                              const EGLint *attrib_list)
13493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
135cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   __DRIcreateNewDrawableFunc createNewDrawable;
13693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
13793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
1386d1f83ec09164bd805c90785635bbcf861b403e5Chad Versace   struct wl_egl_window *window = native_window;
13993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf;
140c2c2e9ab604793c6e01f85497f3f5bf645f962faMarek Olšák   const __DRIconfig *config;
14193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
142f0a8bcd84e50468a703a0ac366a4e067610df30cMatt Turner   dri2_surf = calloc(1, sizeof *dri2_surf);
14393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_surf) {
14493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
14593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
14693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
147052b3d4e2f159038137504f01e9ff2380a67af8bBoyan Ding
148cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
14993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_surf;
15093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
151cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone   if (dri2_dpy->dri2) {
152cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      if (conf->RedSize == 5)
153cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_DRM_FORMAT_RGB565;
154cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      else if (conf->AlphaSize == 0)
155cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
156cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      else
157cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
158cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone   } else {
159cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      if (conf->RedSize == 5)
160cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_SHM_FORMAT_RGB565;
161cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      else if (conf->AlphaSize == 0)
162cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_SHM_FORMAT_XRGB8888;
163cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone      else
164cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone         dri2_surf->format = WL_SHM_FORMAT_ARGB8888;
165cc545ebeabab6d076bfbac159573d29e3cff6ab9Daniel Stone   }
1667b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
1670afa6335079093627b47ff08da38bed00972c217Emil Velikov   if (!window) {
1680afa6335079093627b47ff08da38bed00972c217Emil Velikov      _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface");
1690afa6335079093627b47ff08da38bed00972c217Emil Velikov      goto cleanup_surf;
1700afa6335079093627b47ff08da38bed00972c217Emil Velikov   }
1710afa6335079093627b47ff08da38bed00972c217Emil Velikov
172cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   dri2_surf->wl_win = window;
17393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
174cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   dri2_surf->wl_win->private = dri2_surf;
1752e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna   dri2_surf->wl_win->destroy_window_callback = destroy_window_callback;
176ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
177cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   dri2_surf->base.Width =  -1;
178cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   dri2_surf->base.Height = -1;
17993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
180c2c2e9ab604793c6e01f85497f3f5bf645f962faMarek Olšák   config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
181c2c2e9ab604793c6e01f85497f3f5bf645f962faMarek Olšák                                dri2_surf->base.GLColorspace);
182c2c2e9ab604793c6e01f85497f3f5bf645f962faMarek Olšák
183cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   if (dri2_dpy->dri2) {
184cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov      dri2_surf->wl_win->resize_callback = resize_callback;
185cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov
186cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov      createNewDrawable = dri2_dpy->dri2->createNewDrawable;
187cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   } else {
188cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov      createNewDrawable = dri2_dpy->swrast->createNewDrawable;
18993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
19093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
191cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   dri2_surf->dri_drawable = (*createNewDrawable)(dri2_dpy->dri_screen, config,
192cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov                                                  dri2_surf);
193cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov    if (dri2_surf->dri_drawable == NULL) {
194cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov      _eglError(EGL_BAD_ALLOC, "createNewDrawable");
195cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov       goto cleanup_surf;
196cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov    }
197cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov
198cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   dri2_wl_swap_interval(drv, disp, &dri2_surf->base,
199cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov                         dri2_dpy->default_swap_interval);
200cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov
20193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return &dri2_surf->base;
20293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_surf:
20493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_surf);
20593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
20693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return NULL;
20793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
20893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
2099a40ee16d0be3a08ac2f467311673f4b9333191dChad Versacestatic _EGLSurface *
2109a40ee16d0be3a08ac2f467311673f4b9333191dChad Versacedri2_wl_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
2119a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace                              _EGLConfig *conf, void *native_window,
2129a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace                              const EGLint *attrib_list)
2139a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace{
2149a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace   /* From the EGL_EXT_platform_wayland spec, version 3:
2159a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace    *
2169a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace    *   It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a <dpy>
2179a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace    *   that belongs to Wayland. Any such call fails and generates
2189a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace    *   EGL_BAD_PARAMETER.
2199a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace    */
2209a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace   _eglError(EGL_BAD_PARAMETER, "cannot create EGL pixmap surfaces on "
2219a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace             "Wayland");
2229a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace   return NULL;
2239a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace}
2249a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace
22593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
22693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglDestroySurface(), drv->API.DestroySurface().
22793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
22893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
229d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
23093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
23193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
23293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
23393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
23493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
23593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) drv;
23693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
237868ae3e31b0e479b299188d0047c88f0d260c6ecBoyan Ding   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
23893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
23990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
24090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer)
24190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
242664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg      if (dri2_surf->color_buffers[i].dri_image)
243664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
2444cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      if (dri2_surf->color_buffers[i].linear_copy)
2454cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
246cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (dri2_surf->color_buffers[i].data)
247cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         munmap(dri2_surf->color_buffers[i].data,
248cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                dri2_surf->color_buffers[i].data_size);
24990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
25093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
251cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_dpy->dri2) {
252cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      for (i = 0; i < __DRI_BUFFER_COUNT; i++)
253cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         if (dri2_surf->dri_buffers[i] &&
254cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
255cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
256cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                          dri2_surf->dri_buffers[i]);
257cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
25893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
259992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   if (dri2_surf->throttle_callback)
260992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      wl_callback_destroy(dri2_surf->throttle_callback);
261a3b6b2d3055070da9bf7054fecfd0b171c398eb7Jonas Ådahl
2622e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna   if (dri2_surf->wl_win) {
2632e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna      dri2_surf->wl_win->private = NULL;
2642e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna      dri2_surf->wl_win->resize_callback = NULL;
2652e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna      dri2_surf->wl_win->destroy_window_callback = NULL;
2662e0ab61e29c4b44d349ab433c899b691a9b12f68Stencel, Joanna   }
267ca3ed3e024864e91ca3cccc59fb96950e1d079b5Ander Conselvan de Oliveira
26893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(surf);
26993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
27093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
27193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
27293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
27393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
274d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
27593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
27693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
27793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
27890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   int i;
27993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
28090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
28190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (dri2_surf->color_buffers[i].wl_buffer &&
28290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          !dri2_surf->color_buffers[i].locked)
28390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
284664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg      if (dri2_surf->color_buffers[i].dri_image)
285664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
2864cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      if (dri2_surf->color_buffers[i].linear_copy)
2874cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
288cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (dri2_surf->color_buffers[i].data)
289cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         munmap(dri2_surf->color_buffers[i].data,
290cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                dri2_surf->color_buffers[i].data_size);
29187dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke
29290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->color_buffers[i].wl_buffer = NULL;
293664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg      dri2_surf->color_buffers[i].dri_image = NULL;
2944cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_surf->color_buffers[i].linear_copy = NULL;
295cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->color_buffers[i].data = NULL;
29690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->color_buffers[i].locked = 0;
29787dde5b1cd596c4008695ff2db9469f88c09f925Benjamin Franzke   }
29811f64668a91259b876d6b6bccd902f875531502dBenjamin Franzke
299cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_dpy->dri2) {
300cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      for (i = 0; i < __DRI_BUFFER_COUNT; i++)
301cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         if (dri2_surf->dri_buffers[i] &&
302cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
303cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
304cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                          dri2_surf->dri_buffers[i]);
305cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
30651f2820922b669af3947fcedd17109524644bb94Benjamin Franzke}
30751f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
30890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergstatic int
30968bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergget_back_bo(struct dri2_egl_surface *dri2_surf)
31051f2820922b669af3947fcedd17109524644bb94Benjamin Franzke{
31151f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
31251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
313d943ac432de1f46cea47bdbf5ffe5365e2aef386Axel Davy   int i, use_flags;
3141e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   unsigned int dri_image_format;
3151e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy
3161e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   /* currently supports three WL DRM formats,
3171e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy    * WL_DRM_FORMAT_ARGB8888, WL_DRM_FORMAT_XRGB8888,
3181e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy    * and WL_DRM_FORMAT_RGB565
3191e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy    */
3201e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   switch (dri2_surf->format) {
3211e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_ARGB8888:
3221e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888;
3231e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      break;
3241e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_XRGB8888:
3251e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888;
3261e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      break;
3271e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_RGB565:
3281e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      dri_image_format = __DRI_IMAGE_FORMAT_RGB565;
3291e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      break;
3301e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   default:
3311e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      /* format is not supported */
3321e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      return -1;
3331e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   }
33451f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
3359ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   /* There might be a buffer release already queued that wasn't processed */
3369ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
3370cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
33890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back == NULL) {
33990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
340992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts         /* Get an unlocked buffer, preferrably one with a dri_buffer
341992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts          * already allocated. */
342992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts         if (dri2_surf->color_buffers[i].locked)
34390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg            continue;
34490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         if (dri2_surf->back == NULL)
345992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts            dri2_surf->back = &dri2_surf->color_buffers[i];
346664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         else if (dri2_surf->back->dri_image == NULL)
347992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts            dri2_surf->back = &dri2_surf->color_buffers[i];
34851f2820922b669af3947fcedd17109524644bb94Benjamin Franzke      }
34951f2820922b669af3947fcedd17109524644bb94Benjamin Franzke   }
3500cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
35190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (dri2_surf->back == NULL)
35290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
3534cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
354d943ac432de1f46cea47bdbf5ffe5365e2aef386Axel Davy   use_flags = __DRI_IMAGE_USE_SHARE | __DRI_IMAGE_USE_BACKBUFFER;
355d943ac432de1f46cea47bdbf5ffe5365e2aef386Axel Davy
3564cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (dri2_dpy->is_different_gpu &&
3574cd546df82c557b9a765e40db2f96c4faa299846Axel Davy       dri2_surf->back->linear_copy == NULL) {
3584cd546df82c557b9a765e40db2f96c4faa299846Axel Davy       dri2_surf->back->linear_copy =
3594cd546df82c557b9a765e40db2f96c4faa299846Axel Davy          dri2_dpy->image->createImage(dri2_dpy->dri_screen,
3604cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      dri2_surf->base.Width,
3614cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      dri2_surf->base.Height,
3624cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      dri_image_format,
363d943ac432de1f46cea47bdbf5ffe5365e2aef386Axel Davy                                      use_flags |
3644cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      __DRI_IMAGE_USE_LINEAR,
3654cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      NULL);
3664cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      if (dri2_surf->back->linear_copy == NULL)
3674cd546df82c557b9a765e40db2f96c4faa299846Axel Davy          return -1;
3684cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
3694cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
370664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   if (dri2_surf->back->dri_image == NULL) {
371052b3d4e2f159038137504f01e9ff2380a67af8bBoyan Ding      dri2_surf->back->dri_image =
372664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         dri2_dpy->image->createImage(dri2_dpy->dri_screen,
373664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg                                      dri2_surf->base.Width,
374664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg                                      dri2_surf->base.Height,
3751e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy                                      dri_image_format,
3764cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                      dri2_dpy->is_different_gpu ?
377d943ac432de1f46cea47bdbf5ffe5365e2aef386Axel Davy                                         0 : use_flags,
378664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg                                      NULL);
3796d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      dri2_surf->back->age = 0;
38090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
381664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   if (dri2_surf->back->dri_image == NULL)
38290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
3830cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
38468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   dri2_surf->back->locked = 1;
38568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
38668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   return 0;
38768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg}
38868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
38968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
39068bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergstatic void
39168bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergback_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
39268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg{
39368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   struct dri2_egl_display *dri2_dpy =
39468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
39568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   __DRIimage *image;
39668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   int name, pitch;
39768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
398664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   image = dri2_surf->back->dri_image;
399664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg
400664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
401664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
402664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg
403664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   buffer->attachment = __DRI_BUFFER_BACK_LEFT;
404664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   buffer->name = name;
405664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   buffer->pitch = pitch;
406664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   buffer->cpp = 4;
407664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg   buffer->flags = 0;
4080cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
4090cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
41090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergstatic int
41190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsbergget_aux_bo(struct dri2_egl_surface *dri2_surf,
41290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg	   unsigned int attachment, unsigned int format, __DRIbuffer *buffer)
4130cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke{
41490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   struct dri2_egl_display *dri2_dpy =
41590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
41690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   __DRIbuffer *b = dri2_surf->dri_buffers[attachment];
41790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg
41890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (b == NULL) {
41990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
42090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 attachment, format,
42190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 dri2_surf->base.Width,
42290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg					 dri2_surf->base.Height);
42390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      dri2_surf->dri_buffers[attachment] = b;
42490804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
42590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (b == NULL)
42690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      return -1;
4270cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
42890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   memcpy(buffer, b, sizeof *buffer);
4290cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
43090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   return 0;
4310cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke}
4320cb356dd5c93f745bb1b17987d206a24ab708f31Benjamin Franzke
43368bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergstatic int
43468bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergupdate_buffers(struct dri2_egl_surface *dri2_surf)
43593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
43693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy =
43793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_egl_display(dri2_surf->base.Resource.Display);
43868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   int i;
43960a11e295b86475ff334291a5b483e422371b21cAnder Conselvan de Oliveira
440cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy   if (dri2_surf->base.Width != dri2_surf->wl_win->width ||
441cd25e52f6bb5279cd7b1992e5907df3966b900ceAxel Davy       dri2_surf->base.Height != dri2_surf->wl_win->height) {
44251f2820922b669af3947fcedd17109524644bb94Benjamin Franzke
443d019cd81b566649e9dbe157266f70841a10e00faChad Versace      dri2_wl_release_buffers(dri2_surf);
44493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
44593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Width  = dri2_surf->wl_win->width;
44693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->base.Height = dri2_surf->wl_win->height;
44793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dx = dri2_surf->wl_win->dx;
44893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      dri2_surf->dy = dri2_surf->wl_win->dy;
44990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   }
45093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   if (get_back_bo(dri2_surf) < 0) {
45268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
45368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      return -1;
45493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
45593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
45690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   /* If we have an extra unlocked buffer at this point, we had to do triple
45790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg    * buffering for a while, but now can go back to just double buffering.
45890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg    * That means we can free any unlocked buffer now. */
45990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
46090804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg      if (!dri2_surf->color_buffers[i].locked &&
46190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg          dri2_surf->color_buffers[i].wl_buffer) {
46290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
463664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
4644cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         if (dri2_dpy->is_different_gpu)
4654cd546df82c557b9a765e40db2f96c4faa299846Axel Davy            dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
46690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg         dri2_surf->color_buffers[i].wl_buffer = NULL;
467664fe6dc844358dbc5474aa4e936c6180e86f144Kristian Høgsberg         dri2_surf->color_buffers[i].dri_image = NULL;
4684cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         dri2_surf->color_buffers[i].linear_copy = NULL;
46993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      }
47093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
47193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
47268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   return 0;
47368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg}
47468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
47568bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergstatic __DRIbuffer *
476d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable,
477d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                int *width, int *height,
478d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                unsigned int *attachments, int count,
479d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                int *out_count, void *loaderPrivate)
48068bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg{
48168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = loaderPrivate;
48268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   int i, j;
48368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
48468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   if (update_buffers(dri2_surf) < 0)
48568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      return NULL;
48668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
48768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
48868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      switch (attachments[i]) {
48968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      case __DRI_BUFFER_BACK_LEFT:
49068bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg         back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
49168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	 break;
49268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      default:
49368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	 if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
49468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg			&dri2_surf->buffers[j]) < 0) {
49568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	    _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
49668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	    return NULL;
49768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	 }
49868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg	 break;
49968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      }
50068bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   }
50168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
50290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   *out_count = j;
50390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   if (j == 0)
50493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke	   return NULL;
50593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *width = dri2_surf->base.Width;
50793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   *height = dri2_surf->base.Height;
50893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
50993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return dri2_surf->buffers;
51093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
51193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
51293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic __DRIbuffer *
513d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_get_buffers(__DRIdrawable * driDrawable,
514d019cd81b566649e9dbe157266f70841a10e00faChad Versace                    int *width, int *height,
515d019cd81b566649e9dbe157266f70841a10e00faChad Versace                    unsigned int *attachments, int count,
516d019cd81b566649e9dbe157266f70841a10e00faChad Versace                    int *out_count, void *loaderPrivate)
51793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
5181e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   struct dri2_egl_surface *dri2_surf = loaderPrivate;
51993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   unsigned int *attachments_with_format;
52093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   __DRIbuffer *buffer;
5211e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   unsigned int bpp;
5221e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy
52393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   int i;
52493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
5251e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   switch (dri2_surf->format) {
5261e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_ARGB8888:
5271e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_XRGB8888:
5281e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      bpp = 32;
5291e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      break;
5301e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   case WL_DRM_FORMAT_RGB565:
5311e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      bpp = 16;
5321e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      break;
5331e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   default:
5341e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      /* format is not supported */
5351e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      return NULL;
5361e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy   }
5371e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy
538ecc89e4e42c0eda41de5a37d9d0614d0846e3a3eCarl Worth   attachments_with_format = calloc(count, 2 * sizeof(unsigned int));
53993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!attachments_with_format) {
54093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      *out_count = 0;
54193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return NULL;
54293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
54393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   for (i = 0; i < count; ++i) {
54593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      attachments_with_format[2*i] = attachments[i];
5461e96eece300bbd2dd621a4941a4418222bb4c8e5Vivek Kasireddy      attachments_with_format[2*i + 1] = bpp;
54793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
54893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
54993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   buffer =
550d019cd81b566649e9dbe157266f70841a10e00faChad Versace      dri2_wl_get_buffers_with_format(driDrawable,
551d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                      width, height,
552d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                      attachments_with_format, count,
553d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                      out_count, loaderPrivate);
55493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(attachments_with_format);
55693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
55793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return buffer;
55893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
55993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
56068bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergstatic int
56168bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergimage_get_buffers(__DRIdrawable *driDrawable,
56268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                  unsigned int format,
56368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                  uint32_t *stamp,
56468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                  void *loaderPrivate,
56568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                  uint32_t buffer_mask,
56668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                  struct __DRIimageList *buffers)
56768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg{
56868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = loaderPrivate;
56968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
57068bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   if (update_buffers(dri2_surf) < 0)
57168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg      return 0;
57268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
57368bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
57468bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   buffers->back = dri2_surf->back->dri_image;
57568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
57668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   return 1;
57768bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg}
57868bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
57993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
580d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
58193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
58293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) driDrawable;
58393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   (void) loaderPrivate;
58493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
58593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
586d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikovstatic const __DRIdri2LoaderExtension dri2_loader_extension = {
587d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov   .base = { __DRI_DRI2_LOADER, 3 },
588d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov
589d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov   .getBuffers           = dri2_wl_get_buffers,
590d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov   .flushFrontBuffer     = dri2_wl_flush_front_buffer,
591d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov   .getBuffersWithFormat = dri2_wl_get_buffers_with_format,
592d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov};
593d2d579da7e1ebd7bc33e7c84921eedc8b8208cdaEmil Velikov
59468bb26bead333764f140225926a9123f38b567a3Kristian Høgsbergstatic const __DRIimageLoaderExtension image_loader_extension = {
5959e627ccc0dea03d83c80c56532664ee0a1cb5085Emil Velikov   .base = { __DRI_IMAGE_LOADER, 1 },
5969e627ccc0dea03d83c80c56532664ee0a1cb5085Emil Velikov
5979e627ccc0dea03d83c80c56532664ee0a1cb5085Emil Velikov   .getBuffers          = image_get_buffers,
598d019cd81b566649e9dbe157266f70841a10e00faChad Versace   .flushFrontBuffer    = dri2_wl_flush_front_buffer,
59968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg};
60068bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
60193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic void
602992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Robertswayland_throttle_callback(void *data,
603992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                          struct wl_callback *callback,
604992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                          uint32_t time)
60593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
60693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = data;
60793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
608992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   dri2_surf->throttle_callback = NULL;
6096602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg   wl_callback_destroy(callback);
61093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
61193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
612992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Robertsstatic const struct wl_callback_listener throttle_listener = {
6135567494403938940f61d44888c436a20a6635ef3Emil Velikov   .done = wayland_throttle_callback
6146602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg};
6156602bda23ba6c4351eb7f04d34803103a68ac2dbKristian Høgsberg
616de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsbergstatic void
617de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsbergcreate_wl_buffer(struct dri2_egl_surface *dri2_surf)
618de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg{
619de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   struct dri2_egl_display *dri2_dpy =
620de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      dri2_egl_display(dri2_surf->base.Resource.Display);
6214cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   __DRIimage *image;
62268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   int fd, stride, name;
623de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
624de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   if (dri2_surf->current->wl_buffer != NULL)
625de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      return;
626de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
6274cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (dri2_dpy->is_different_gpu) {
6284cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      image = dri2_surf->current->linear_copy;
6294cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   } else {
6304cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      image = dri2_surf->current->dri_image;
6314cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
632de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
6334cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd);
6344cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
635de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
636de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      dri2_surf->current->wl_buffer =
637de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg         wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
638de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    fd,
639de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    dri2_surf->base.Width,
640de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    dri2_surf->base.Height,
641de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    dri2_surf->format,
64268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                                    0, stride,
643de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    0, 0,
644de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                                    0, 0);
645de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      close(fd);
646de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   } else {
6474cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
6484cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
64968bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg
650de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      dri2_surf->current->wl_buffer =
651de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg         wl_drm_create_buffer(dri2_dpy->wl_drm,
65268bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                              name,
653de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                              dri2_surf->base.Width,
654de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                              dri2_surf->base.Height,
65568bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg                              stride,
656de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                              dri2_surf->format);
657de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   }
658de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
659de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   wl_proxy_set_queue((struct wl_proxy *) dri2_surf->current->wl_buffer,
660de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                      dri2_dpy->wl_queue);
661de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   wl_buffer_add_listener(dri2_surf->current->wl_buffer,
662de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg                          &wl_buffer_listener, dri2_surf);
663de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg}
664de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
665d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foremanstatic EGLBoolean
666d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foremantry_damage_buffer(struct dri2_egl_surface *dri2_surf,
667d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                  const EGLint *rects,
668d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                  EGLint n_rects)
669d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman{
670d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   int i;
671d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman
672d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   if (wl_proxy_get_version((struct wl_proxy *) dri2_surf->wl_win->surface)
673d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman       < WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
674d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman      return EGL_FALSE;
675d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman
676d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   for (i = 0; i < n_rects; i++) {
677d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman      const int *rect = &rects[i * 4];
678d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman
679d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman      wl_surface_damage_buffer(dri2_surf->wl_win->surface,
680d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                               rect[0],
681d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                               dri2_surf->base.Height - rect[1] - rect[3],
682d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                               rect[2], rect[3]);
683d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   }
684d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   return EGL_TRUE;
685d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman}
68693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke/**
68793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke * Called via eglSwapBuffers(), drv->API.SwapBuffers().
68893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke */
68993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzkestatic EGLBoolean
690d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_swap_buffers_with_damage(_EGLDriver *drv,
691d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                 _EGLDisplay *disp,
692d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                 _EGLSurface *draw,
693d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                 const EGLint *rects,
694d019cd81b566649e9dbe157266f70841a10e00faChad Versace                                 EGLint n_rects)
69593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
69693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
69793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
69825cc889004aad6d1cab9edd76db898658e347b97Neil Roberts   int i;
69993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7009ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   while (dri2_surf->throttle_callback != NULL)
7019ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone      if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
7029ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone                                    dri2_dpy->wl_queue) == -1)
7039ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone         return -1;
7049ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone
7056d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
7066d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      if (dri2_surf->color_buffers[i].age > 0)
7076d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg         dri2_surf->color_buffers[i].age++;
7086d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
7091fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg   /* Make sure we have a back buffer in case we're swapping without ever
7101fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg    * rendering. */
71168bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   if (get_back_bo(dri2_surf) < 0) {
7121fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
7131fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg      return EGL_FALSE;
7141fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg   }
7151fe007399c1ed28b8cef9d4f040164480423f2c9Kristian Høgsberg
716992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   if (draw->SwapInterval > 0) {
717992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_surf->throttle_callback =
718992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts         wl_surface_frame(dri2_surf->wl_win->surface);
719992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      wl_callback_add_listener(dri2_surf->throttle_callback,
720992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                               &throttle_listener, dri2_surf);
721992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback,
722992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                         dri2_dpy->wl_queue);
723992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   }
72425cc889004aad6d1cab9edd76db898658e347b97Neil Roberts
7256d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   dri2_surf->back->age = 1;
72690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->current = dri2_surf->back;
72790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->back = NULL;
72890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg
729de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   create_wl_buffer(dri2_surf);
73093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
73190804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   wl_surface_attach(dri2_surf->wl_win->surface,
73290804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                     dri2_surf->current->wl_buffer,
73390804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg                     dri2_surf->dx, dri2_surf->dy);
73493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
73590804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
73690804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
73790804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   /* reset resize growing parameters */
73890804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->dx = 0;
73990804e886de892cfedb8248a4f5700fd7422b94aKristian Høgsberg   dri2_surf->dy = 0;
74093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
741d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   /* If the compositor doesn't support damage_buffer, we deliberately
742d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman    * ignore the damage region and post maximum damage, due to
743d1314de293e9e4a63c35f094c3893aaaed8580b4Daniel Stone    * https://bugs.freedesktop.org/78190 */
744d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman   if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
745d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman      wl_surface_damage(dri2_surf->wl_win->surface,
746d085a5dff5bf753b82228ef0827f2331aff7b35bDerek Foreman                        0, 0, INT32_MAX, INT32_MAX);
7470229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
7484cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (dri2_dpy->is_different_gpu) {
7494cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      _EGLContext *ctx = _eglGetCurrentContext();
7504cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
7514cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->image->blitImage(dri2_ctx->dri_context,
7524cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 dri2_surf->current->linear_copy,
7534cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 dri2_surf->current->dri_image,
7544cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 0, 0, dri2_surf->base.Width,
7554cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 dri2_surf->base.Height,
7564cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 0, 0, dri2_surf->base.Width,
7574cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                 dri2_surf->base.Height, 0);
7584cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
7594cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
76070e8ccc459d9bf579ad7efeae453cb8641266c94Eric Anholt   dri2_flush_drawable_for_swapbuffers(disp, draw);
761868ae3e31b0e479b299188d0047c88f0d260c6ecBoyan Ding   dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
76293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
76333eb5eabeec0c17e81b6bb11be703701e4025d4eKristian Høgsberg   wl_surface_commit(dri2_surf->wl_win->surface);
764992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
765992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   /* If we're not waiting for a frame callback then we'll at least throttle
766992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * to a sync callback so that we always give a chance for the compositor to
767992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * handle the commit and send a release event before checking for a free
768992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * buffer */
769992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   if (dri2_surf->throttle_callback == NULL) {
77036b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl      dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy_wrapper);
771992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      wl_callback_add_listener(dri2_surf->throttle_callback,
772992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                               &throttle_listener, dri2_surf);
773992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   }
774992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
775402bf6e8d098b64390277b229f7fae769e4449e5Axel Davy   wl_display_flush(dri2_dpy->wl_dpy);
776402bf6e8d098b64390277b229f7fae769e4449e5Axel Davy
77793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
77893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
77993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
7806d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsbergstatic EGLint
781d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_query_buffer_age(_EGLDriver *drv,
782d019cd81b566649e9dbe157266f70841a10e00faChad Versace                         _EGLDisplay *disp, _EGLSurface *surface)
7836d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg{
7846d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
7856d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
78668bb26bead333764f140225926a9123f38b567a3Kristian Høgsberg   if (get_back_bo(dri2_surf) < 0) {
7876d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
7886d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg      return 0;
7896d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   }
7906d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
7916d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   return dri2_surf->back->age;
7926d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg}
7936d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg
794f8c324268223611ce7d14c4109faed4ab0eb3798Robert Braggstatic EGLBoolean
795d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
796f8c324268223611ce7d14c4109faed4ab0eb3798Robert Bragg{
797d019cd81b566649e9dbe157266f70841a10e00faChad Versace   return dri2_wl_swap_buffers_with_damage (drv, disp, draw, NULL, 0);
798f8c324268223611ce7d14c4109faed4ab0eb3798Robert Bragg}
799f8c324268223611ce7d14c4109faed4ab0eb3798Robert Bragg
8005cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Robertsstatic struct wl_buffer *
801eadd5e0c0a3c4b24c25e6368ea0a8352a8fd0701Chad Versacedri2_wl_create_wayland_buffer_from_image(_EGLDriver *drv,
802eadd5e0c0a3c4b24c25e6368ea0a8352a8fd0701Chad Versace                                          _EGLDisplay *disp,
803eadd5e0c0a3c4b24c25e6368ea0a8352a8fd0701Chad Versace                                          _EGLImage *img)
8045cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts{
8055cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
8065cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   struct dri2_egl_image *dri2_img = dri2_egl_image(img);
8075cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   __DRIimage *image = dri2_img->dri_image;
8085cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   struct wl_buffer *buffer;
8095cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   int width, height, format, pitch;
8105cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   enum wl_drm_format wl_format;
8115cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8125cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
8135cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8145cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   switch (format) {
8155cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   case __DRI_IMAGE_FORMAT_ARGB8888:
8165cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      if (!(dri2_dpy->formats & HAS_ARGB8888))
8175cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts         goto bad_format;
8185cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      wl_format = WL_DRM_FORMAT_ARGB8888;
8195cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      break;
8205cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   case __DRI_IMAGE_FORMAT_XRGB8888:
8215cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      if (!(dri2_dpy->formats & HAS_XRGB8888))
8225cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts         goto bad_format;
8235cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      wl_format = WL_DRM_FORMAT_XRGB8888;
8245cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      break;
8255cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   default:
8265cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      goto bad_format;
8275cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   }
8285cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8295cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
8305cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height);
8315cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
8325cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8335cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
8345cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      int fd;
8355cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8365cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd);
8375cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8385cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      buffer =
8395cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts         wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
8405cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    fd,
8415cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    width, height,
8425cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    wl_format,
8435cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    0, pitch,
8445cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    0, 0,
8455cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                                    0, 0);
8465cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8475cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      close(fd);
8485cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   } else {
8495cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      int name;
8505cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8515cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
8525cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8535cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      buffer =
8545cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts         wl_drm_create_buffer(dri2_dpy->wl_drm,
8555cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                              name,
8565cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                              width, height,
8575cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                              pitch,
8585cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts                              wl_format);
8595cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   }
8605cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8615cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   /* The buffer object will have been created with our internal event queue
8625cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts    * because it is using the wl_drm object as a proxy factory. We want the
8635cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts    * buffer to be used by the application so we'll reset it to the display's
8645cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts    * default event queue */
8655cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   if (buffer)
8665cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts      wl_proxy_set_queue((struct wl_proxy *) buffer, NULL);
8675cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8685cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   return buffer;
8695cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8705cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Robertsbad_format:
8715cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   _eglError(EGL_BAD_MATCH, "unsupported image format");
8725cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts   return NULL;
8735cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts}
8745cddb1ce3c9890435374ae3e03fc4a5b57dee314Neil Roberts
8756b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzkestatic int
876d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_authenticate(_EGLDisplay *disp, uint32_t id)
8776b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
8786b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
8796b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   int ret = 0;
8806b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
881fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   if (dri2_dpy->is_render_node) {
882fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      _eglLog(_EGL_WARNING, "wayland-egl: client asks server to "
883fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy                            "authenticate for render-nodes");
884fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      return 0;
885fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   }
886aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 0;
8876b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
888c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_authenticate(dri2_dpy->wl_drm, id);
8890229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0)
8900229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      ret = -1;
8916b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
892c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->authenticated)
8936b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke      ret = -1;
8946b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
8956b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /* reset authenticated */
896aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
8976b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
8986b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   return ret;
8996b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke}
9006b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
901c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
902c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
903c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
904c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
905c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   drm_magic_t magic;
906c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
907c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   dri2_dpy->device_name = strdup(device);
908c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (!dri2_dpy->device_name)
909c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
910c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
9114f8f790525f1adcb5259cb72b7c9dbfd121867c6Derek Foreman   dri2_dpy->fd = loader_open_device(dri2_dpy->device_name);
912c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   if (dri2_dpy->fd == -1) {
913c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
914c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg	      dri2_dpy->device_name, strerror(errno));
915c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      return;
916c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   }
917c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
918175d9752796bbcc52f1df90b1466c879bccfc406Emil Velikov   if (drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER) {
919fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      dri2_dpy->authenticated = 1;
920fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   } else {
921fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      drmGetMagic(dri2_dpy->fd, &magic);
922fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      wl_drm_authenticate(dri2_dpy->wl_drm, magic);
923fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   }
924c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
925c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
926c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic void
9277b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergdrm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
9287b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg{
9297b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
9307b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
9317b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   switch (format) {
93258dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_ARGB8888:
93358dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_ARGB8888;
9347b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
93558dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg   case WL_DRM_FORMAT_XRGB8888:
93658dc1b28d1ef4d1931c52b079d304f2e1546329dKristian Høgsberg      dri2_dpy->formats |= HAS_XRGB8888;
9377b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg      break;
9382efc97d51300849636b4b64ef8dfb5645e3b4e5bSingh, Satyeshwar   case WL_DRM_FORMAT_RGB565:
9392efc97d51300849636b4b64ef8dfb5645e3b4e5bSingh, Satyeshwar      dri2_dpy->formats |= HAS_RGB565;
9402efc97d51300849636b4b64ef8dfb5645e3b4e5bSingh, Satyeshwar      break;
9417b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
9427b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg}
9437b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg
9447b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsbergstatic void
945de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsbergdrm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
946de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg{
947de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
948de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
949de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   dri2_dpy->capabilities = value;
950de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg}
951de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg
952de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsbergstatic void
953c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergdrm_handle_authenticated(void *data, struct wl_drm *drm)
954c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg{
955c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
956c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
957aa87a938fb4cec30dad48642e8d12810e947bc8bBenjamin Franzke   dri2_dpy->authenticated = 1;
958c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg}
959c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
960c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsbergstatic const struct wl_drm_listener drm_listener = {
9615567494403938940f61d44888c436a20a6635ef3Emil Velikov   .device = drm_handle_device,
9625567494403938940f61d44888c436a20a6635ef3Emil Velikov   .format = drm_handle_format,
9635567494403938940f61d44888c436a20a6635ef3Emil Velikov   .authenticated = drm_handle_authenticated,
9645567494403938940f61d44888c436a20a6635ef3Emil Velikov   .capabilities = drm_handle_capabilities
965c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg};
966c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg
9670229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsbergstatic void
968cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyregistry_handle_global_drm(void *data, struct wl_registry *registry, uint32_t name,
9690229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg		       const char *interface, uint32_t version)
9700229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg{
9710229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   struct dri2_egl_display *dri2_dpy = data;
9720229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
973de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg   if (version > 1)
974de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg      version = 2;
9750229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (strcmp(interface, "wl_drm") == 0) {
9760229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      dri2_dpy->wl_drm =
977de315f76a266ce51ca0638b9ea2ec3ccfd31f03bKristian Høgsberg         wl_registry_bind(registry, name, &wl_drm_interface, version);
9780229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg      wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
9790229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   }
9800229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg}
9810229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
982712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsbergstatic void
983712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsbergregistry_handle_global_remove(void *data, struct wl_registry *registry,
984712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsberg			      uint32_t name)
985712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsberg{
986712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsberg}
987712269d6744a8849d1d0cf01fa0132d969b79ed4Kristian Høgsberg
988cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic const struct wl_registry_listener registry_listener_drm = {
9895567494403938940f61d44888c436a20a6635ef3Emil Velikov   .global = registry_handle_global_drm,
9905567494403938940f61d44888c436a20a6635ef3Emil Velikov   .global_remove = registry_handle_global_remove
9910229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg};
9920229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
993992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Robertsstatic EGLBoolean
994d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_swap_interval(_EGLDriver *drv,
995992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                   _EGLDisplay *disp,
996992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                   _EGLSurface *surf,
997992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                   EGLint interval)
998992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts{
999992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   if (interval > surf->Config->MaxSwapInterval)
1000992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      interval = surf->Config->MaxSwapInterval;
1001992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   else if (interval < surf->Config->MinSwapInterval)
1002992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      interval = surf->Config->MinSwapInterval;
1003992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
1004992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   surf->SwapInterval = interval;
1005992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
1006992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   return EGL_TRUE;
1007992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts}
1008992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
1009992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Robertsstatic void
1010d019cd81b566649e9dbe157266f70841a10e00faChad Versacedri2_wl_setup_swap_interval(struct dri2_egl_display *dri2_dpy)
1011992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts{
1012992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
1013992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
1014992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   /* We can't use values greater than 1 on Wayland because we are using the
1015992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * frame callback to synchronise the frame and the only way we be sure to
1016992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * get a frame callback is to attach a new buffer. Therefore we can't just
1017992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts    * sit drawing nothing to wait until the next ‘n’ frame callbacks */
1018992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
1019992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   if (dri2_dpy->config)
1020992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->config->configQueryi(dri2_dpy->dri_screen,
1021992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts                                     "vblank_mode", &vblank_mode);
1022992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   switch (vblank_mode) {
1023992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   case DRI_CONF_VBLANK_NEVER:
1024992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->min_swap_interval = 0;
1025992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->max_swap_interval = 0;
1026992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->default_swap_interval = 0;
1027992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      break;
1028992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   case DRI_CONF_VBLANK_ALWAYS_SYNC:
1029992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->min_swap_interval = 1;
1030992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->max_swap_interval = 1;
1031992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->default_swap_interval = 1;
1032992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      break;
1033992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   case DRI_CONF_VBLANK_DEF_INTERVAL_0:
1034992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->min_swap_interval = 0;
1035992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->max_swap_interval = 1;
1036992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->default_swap_interval = 0;
1037992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      break;
1038992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   default:
1039992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   case DRI_CONF_VBLANK_DEF_INTERVAL_1:
1040992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->min_swap_interval = 0;
1041992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->max_swap_interval = 1;
1042992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      dri2_dpy->default_swap_interval = 1;
1043992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts      break;
1044992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts   }
1045992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts}
1046992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
104790502b18b2b868250ab7e9189810ca42b3c812a1Chad Versacestatic struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
1048d019cd81b566649e9dbe157266f70841a10e00faChad Versace   .authenticate = dri2_wl_authenticate,
10490a0c881a13afc99c7a88bf16117850350ccb85dfChad Versace   .create_window_surface = dri2_wl_create_window_surface,
10509a40ee16d0be3a08ac2f467311673f4b9333191dChad Versace   .create_pixmap_surface = dri2_wl_create_pixmap_surface,
1051bf20076bafcf0809529ae470fb12af5eae12b33dChad Versace   .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface,
1052958dd80c40dc87545b49d09cb2e4415a30746004Chad Versace   .destroy_surface = dri2_wl_destroy_surface,
1053eef68a9094396ee85f73a94911f8919d232b9a08Chad Versace   .create_image = dri2_create_image_khr,
10548b9298af0a3bce1360cc2c020b31470b37b660feChad Versace   .swap_interval = dri2_wl_swap_interval,
1055ad173bcfdbeaa52d6a024cd7ef6c068c5a999ba2Chad Versace   .swap_buffers = dri2_wl_swap_buffers,
1056d03948a76634392455ae53fbf975d09c58bfc7aaChad Versace   .swap_buffers_with_damage = dri2_wl_swap_buffers_with_damage,
105775d398ed9309c0cb8179380bd317d8f935618df7Chad Versace   .swap_buffers_region = dri2_fallback_swap_buffers_region,
1058688a0e8e73b916438878b4fc2271453ee79ec7a6Chad Versace   .post_sub_buffer = dri2_fallback_post_sub_buffer,
1059bc2cbc0951ded883dc610672a6f6d4cca5d99502Chad Versace   .copy_buffers = dri2_fallback_copy_buffers,
10603fdfbd2572ea42f3ef71db032b31cc87ea274e11Chad Versace   .query_buffer_age = dri2_wl_query_buffer_age,
1061eadd5e0c0a3c4b24c25e6368ea0a8352a8fd0701Chad Versace   .create_wayland_buffer_from_image = dri2_wl_create_wayland_buffer_from_image,
1062c524f3ef9155caba6cd4f9fc72485426b1da76fdSarah Sharp   .get_sync_values = dri2_fallback_get_sync_values,
1063a25df5457121d40fef86929d4c10d8058a4d5c72Boyan Ding   .get_dri_drawable = dri2_surface_get_dri_drawable,
106490502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace};
106590502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace
1066f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikovstatic const __DRIextension *dri2_loader_extensions[] = {
1067f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &dri2_loader_extension.base,
1068534ea2b5ba0282a350dc02d21bfbc8ffa1f8635dDerek Foreman   &image_loader_extension.base,
1069f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &image_lookup_extension.base,
1070f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &use_invalidate.base,
1071f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   NULL,
1072f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov};
1073f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov
1074f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikovstatic const __DRIextension *image_loader_extensions[] = {
1075f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &image_loader_extension.base,
1076f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &image_lookup_extension.base,
1077f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &use_invalidate.base,
1078f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   NULL,
1079f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov};
1080f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov
1081cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic EGLBoolean
10820b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikovdri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
10830b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov{
10840b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
10850b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   static const struct {
10860b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      const char *format_name;
10870b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      int has_format;
10880b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      unsigned int rgba_masks[4];
10890b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   } visuals[] = {
10900b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      { "XRGB8888", HAS_XRGB8888, { 0xff0000, 0xff00, 0x00ff, 0xff000000 } },
10910b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      { "ARGB8888", HAS_ARGB8888, { 0xff0000, 0xff00, 0x00ff, 0 } },
10920b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      { "RGB565",   HAS_RGB565,   { 0x00f800, 0x07e0, 0x001f, 0 } },
10930b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   };
10940b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
10950b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   unsigned int count, i, j;
10960b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
10970b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   count = 0;
10980b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
10990b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      for (j = 0; j < ARRAY_SIZE(visuals); j++) {
11000b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         struct dri2_egl_config *dri2_conf;
11010b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
11020b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         if (!(dri2_dpy->formats & visuals[j].has_format))
11030b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov            continue;
11040b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
11050b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
11060b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov               count + 1, EGL_WINDOW_BIT, NULL, visuals[j].rgba_masks);
11070b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         if (dri2_conf) {
11080b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov            count++;
11090b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov            format_count[j]++;
11100b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         }
11110b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      }
11120b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   }
11130b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
11140b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   for (i = 0; i < ARRAY_SIZE(format_count); i++) {
11150b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      if (!format_count[i]) {
11160b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov         _eglLog(_EGL_DEBUG, "No DRI config supports native format %s",
11170b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov                 visuals[i].format_name);
11180b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      }
11190b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   }
11200b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
11210b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   return (count != 0);
11220b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov}
11230b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov
11240b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikovstatic EGLBoolean
1125cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
112693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke{
112793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   struct dri2_egl_display *dri2_dpy;
112893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
11298d4357b5ba9e224ffe02e2457a2f4ffe2915f608Emil Velikov   loader_set_logger(_eglLog);
11308d4357b5ba9e224ffe02e2457a2f4ffe2915f608Emil Velikov
11316bda027e01c15df24d36de5bf3838ea8ed7e9e56Matt Turner   dri2_dpy = calloc(1, sizeof *dri2_dpy);
113293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_dpy)
113393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
113493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
113593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   disp->DriverData = (void *) dri2_dpy;
1136b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   if (disp->PlatformDisplay == NULL) {
1137b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = wl_display_connect(NULL);
1138b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      if (dri2_dpy->wl_dpy == NULL)
1139b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke         goto cleanup_dpy;
11402a58453e25899e726f02db005de0e1296c326845Benjamin Franzke      dri2_dpy->own_device = 1;
1141b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   } else {
1142b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke      dri2_dpy->wl_dpy = disp->PlatformDisplay;
1143b8325fd2554aafde3d0b784b7944b1473af7d144Benjamin Franzke   }
114493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
11450229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
1146112ccfab44eb3e23a516209c3be8b2f0107adb47Kristian Høgsberg
114736b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   dri2_dpy->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy);
114836b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   if (dri2_dpy->wl_dpy_wrapper == NULL)
114936b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl      goto cleanup_dpy_wrapper;
115036b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl
115136b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper,
115236b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl                      dri2_dpy->wl_queue);
115336b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl
1154112ccfab44eb3e23a516209c3be8b2f0107adb47Kristian Høgsberg   if (dri2_dpy->own_device)
1155112ccfab44eb3e23a516209c3be8b2f0107adb47Kristian Høgsberg      wl_display_dispatch_pending(dri2_dpy->wl_dpy);
1156112ccfab44eb3e23a516209c3be8b2f0107adb47Kristian Høgsberg
115736b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper);
11580229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   wl_registry_add_listener(dri2_dpy->wl_registry,
1159cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                            &registry_listener_drm, dri2_dpy);
11600229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL)
11616aaf09b93b668a24b557e05195b9897e8cee8559Axel Davy      goto cleanup_registry;
11620229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg
11630229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1)
1164c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_drm;
116556758c839ff29bd168529535a4816bff3b79cde5Kristian Høgsberg
11660229e3ae41be109ac423b2eb2ddf79e24b799d60Kristian Høgsberg   if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated)
1167c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_fd;
116893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
11694cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
11704cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                               &dri2_dpy->is_different_gpu);
11714cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (dri2_dpy->is_different_gpu) {
11724cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      free(dri2_dpy->device_name);
11734cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
11744cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      if (!dri2_dpy->device_name) {
11754cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         _eglError(EGL_BAD_ALLOC, "wayland-egl: failed to get device name "
11764cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                                  "for requested GPU");
11774cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         goto cleanup_fd;
11784cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      }
11794cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
11804cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
11814cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   /* we have to do the check now, because loader_get_user_preferred_fd
11824cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * will return a render-node when the requested gpu is different
11834cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * to the server, but also if the client asks for the same gpu than
11844cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * the server by requesting its pci-id */
1185175d9752796bbcc52f1df90b1466c879bccfc406Emil Velikov   dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
11864cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
1187af7abc512c422183a761ce3d687086abe282fa74Emil Velikov   dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
118893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (dri2_dpy->driver_name == NULL) {
118993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
119093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_fd;
119193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   }
119293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
11936b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   if (!dri2_load_driver(disp))
1194c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg      goto cleanup_driver_name;
119593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1196fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   /* render nodes cannot use Gem names, and thus do not support
1197fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy    * the __DRI_DRI2_LOADER extension */
1198f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   if (!dri2_dpy->is_render_node)
1199f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov      dri2_dpy->loader_extensions = dri2_loader_extensions;
1200f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   else
1201f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov      dri2_dpy->loader_extensions = image_loader_extensions;
120293aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
120393aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   if (!dri2_create_screen(disp))
120493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke      goto cleanup_driver;
120593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1206d019cd81b566649e9dbe157266f70841a10e00faChad Versace   dri2_wl_setup_swap_interval(dri2_dpy);
1207992a2dbba80aba35efe83202e1013bd6143f0dbaNeil Roberts
12084cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   /* To use Prime, we must have _DRI_IMAGE v7 at least.
12094cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * createImageFromFds support indicates that Prime export/import
12104cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * is supported by the driver. Fall back to
12114cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * gem names if we don't have Prime support. */
12121670737436adc5eea6af860bff5035b52dc6c303Kristian Høgsberg
12131670737436adc5eea6af860bff5035b52dc6c303Kristian Høgsberg   if (dri2_dpy->image->base.version < 7 ||
12141670737436adc5eea6af860bff5035b52dc6c303Kristian Høgsberg       dri2_dpy->image->createImageFromFds == NULL)
121563d4661ab28c036ab000f94812a91d93d538a72aNeil Roberts      dri2_dpy->capabilities &= ~WL_DRM_CAPABILITY_PRIME;
12161670737436adc5eea6af860bff5035b52dc6c303Kristian Høgsberg
1217fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   /* We cannot use Gem names with render-nodes, only prime fds (dma-buf).
1218fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy    * The server needs to accept them */
1219fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   if (dri2_dpy->is_render_node &&
1220fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy       !(dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME)) {
1221fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      _eglLog(_EGL_WARNING, "wayland-egl: display is not render-node capable");
1222fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy      goto cleanup_screen;
1223fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   }
1224fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy
12254cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (dri2_dpy->is_different_gpu &&
12264cd546df82c557b9a765e40db2f96c4faa299846Axel Davy       (dri2_dpy->image->base.version < 9 ||
12274cd546df82c557b9a765e40db2f96c4faa299846Axel Davy        dri2_dpy->image->blitImage == NULL)) {
12284cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      _eglLog(_EGL_WARNING, "wayland-egl: Different GPU selected, but the "
12294cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                            "Image extension in the driver is not "
12304cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                            "compatible. Version 9 or later and blitImage() "
12314cd546df82c557b9a765e40db2f96c4faa299846Axel Davy                            "are required");
12324cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      goto cleanup_screen;
12334cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
12344cd546df82c557b9a765e40db2f96c4faa299846Axel Davy
12350b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   if (!dri2_wl_add_configs_for_visuals(drv, disp)) {
12360b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
12370b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      goto cleanup_screen;
12387b1d94e5d1f53ac5f59000176aea1d02fc9a1181Kristian Høgsberg   }
123993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
124098f5d0106a8ee45e58a6bf162720da3f6f614a95Emil Velikov   dri2_set_WL_bind_wayland_display(drv, disp);
12414cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   /* When cannot convert EGLImage to wl_buffer when on a different gpu,
12424cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * because the buffer of the EGLImage has likely a tiling mode the server
12434cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * gpu won't support. These is no way to check for now. Thus do not support the
12444cd546df82c557b9a765e40db2f96c4faa299846Axel Davy    * extension */
12454cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   if (!dri2_dpy->is_different_gpu) {
12464cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE;
12474cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   } else {
12484cd546df82c557b9a765e40db2f96c4faa299846Axel Davy      dri2_wl_display_vtbl.create_wayland_buffer_from_image =
12494cd546df82c557b9a765e40db2f96c4faa299846Axel Davy         dri2_fallback_create_wayland_buffer_from_image;
12504cd546df82c557b9a765e40db2f96c4faa299846Axel Davy   }
12516d4d4b00ddfbd3257ecd129fec5b813be7e36fe9Kristian Høgsberg   disp->Extensions.EXT_buffer_age = EGL_TRUE;
12526b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
1253f8c324268223611ce7d14c4109faed4ab0eb3798Robert Bragg   disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
1254f8c324268223611ce7d14c4109faed4ab0eb3798Robert Bragg
125590502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace   /* Fill vtbl last to prevent accidentally calling virtual function during
125690502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace    * initialization.
125790502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace    */
125890502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace   dri2_dpy->vtbl = &dri2_wl_display_vtbl;
125990502b18b2b868250ab7e9189810ca42b3c812a1Chad Versace
126093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_TRUE;
126193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke
1262fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy cleanup_screen:
1263fb0960a14bd6980aa63deef45ec3cf1ab99bcf0aAxel Davy   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
126493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver:
126593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   dlclose(dri2_dpy->driver);
126693aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_driver_name:
126793aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy->driver_name);
126893aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_fd:
126993aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   close(dri2_dpy->fd);
1270c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg cleanup_drm:
1271c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   free(dri2_dpy->device_name);
1272c0f8c9911c82c576cdd82dabad4a2370ac53565cKristian Høgsberg   wl_drm_destroy(dri2_dpy->wl_drm);
12736aaf09b93b668a24b557e05195b9897e8cee8559Axel Davy cleanup_registry:
12746aaf09b93b668a24b557e05195b9897e8cee8559Axel Davy   wl_registry_destroy(dri2_dpy->wl_registry);
127536b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper);
127636b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl cleanup_dpy_wrapper:
12776aaf09b93b668a24b557e05195b9897e8cee8559Axel Davy   wl_event_queue_destroy(dri2_dpy->wl_queue);
1278361796651c5abb21ff429466c061119dce8f33d5Jonas Ådahl   if (disp->PlatformDisplay == NULL)
1279361796651c5abb21ff429466c061119dce8f33d5Jonas Ådahl      wl_display_disconnect(dri2_dpy->wl_dpy);
128093aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke cleanup_dpy:
128193aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   free(dri2_dpy);
128248fd952f28a5fcd71eed5a60c8e3a10231c7a5b0Nicolas Boichat   disp->DriverData = NULL;
1283052b3d4e2f159038137504f01e9ff2380a67af8bBoyan Ding
128493aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke   return EGL_FALSE;
128593aea84f472f5f9ff588f7b2d4f7320ec43bc216Benjamin Franzke}
1286cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1287cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic int
1288cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_get_stride_for_format(int format, int w)
1289cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1290cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (format == WL_SHM_FORMAT_RGB565)
1291cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return 2 * w;
1292cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   else /* ARGB8888 || XRGB8888 */
1293cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return 4 * w;
1294cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1295cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1296cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy/*
1297cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * Taken from weston shared/os-compatibility.c
1298cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy */
1299cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1300d7bafcafd329d23ab0c76e3a6ae06277506f50f3Boyan Ding#ifndef HAVE_MKOSTEMP
1301d7bafcafd329d23ab0c76e3a6ae06277506f50f3Boyan Ding
1302cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic int
1303cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyset_cloexec_or_close(int fd)
1304cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1305cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   long flags;
1306cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1307cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fd == -1)
1308cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1309cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1310cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   flags = fcntl(fd, F_GETFD);
1311cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (flags == -1)
1312cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto err;
1313cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1314cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
1315cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto err;
1316cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1317cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return fd;
1318cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1319cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyerr:
1320cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   close(fd);
1321cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return -1;
1322cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1323cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1324d7bafcafd329d23ab0c76e3a6ae06277506f50f3Boyan Ding#endif
1325d7bafcafd329d23ab0c76e3a6ae06277506f50f3Boyan Ding
1326cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy/*
1327cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * Taken from weston shared/os-compatibility.c
1328cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy */
1329cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1330cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic int
1331cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davycreate_tmpfile_cloexec(char *tmpname)
1332cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1333cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int fd;
1334cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1335cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy#ifdef HAVE_MKOSTEMP
1336cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   fd = mkostemp(tmpname, O_CLOEXEC);
1337cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fd >= 0)
1338cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      unlink(tmpname);
1339cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy#else
1340cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   fd = mkstemp(tmpname);
1341cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fd >= 0) {
1342cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      fd = set_cloexec_or_close(fd);
1343cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      unlink(tmpname);
1344cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1345cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy#endif
1346cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1347cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return fd;
1348cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1349cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1350cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy/*
1351cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * Taken from weston shared/os-compatibility.c
1352cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy *
1353cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * Create a new, unique, anonymous file of the given size, and
1354cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * return the file descriptor for it. The file descriptor is set
1355cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * CLOEXEC. The file is immediately suitable for mmap()'ing
1356cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * the given size at offset zero.
1357cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy *
1358cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * The file should not have a permanent backing store like a disk,
1359cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
1360cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy *
1361cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * The file name is deleted from the file system.
1362cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy *
1363cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * The file is suitable for buffer sharing between processes by
1364cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * transmitting the file descriptor over Unix sockets using the
1365cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * SCM_RIGHTS methods.
1366cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy *
1367cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * If the C library implements posix_fallocate(), it is used to
1368cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * guarantee that disk space is available for the file at the
1369cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * given size. If disk space is insufficent, errno is set to ENOSPC.
1370cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * If posix_fallocate() is not supported, program may receive
1371cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy * SIGBUS on accessing mmap()'ed file contents instead.
1372cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy */
1373cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic int
1374cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyos_create_anonymous_file(off_t size)
1375cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1376cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   static const char template[] = "/mesa-shared-XXXXXX";
1377cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   const char *path;
1378cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   char *name;
1379cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int fd;
1380cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int ret;
1381cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1382cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   path = getenv("XDG_RUNTIME_DIR");
1383cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!path) {
1384cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      errno = ENOENT;
1385cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1386cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1387cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1388cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   name = malloc(strlen(path) + sizeof(template));
1389cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!name)
1390cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1391cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1392cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   strcpy(name, path);
1393cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   strcat(name, template);
1394cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1395cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   fd = create_tmpfile_cloexec(name);
1396cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1397cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   free(name);
1398cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1399cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fd < 0)
1400cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1401cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1402cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   ret = ftruncate(fd, size);
1403cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (ret < 0) {
1404cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      close(fd);
1405cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1406cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1407cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1408cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return fd;
1409cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1410cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1411cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1412cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic EGLBoolean
1413cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_allocate_buffer(struct dri2_egl_display *dri2_dpy,
1414cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               int format, int w, int h,
1415cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               void **data, int *size,
1416cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               struct wl_buffer **buffer)
1417cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1418cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct wl_shm_pool *pool;
1419cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int fd, stride, size_map;
1420cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   void *data_map;
1421cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1422cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   stride = dri2_wl_swrast_get_stride_for_format(format, w);
1423cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   size_map = h * stride;
1424cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1425cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* Create a sharable buffer */
1426cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   fd = os_create_anonymous_file(size_map);
1427cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (fd < 0)
1428cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return EGL_FALSE;
1429cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1430cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   data_map = mmap(NULL, size_map, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1431cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (data_map == MAP_FAILED) {
1432cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      close(fd);
1433cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return EGL_FALSE;
1434cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1435cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1436cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* Share it in a wl_buffer */
1437cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   pool = wl_shm_create_pool(dri2_dpy->wl_shm, fd, size_map);
1438cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *buffer = wl_shm_pool_create_buffer(pool, 0, w, h, stride, format);
1439cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_shm_pool_destroy(pool);
1440cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   close(fd);
1441cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1442cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *data = data_map;
1443cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *size = size_map;
1444cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return EGL_TRUE;
1445cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1446cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1447cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic int
1448cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyswrast_update_buffers(struct dri2_egl_surface *dri2_surf)
1449cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1450cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy =
1451cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_egl_display(dri2_surf->base.Resource.Display);
1452cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int i;
1453cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1454cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* we need to do the following operations only once per frame */
1455cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_surf->back)
1456cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return 0;
1457cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1458cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_surf->base.Width != dri2_surf->wl_win->width ||
1459cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy       dri2_surf->base.Height != dri2_surf->wl_win->height) {
1460cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1461cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_wl_release_buffers(dri2_surf);
1462cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1463cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->base.Width  = dri2_surf->wl_win->width;
1464cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->base.Height = dri2_surf->wl_win->height;
1465cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->dx = dri2_surf->wl_win->dx;
1466cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->dy = dri2_surf->wl_win->dy;
1467cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->current = NULL;
1468cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1469cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1470cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* find back buffer */
1471cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
14729ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   /* There might be a buffer release already queued that wasn't processed */
14739ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
1474cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1475cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* try get free buffer already created */
1476cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
1477cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (!dri2_surf->color_buffers[i].locked &&
1478cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy          dri2_surf->color_buffers[i].wl_buffer) {
1479cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy          dri2_surf->back = &dri2_surf->color_buffers[i];
1480cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy          break;
1481cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      }
1482cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1483cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1484cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* else choose any another free location */
1485cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_surf->back) {
1486cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
1487cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         if (!dri2_surf->color_buffers[i].locked) {
1488cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             dri2_surf->back = &dri2_surf->color_buffers[i];
1489cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             if (!dri2_wl_swrast_allocate_buffer(dri2_dpy,
1490cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 dri2_surf->format,
1491cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 dri2_surf->base.Width,
1492cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 dri2_surf->base.Height,
1493cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 &dri2_surf->back->data,
1494cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 &dri2_surf->back->data_size,
1495cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                                 &dri2_surf->back->wl_buffer)) {
1496cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
1497cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                 return -1;
1498cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             }
1499cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             wl_proxy_set_queue((struct wl_proxy *) dri2_surf->back->wl_buffer,
1500cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                dri2_dpy->wl_queue);
1501cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             wl_buffer_add_listener(dri2_surf->back->wl_buffer,
1502cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                    &wl_buffer_listener, dri2_surf);
1503cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy             break;
1504cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         }
1505cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      }
1506cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1507cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1508cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_surf->back) {
1509cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      _eglError(EGL_BAD_ALLOC, "failed to find free buffer");
1510cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return -1;
1511cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1512cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1513cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->back->locked = 1;
1514cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1515cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* If we have an extra unlocked buffer at this point, we had to do triple
1516cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * buffering for a while, but now can go back to just double buffering.
1517cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * That means we can free any unlocked buffer now. */
1518cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
1519cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (!dri2_surf->color_buffers[i].locked &&
1520cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy          dri2_surf->color_buffers[i].wl_buffer) {
1521cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
1522cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         munmap(dri2_surf->color_buffers[i].data,
1523cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                dri2_surf->color_buffers[i].data_size);
1524cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         dri2_surf->color_buffers[i].wl_buffer = NULL;
1525cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         dri2_surf->color_buffers[i].data = NULL;
1526cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      }
1527cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1528cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1529cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return 0;
1530cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1531cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1532cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void*
1533cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf)
1534cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1535cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* if there has been a resize: */
1536cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_surf->current)
1537cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return NULL;
1538cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1539cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return dri2_surf->current->data;
1540cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1541cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1542cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void*
1543cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_get_backbuffer_data(struct dri2_egl_surface *dri2_surf)
1544cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1545cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   assert(dri2_surf->back);
1546cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return dri2_surf->back->data;
1547cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1548cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1549cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1550cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf)
1551cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1552cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
1553cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
15549ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone   while (dri2_surf->throttle_callback != NULL)
15559ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone      if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
15569ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone                                    dri2_dpy->wl_queue) == -1)
15576ff948ece11042476acbdf218f60ce7c03a147c5Emil Velikov         return;
15589ca6711faa03a9527c0946f2489e42cd9a62235cDaniel Stone
1559cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_surf->base.SwapInterval > 0) {
1560cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_surf->throttle_callback =
1561cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         wl_surface_frame(dri2_surf->wl_win->surface);
1562cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      wl_callback_add_listener(dri2_surf->throttle_callback,
1563cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               &throttle_listener, dri2_surf);
1564cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback,
1565cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         dri2_dpy->wl_queue);
1566cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1567cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1568cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->current = dri2_surf->back;
1569cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->back = NULL;
1570cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1571cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_surface_attach(dri2_surf->wl_win->surface,
1572cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                     dri2_surf->current->wl_buffer,
1573cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                     dri2_surf->dx, dri2_surf->dy);
1574cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1575cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
1576cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
1577cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* reset resize growing parameters */
1578cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->dx = 0;
1579cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_surf->dy = 0;
1580cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1581cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_surface_damage(dri2_surf->wl_win->surface,
1582cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                     0, 0, INT32_MAX, INT32_MAX);
1583cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_surface_commit(dri2_surf->wl_win->surface);
1584cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1585cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* If we're not waiting for a frame callback then we'll at least throttle
1586cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * to a sync callback so that we always give a chance for the compositor to
1587cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * handle the commit and send a release event before checking for a free
1588cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * buffer */
1589cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_surf->throttle_callback == NULL) {
159036b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl      dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy_wrapper);
1591cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      wl_callback_add_listener(dri2_surf->throttle_callback,
1592cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               &throttle_listener, dri2_surf);
1593cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1594cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1595cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_display_flush(dri2_dpy->wl_dpy);
1596cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1597cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1598cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1599cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
1600cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                 int *x, int *y, int *w, int *h,
1601cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                                 void *loaderPrivate)
1602cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1603cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_surface *dri2_surf = loaderPrivate;
1604cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1605cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   (void) swrast_update_buffers(dri2_surf);
1606cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *x = 0;
1607cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *y = 0;
1608cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *w = dri2_surf->base.Width;
1609cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   *h = dri2_surf->base.Height;
1610cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1611cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1612cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1613cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_get_image(__DRIdrawable * read,
1614cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         int x, int y, int w, int h,
1615cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         char *data, void *loaderPrivate)
1616cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1617cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_surface *dri2_surf = loaderPrivate;
1618cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
1619cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
1620cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int src_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
1621cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int dst_stride = copy_width;
1622cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   char *src, *dst;
1623cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1624cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf);
1625cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!src) {
1626cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      memset(data, 0, copy_width * h);
1627cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return;
1628cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1629cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1630cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   assert(data != src);
1631cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   assert(copy_width <= src_stride);
1632cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1633cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   src += x_offset;
1634cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   src += y * src_stride;
1635cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dst = data;
1636cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1637cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (copy_width > src_stride-x_offset)
1638cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      copy_width = src_stride-x_offset;
1639cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (h > dri2_surf->base.Height-y)
1640cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      h = dri2_surf->base.Height-y;
1641cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1642cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   for (; h>0; h--) {
1643cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      memcpy(dst, src, copy_width);
1644cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      src += src_stride;
1645cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dst += dst_stride;
1646cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1647cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1648cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1649cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1650cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
1651cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         int x, int y, int w, int h, int stride,
1652cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         char *data, void *loaderPrivate)
1653cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1654cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_surface *dri2_surf = loaderPrivate;
1655cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int copy_width = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
1656cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int dst_stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, dri2_surf->base.Width);
1657cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int x_offset = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, x);
1658cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   char *src, *dst;
1659cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1660cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   assert(copy_width <= stride);
1661cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1662cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   (void) swrast_update_buffers(dri2_surf);
1663cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
1664cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1665cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* partial copy, copy old content */
1666cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (copy_width < dst_stride)
1667cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_wl_swrast_get_image(draw, 0, 0,
1668cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               dri2_surf->base.Width, dri2_surf->base.Height,
1669cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                               dst, loaderPrivate);
1670cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1671cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dst += x_offset;
1672cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dst += y * dst_stride;
1673cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1674cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   src = data;
1675cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1676cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* drivers expect we do these checks (and some rely on it) */
1677cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (copy_width > dst_stride-x_offset)
1678cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      copy_width = dst_stride-x_offset;
1679cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (h > dri2_surf->base.Height-y)
1680cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      h = dri2_surf->base.Height-y;
1681cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1682cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   for (; h>0; h--) {
1683cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      memcpy(dst, src, copy_width);
1684cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      src += stride;
1685cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dst += dst_stride;
1686cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1687cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_wl_swrast_commit_backbuffer(dri2_surf);
1688cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1689cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1690cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1691cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_put_image(__DRIdrawable * draw, int op,
1692cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         int x, int y, int w, int h,
1693cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                         char *data, void *loaderPrivate)
1694cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1695cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_surface *dri2_surf = loaderPrivate;
1696cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int stride;
1697cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1698cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   stride = dri2_wl_swrast_get_stride_for_format(dri2_surf->format, w);
1699cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_wl_swrast_put_image2(draw, op, x, y, w, h,
1700cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                             stride, data, loaderPrivate);
1701cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1702cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1703cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic EGLBoolean
1704cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_wl_swrast_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
1705cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1706cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
1707cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
1708cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1709cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
1710cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return EGL_TRUE;
1711cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1712cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1713cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1714cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyshm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
1715cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1716cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy = data;
1717cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1718cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   switch (format) {
1719cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   case WL_SHM_FORMAT_ARGB8888:
1720cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->formats |= HAS_ARGB8888;
1721cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      break;
1722cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   case WL_SHM_FORMAT_XRGB8888:
1723cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->formats |= HAS_XRGB8888;
1724cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      break;
1725cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   case WL_SHM_FORMAT_RGB565:
1726cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->formats |= HAS_RGB565;
1727cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      break;
1728cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1729cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1730cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1731cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic const struct wl_shm_listener shm_listener = {
17325567494403938940f61d44888c436a20a6635ef3Emil Velikov   .format = shm_handle_format
1733cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy};
1734cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1735cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic void
1736cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davyregistry_handle_global_swrast(void *data, struct wl_registry *registry, uint32_t name,
1737cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                              const char *interface, uint32_t version)
1738cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1739cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy = data;
1740cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1741cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (strcmp(interface, "wl_shm") == 0) {
1742cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->wl_shm =
1743cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         wl_registry_bind(registry, name, &wl_shm_interface, 1);
1744cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      wl_shm_add_listener(dri2_dpy->wl_shm, &shm_listener, dri2_dpy);
1745cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1746cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1747cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1748cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic const struct wl_registry_listener registry_listener_swrast = {
17495567494403938940f61d44888c436a20a6635ef3Emil Velikov   .global = registry_handle_global_swrast,
17505567494403938940f61d44888c436a20a6635ef3Emil Velikov   .global_remove = registry_handle_global_remove
1751cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy};
1752cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1753cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
1754cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .authenticate = NULL,
1755cb5e799448c959fa9f0d7ea76999ac6f8c0ad88eEmil Velikov   .create_window_surface = dri2_wl_create_window_surface,
1756cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .create_pixmap_surface = dri2_wl_create_pixmap_surface,
1757cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface,
1758cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .destroy_surface = dri2_wl_destroy_surface,
1759cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .create_image = dri2_fallback_create_image_khr,
1760cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .swap_interval = dri2_wl_swap_interval,
1761cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .swap_buffers = dri2_wl_swrast_swap_buffers,
1762cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
1763cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .swap_buffers_region = dri2_fallback_swap_buffers_region,
1764cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .post_sub_buffer = dri2_fallback_post_sub_buffer,
1765cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .copy_buffers = dri2_fallback_copy_buffers,
1766cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .query_buffer_age = dri2_fallback_query_buffer_age,
1767cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
1768cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   .get_sync_values = dri2_fallback_get_sync_values,
1769a25df5457121d40fef86929d4c10d8058a4d5c72Boyan Ding   .get_dri_drawable = dri2_surface_get_dri_drawable,
1770cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy};
1771cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
17722dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikovstatic const __DRIswrastLoaderExtension swrast_loader_extension = {
17732dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov   .base = { __DRI_SWRAST_LOADER, 2 },
17742dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov
17752dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov   .getDrawableInfo = dri2_wl_swrast_get_drawable_info,
17762dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov   .putImage        = dri2_wl_swrast_put_image,
17772dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov   .getImage        = dri2_wl_swrast_get_image,
17782dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov   .putImage2       = dri2_wl_swrast_put_image2,
17792dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov};
17802dbe14af1ea6b9d7af13a3067f52f844c658d412Emil Velikov
1781f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikovstatic const __DRIextension *swrast_loader_extensions[] = {
1782f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   &swrast_loader_extension.base,
1783f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   NULL,
1784f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov};
1785f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov
1786cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davystatic EGLBoolean
1787cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
1788cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1789cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   struct dri2_egl_display *dri2_dpy;
1790cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1791cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   loader_set_logger(_eglLog);
1792cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1793cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_dpy = calloc(1, sizeof *dri2_dpy);
1794cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_dpy)
1795cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
1796cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1797cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   disp->DriverData = (void *) dri2_dpy;
1798cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (disp->PlatformDisplay == NULL) {
1799cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->wl_dpy = wl_display_connect(NULL);
1800cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (dri2_dpy->wl_dpy == NULL)
1801cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         goto cleanup_dpy;
1802cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->own_device = 1;
1803cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   } else {
1804cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      dri2_dpy->wl_dpy = disp->PlatformDisplay;
1805cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1806cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1807cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
1808cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
180936b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   dri2_dpy->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy);
181036b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   if (dri2_dpy->wl_dpy_wrapper == NULL)
181136b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl      goto cleanup_dpy_wrapper;
181236b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl
181336b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper,
181436b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl                      dri2_dpy->wl_queue);
181536b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl
1816cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (dri2_dpy->own_device)
1817cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      wl_display_dispatch_pending(dri2_dpy->wl_dpy);
1818cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
181936b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper);
1820cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_registry_add_listener(dri2_dpy->wl_registry,
1821cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy                            &registry_listener_swrast, dri2_dpy);
1822cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1823cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_shm == NULL)
1824cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto cleanup_registry;
1825cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1826cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->formats == 0)
1827cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto cleanup_shm;
1828cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1829a1ac742f709089eabad59b4da484799091203d91Emil Velikov   dri2_dpy->fd = -1;
1830cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_dpy->driver_name = strdup("swrast");
1831cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_load_driver_swrast(disp))
1832cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto cleanup_shm;
1833cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1834f871946594129500a67c05a6d9fe99db54b4bb64Emil Velikov   dri2_dpy->loader_extensions = swrast_loader_extensions;
1835cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1836cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (!dri2_create_screen(disp))
1837cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      goto cleanup_driver;
1838cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1839cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_wl_setup_swap_interval(dri2_dpy);
1840cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
18410b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   if (!dri2_wl_add_configs_for_visuals(drv, disp)) {
18420b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
18430b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov      goto cleanup_screen;
1844cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1845cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1846cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   /* Fill vtbl last to prevent accidentally calling virtual function during
1847cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    * initialization.
1848cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy    */
1849cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dri2_dpy->vtbl = &dri2_wl_swrast_display_vtbl;
1850cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1851cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return EGL_TRUE;
1852cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
18530b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov cleanup_screen:
18540b2b7191214eb77c5720a40231a6f2d28da63027Emil Velikov   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
1855cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy cleanup_driver:
1856cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   dlclose(dri2_dpy->driver);
1857cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy cleanup_shm:
1858cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_shm_destroy(dri2_dpy->wl_shm);
1859cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy cleanup_registry:
1860cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_registry_destroy(dri2_dpy->wl_registry);
186136b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl   wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper);
186236b9976e1f99e8070c67cb8a255793939db77d02Jonas Ådahl cleanup_dpy_wrapper:
1863cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   wl_event_queue_destroy(dri2_dpy->wl_queue);
1864361796651c5abb21ff429466c061119dce8f33d5Jonas Ådahl   if (disp->PlatformDisplay == NULL)
1865361796651c5abb21ff429466c061119dce8f33d5Jonas Ådahl      wl_display_disconnect(dri2_dpy->wl_dpy);
1866cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy cleanup_dpy:
1867cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   free(dri2_dpy);
186848fd952f28a5fcd71eed5a60c8e3a10231c7a5b0Nicolas Boichat   disp->DriverData = NULL;
1869cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1870cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return EGL_FALSE;
1871cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1872cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1873cdcfe48fb0431184fabb40aa5a244d086f551df5Axel DavyEGLBoolean
1874cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davydri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
1875cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy{
1876cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   EGLBoolean initialized = EGL_TRUE;
1877cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1878cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   int hw_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
1879cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1880cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   if (hw_accel) {
1881cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      if (!dri2_initialize_wayland_drm(drv, disp)) {
1882cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy         initialized = dri2_initialize_wayland_swrast(drv, disp);
1883cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      }
1884cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   } else {
1885cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy      initialized = dri2_initialize_wayland_swrast(drv, disp);
1886cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   }
1887cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1888cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy   return initialized;
1889cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy
1890cdcfe48fb0431184fabb40aa5a244d086f551df5Axel Davy}
1891