1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2011 Intel Corporation
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Kristian Høgsberg <krh@bitplanet.net>
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Benjamin Franzke <benjaminfranzke@googlemail.com>
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <limits.h>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <dlfcn.h>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h>
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <unistd.h>
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <fcntl.h>
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xf86drm.h>
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_dri2.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <wayland-client.h>
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "wayland-drm-client-protocol.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum wl_drm_format_flags {
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   HAS_ARGB8888 = 1,
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   HAS_XRGB8888 = 2
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsync_callback(void *data, struct wl_callback *callback, uint32_t serial)
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int *done = data;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *done = 1;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_callback_destroy(callback);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct wl_callback_listener sync_listener = {
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sync_callback
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgroundtrip(struct dri2_egl_display *dri2_dpy)
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct wl_callback *callback;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int done = 0, ret = 0;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   callback = wl_display_sync(dri2_dpy->wl_dpy);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_callback_add_listener(callback, &sync_listener, &done);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_proxy_set_queue((struct wl_proxy *) callback, dri2_dpy->wl_queue);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (ret != -1 && !done)
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!done)
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_callback_destroy(callback);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwl_buffer_release(void *data, struct wl_buffer *buffer)
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = data;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < WL_BUFFER_COUNT; ++i)
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->wl_drm_buffer[i] == buffer)
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(i <= WL_BUFFER_COUNT);
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* not found? */
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i == WL_BUFFER_COUNT)
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->wl_buffer_lock[i] = 0;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct wl_buffer_listener wl_buffer_listener = {
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_buffer_release
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresize_callback(struct wl_egl_window *wl_win, void *data)
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = data;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    _EGLConfig *conf, EGLNativeWindowType window,
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    const EGLint *attrib_list)
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) drv;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf = malloc(sizeof *dri2_surf);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_surf) {
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_surf;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < WL_BUFFER_COUNT; ++i) {
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_drm_buffer[i] = NULL;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_buffer_lock[i] = 0;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dri_buffers[i] = NULL;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->pending_buffer = NULL;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->third_buffer = NULL;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->frame_callback = NULL;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->pending_buffer_callback = NULL;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (conf->AlphaSize == 0)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->format = WL_DRM_FORMAT_XRGB8888;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->format = WL_DRM_FORMAT_ARGB8888;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type) {
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_WINDOW_BIT:
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win = (struct wl_egl_window *) window;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->private = dri2_surf;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->resize_callback = resize_callback;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->base.Width =  -1;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->base.Height = -1;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_surf;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->dri_drawable =
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    type == EGL_WINDOW_BIT ?
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    dri2_conf->dri_double_config :
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    dri2_conf->dri_single_config,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    dri2_surf);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->dri_drawable == NULL) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_dri_drawable;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &dri2_surf->base;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_dri_drawable:
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_surf:
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_surf);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   _EGLConfig *conf, EGLNativeWindowType window,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   const EGLint *attrib_list)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      window, attrib_list);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglDestroySurface(), drv->API.DestroySurface().
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) drv;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglPutSurface(surf))
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < WL_BUFFER_COUNT; ++i)
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->wl_drm_buffer[i])
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->dri_buffers[i])
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       dri2_surf->dri_buffers[i]);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->third_buffer) {
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    dri2_surf->third_buffer);
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->frame_callback)
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_callback_destroy(dri2_surf->frame_callback);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->pending_buffer_callback)
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_callback_destroy(dri2_surf->pending_buffer_callback);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->private = NULL;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->resize_callback = NULL;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(surf);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct wl_buffer *
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwayland_create_buffer(struct dri2_egl_surface *dri2_surf,
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      __DRIbuffer *buffer)
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct wl_buffer *buf;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              dri2_surf->base.Width, dri2_surf->base.Height,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              buffer->pitch, dri2_surf->format);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return buf;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) format;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (dri2_surf->base.Type) {
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_WINDOW_BIT:
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* allocate a front buffer for our double-buffered window*/
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL)
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               __DRI_BUFFER_FRONT_LEFT, format,
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               dri2_surf->base.Width, dri2_surf->base.Height);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_release_pending_buffer(void *data,
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    struct wl_callback *callback, uint32_t time)
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = data;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME: print internal error */
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_surf->pending_buffer)
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 dri2_surf->pending_buffer);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->pending_buffer = NULL;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_callback_destroy(callback);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->pending_buffer_callback = NULL;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct wl_callback_listener release_buffer_listener = {
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_release_pending_buffer
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_release_buffers(struct dri2_egl_surface *dri2_surf)
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct wl_callback *callback;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->third_buffer) {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    dri2_surf->third_buffer);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->third_buffer = NULL;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->dri_buffers[i]) {
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (i) {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case __DRI_BUFFER_FRONT_LEFT:
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (dri2_surf->pending_buffer)
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               roundtrip(dri2_dpy);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dri2_surf->pending_buffer = dri2_surf->dri_buffers[i];
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            callback = wl_display_sync(dri2_dpy->wl_dpy);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    wl_callback_add_listener(callback,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     &release_buffer_listener, dri2_surf);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            wl_proxy_set_queue((struct wl_proxy *) callback,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               dri2_dpy->wl_queue);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dri2_surf->pending_buffer_callback = callback;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          dri2_surf->dri_buffers[i]);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_surf->dri_buffers[i] = NULL;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpointer_swap(const void **p1, const void **p2)
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const void *tmp = *p1;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *p1 = *p2;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *p2 = tmp;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdestroy_third_buffer(struct dri2_egl_surface *dri2_surf)
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->third_buffer == NULL)
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 dri2_surf->third_buffer);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->third_buffer = NULL;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD])
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL;
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_wl_buffers(struct dri2_egl_surface *dri2_surf,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                enum wayland_buffer_type a, enum wayland_buffer_type b)
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int tmp;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tmp = dri2_surf->wl_buffer_lock[a];
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b];
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->wl_buffer_lock[b] = tmp;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a],
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (const void **) &dri2_surf->wl_drm_buffer[b]);
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_back_and_third(struct dri2_egl_surface *dri2_surf)
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD])
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      destroy_third_buffer(dri2_surf);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT],
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (const void **) &dri2_surf->third_buffer);
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD);
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf,
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           unsigned int type)
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type) {
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case __DRI_BUFFER_BACK_LEFT:
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK])
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swap_back_and_third(dri2_surf);
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (dri2_surf->third_buffer)
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            destroy_third_buffer(dri2_surf);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __DRIbuffer *
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_get_buffers_with_format(__DRIdrawable * driDrawable,
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     int *width, int *height,
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     unsigned int *attachments, int count,
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     int *out_count, void *loaderPrivate)
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = loaderPrivate;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy =
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_egl_display(dri2_surf->base.Resource.Display);
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* There might be a buffer release already queued that wasn't processed */
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (dri2_surf->base.Width != dri2_surf->wl_win->width ||
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        dri2_surf->base.Height != dri2_surf->wl_win->height)) {
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_release_buffers(dri2_surf);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->base.Width  = dri2_surf->wl_win->width;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->base.Height = dri2_surf->wl_win->height;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dx = dri2_surf->wl_win->dx;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dy = dri2_surf->wl_win->dy;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < WL_BUFFER_COUNT; ++i) {
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dri2_surf->wl_drm_buffer[i])
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_surf->wl_drm_buffer[i]  = NULL;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_surf->wl_buffer_lock[i] = 0;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->buffer_count = 0;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 2*count; i+=2) {
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(attachments[i] < __DRI_BUFFER_COUNT);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(dri2_surf->buffer_count < 5);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_prior_buffer_creation(dri2_surf, attachments[i]);
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_surf->dri_buffers[attachments[i]] =
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  attachments[i], attachments[i+1],
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  dri2_surf->base.Width, dri2_surf->base.Height);
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!dri2_surf->dri_buffers[attachments[i]])
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (attachments[i] == __DRI_BUFFER_BACK_LEFT)
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dri2_process_back_buffer(dri2_surf, attachments[i+1]);
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             dri2_surf->dri_buffers[attachments[i]],
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             sizeof(__DRIbuffer));
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->buffer_count++;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *out_count = dri2_surf->buffer_count;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->buffer_count == 0)
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   return NULL;
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *width = dri2_surf->base.Width;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *height = dri2_surf->base.Height;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return dri2_surf->buffers;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __DRIbuffer *
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_get_buffers(__DRIdrawable * driDrawable,
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 int *width, int *height,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 unsigned int *attachments, int count,
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 int *out_count, void *loaderPrivate)
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int *attachments_with_format;
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIbuffer *buffer;
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned int format = 32;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   attachments_with_format = calloc(count * 2, sizeof(unsigned int));
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!attachments_with_format) {
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *out_count = 0;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; ++i) {
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      attachments_with_format[2*i] = attachments[i];
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      attachments_with_format[2*i + 1] = format;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer =
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_get_buffers_with_format(driDrawable,
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   width, height,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   attachments_with_format, count,
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   out_count, loaderPrivate);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(attachments_with_format);
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return buffer;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) driDrawable;
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME: Does EGL support front buffer rendering at all? */
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = loaderPrivate;
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2WaitGL(dri2_surf);
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) loaderPrivate;
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = data;
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->frame_callback = NULL;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_callback_destroy(callback);
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct wl_callback_listener frame_listener = {
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	wayland_frame_callback
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglSwapBuffers(), drv->API.SwapBuffers().
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret = 0;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (dri2_surf->frame_callback && ret != -1)
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ret < 0)
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_surf->frame_callback = wl_surface_frame(dri2_surf->wl_win->surface);
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_callback_add_listener(dri2_surf->frame_callback,
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            &frame_listener, dri2_surf);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_proxy_set_queue((struct wl_proxy *) dri2_surf->frame_callback,
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dri2_dpy->wl_queue);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pointer_swap(
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __DRI_BUFFER_FRONT_LEFT;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __DRI_BUFFER_BACK_LEFT;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    wayland_create_buffer(dri2_surf,
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_surface_attach(dri2_surf->wl_win->surface,
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dri2_surf->dx, dri2_surf->dy);
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* reset resize growing parameters */
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dx = 0;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_surf->dy = 0;
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    dri2_surf->base.Width, dri2_surf->base.Height);
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_surface_commit(dri2_surf->wl_win->surface);
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *ctx;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_drv->glFlush) {
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx = _eglGetCurrentContext();
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx && ctx->DrawSurface == &dri2_surf->base)
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dri2_drv->glFlush();
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret = 0;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->authenticated = 0;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_drm_authenticate(dri2_dpy->wl_drm, id);
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (roundtrip(dri2_dpy) < 0)
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = -1;
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_dpy->authenticated)
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = -1;
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* reset authenticated */
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->authenticated = 1;
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via eglTerminate(), drv->API.Terminate().
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _eglReleaseDisplayResources(drv, disp);
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _eglCleanupDisplay(disp);
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   close(dri2_dpy->fd);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dlclose(dri2_dpy->driver);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy->driver_name);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy->device_name);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_drm_destroy(dri2_dpy->wl_drm);
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_dpy->own_device)
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_display_disconnect(dri2_dpy->wl_dpy);
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   disp->DriverData = NULL;
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdrm_handle_device(void *data, struct wl_drm *drm, const char *device)
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = data;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_magic_t magic;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->device_name = strdup(device);
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_dpy->device_name)
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef O_CLOEXEC
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC);
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_dpy->fd == -1 && errno == EINVAL)
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_dpy->fd != -1)
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) |
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            FD_CLOEXEC);
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_dpy->fd == -1) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dri2_dpy->device_name, strerror(errno));
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drmGetMagic(dri2_dpy->fd, &magic);
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_drm_authenticate(dri2_dpy->wl_drm, magic);
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdrm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = data;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (format) {
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case WL_DRM_FORMAT_ARGB8888:
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->formats |= HAS_ARGB8888;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case WL_DRM_FORMAT_XRGB8888:
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->formats |= HAS_XRGB8888;
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdrm_handle_authenticated(void *data, struct wl_drm *drm)
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = data;
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->authenticated = 1;
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct wl_drm_listener drm_listener = {
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	drm_handle_device,
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	drm_handle_format,
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	drm_handle_authenticated
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgregistry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       const char *interface, uint32_t version)
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy = data;
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strcmp(interface, "wl_drm") == 0) {
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->wl_drm =
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         wl_registry_bind(registry, name, &wl_drm_interface, 1);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wl_drm_add_listener(dri2_dpy->wl_drm, &drm_listener, dri2_dpy);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct wl_registry_listener registry_listener = {
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	registry_handle_global
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri2_egl_display *dri2_dpy;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIconfig *config;
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t types;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const unsigned int argb_masks[4] =
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { 0xff0000, 0xff00, 0xff, 0xff000000 };
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateWindowSurface = dri2_create_window_surface;
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.DestroySurface = dri2_destroy_surface;
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.SwapBuffers = dri2_swap_buffers;
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.Terminate = dri2_terminate;
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy = malloc(sizeof *dri2_dpy);
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_dpy)
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(dri2_dpy, 0, sizeof *dri2_dpy);
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   disp->DriverData = (void *) dri2_dpy;
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (disp->PlatformDisplay == NULL) {
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->wl_dpy = wl_display_connect(NULL);
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_dpy->wl_dpy == NULL)
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto cleanup_dpy;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->own_device = 1;
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_dpy->wl_dpy = disp->PlatformDisplay;
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy);
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry,
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dri2_dpy->wl_queue);
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_registry_add_listener(dri2_dpy->wl_registry,
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            &registry_listener, dri2_dpy);
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL)
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_dpy;
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1)
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_drm;
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated)
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_fd;
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dri2_dpy->driver_name == NULL) {
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_fd;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_load_driver(disp))
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_driver_name;
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2_loader_extension.base.version = 3;
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dri2_get_buffers_with_format;
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->extensions[1] = &image_lookup_extension.base;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->extensions[2] = &use_invalidate.base;
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->extensions[3] = NULL;
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dri2_create_screen(disp))
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup_driver;
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   types = EGL_WINDOW_BIT;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      config = dri2_dpy->driver_configs[i];
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_dpy->formats & HAS_XRGB8888)
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dri2_add_config(disp, config, i + 1, 0, types, NULL, rgb_masks);
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dri2_dpy->formats & HAS_ARGB8888)
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks);
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri2_dpy->authenticate = dri2_wayland_authenticate;
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we're supporting EGL 1.4 */
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   disp->VersionMajor = 1;
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   disp->VersionMinor = 4;
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_driver:
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dlclose(dri2_dpy->driver);
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_driver_name:
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy->driver_name);
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_fd:
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   close(dri2_dpy->fd);
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_drm:
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy->device_name);
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   wl_drm_destroy(dri2_dpy->wl_drm);
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cleanup_dpy:
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(dri2_dpy);
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_FALSE;
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
851