egl_g3d.c revision c97c77d8698ddab1c8a2900fe7c82e1d111ccb8a
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Mesa 3-D graphics library
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Version:  7.8
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Permission is hereby granted, free of charge, to any person obtaining a
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * copy of this software and associated documentation files (the "Software"),
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * to deal in the Software without restriction, including without limitation
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and/or sell copies of the Software, and to permit persons to whom the
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Software is furnished to do so, subject to the following conditions:
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The above copyright notice and this permission notice shall be included
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in all copies or substantial portions of the Software.
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
17856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * DEALINGS IN THE SOFTWARE.
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org#include "egldriver.h"
27856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org#include "eglcurrent.h"
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "egllog.h"
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "pipe/p_screen.h"
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "util/u_memory.h"
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "util/u_format.h"
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "util/u_string.h"
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "egl_g3d.h"
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "egl_g3d_api.h"
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "egl_g3d_st.h"
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "egl_g3d_loader.h"
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "native.h"
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Get the native platform.
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const struct native_platform *
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!gdrv->platforms[plat]) {
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      const char *plat_name = NULL;
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      const struct native_platform *nplat = NULL;
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      switch (plat) {
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case _EGL_PLATFORM_WINDOWS:
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         plat_name = "Windows";
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_GDI_BACKEND
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         nplat = native_get_gdi_platform();
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         break;
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case _EGL_PLATFORM_X11:
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         plat_name = "X11";
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_X11_BACKEND
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         nplat = native_get_x11_platform();
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         break;
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case _EGL_PLATFORM_DRM:
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         plat_name = "DRM";
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_DRM_BACKEND
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         nplat = native_get_drm_platform();
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         break;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      case _EGL_PLATFORM_FBDEV:
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         plat_name = "FBDEV";
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_FBDEV_BACKEND
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         nplat = native_get_fbdev_platform();
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         break;
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      default:
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         break;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (!nplat)
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gdrv->platforms[plat] = nplat;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return gdrv->platforms[plat];
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef EGL_MESA_screen_surface
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   const struct native_connector **native_connectors;
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLint num_connectors, i;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   native_connectors =
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!num_connectors) {
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (native_connectors)
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         FREE(native_connectors);
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   for (i = 0; i < num_connectors; i++) {
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      const struct native_connector *nconn = native_connectors[i];
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      struct egl_g3d_screen *gscr;
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      const struct native_mode **native_modes;
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      EGLint num_modes, j;
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* TODO support for hotplug */
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      native_modes =
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (!num_modes) {
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         if (native_modes)
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            FREE(native_modes);
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         continue;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gscr = CALLOC_STRUCT(egl_g3d_screen);
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (!gscr) {
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         FREE(native_modes);
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         continue;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglInitScreen(&gscr->base);
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (j = 0; j < num_modes; j++) {
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         const struct native_mode *nmode = native_modes[j];
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         _EGLMode *mode;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               nmode->refresh_rate, nmode->desc);
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         if (!mode)
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         /* gscr->native_modes and gscr->base.Modes should be consistent */
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         assert(mode == &gscr->base.Modes[j]);
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gscr->native = nconn;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gscr->native_modes = native_modes;
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglAddScreen(dpy, &gscr->base);
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
148856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(native_connectors);
150856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org}
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
152856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org#endif /* EGL_MESA_screen_surface */
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**
155856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org * Initialize and validate the EGL config attributes.
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLBoolean
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orginit_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       EGLint api_mask, enum pipe_format depth_stencil_format)
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   uint rgba[4], depth_stencil[2], buffer_size;
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLint surface_type;
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLint i;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* get the color and depth/stencil component sizes */
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   assert(nconf->color_format != PIPE_FORMAT_NONE);
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   buffer_size = 0;
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   for (i = 0; i < 4; i++) {
169856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      rgba[i] = util_format_get_component_bits(nconf->color_format,
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            UTIL_FORMAT_COLORSPACE_RGB, i);
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      buffer_size += rgba[i];
172856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   }
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   for (i = 0; i < 2; i++) {
174856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      if (depth_stencil_format != PIPE_FORMAT_NONE) {
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         depth_stencil[i] =
176856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org            util_format_get_component_bits(depth_stencil_format,
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               UTIL_FORMAT_COLORSPACE_ZS, i);
178856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      }
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      else {
180856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org         depth_stencil[i] = 0;
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
182856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   }
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
184856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   surface_type = 0x0;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->window_bit)
186856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      surface_type |= EGL_WINDOW_BIT;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->pixmap_bit)
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      surface_type |= EGL_PIXMAP_BIT;
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef EGL_MESA_screen_surface
190856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   if (nconf->scanout_bit)
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      surface_type |= EGL_SCREEN_BIT_MESA;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
193856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      surface_type |= EGL_PBUFFER_BIT;
196856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->Conformant = api_mask;
198856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->RenderableType = api_mask;
199856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->RedSize = rgba[0];
201856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->GreenSize = rgba[1];
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->BlueSize = rgba[2];
203856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->AlphaSize = rgba[3];
204856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->BufferSize = buffer_size;
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
206856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->DepthSize = depth_stencil[0];
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->StencilSize = depth_stencil[1];
208856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
209856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->SurfaceType = surface_type;
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   conf->NativeRenderable = EGL_TRUE;
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (surface_type & EGL_WINDOW_BIT) {
213856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      conf->NativeVisualID = nconf->native_visual_id;
214856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      conf->NativeVisualType = nconf->native_visual_type;
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (surface_type & EGL_PBUFFER_BIT) {
218856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      conf->BindToTextureRGB = EGL_TRUE;
219856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org      if (rgba[3])
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         conf->BindToTextureRGBA = EGL_TRUE;
221856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->MaxPbufferWidth = 4096;
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->MaxPbufferHeight = 4096;
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->MaxPbufferPixels = 4096 * 4096;
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->Level = nconf->level;
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->Samples = nconf->samples;
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   conf->SampleBuffers = 0;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->slow_config)
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->ConfigCaveat = EGL_SLOW_CONFIG;
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->transparent_rgb) {
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->TransparentType = EGL_TRANSPARENT_RGB;
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->TransparentRedValue = nconf->transparent_rgb_values[0];
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->TransparentGreenValue = nconf->transparent_rgb_values[1];
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      conf->TransparentBlueValue = nconf->transparent_rgb_values[2];
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return _eglValidateConfig(conf, EGL_FALSE);
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Initialize an EGL config from the native config.
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLBoolean
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _EGLConfig *conf, const struct native_config *nconf,
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    enum pipe_format depth_stencil_format)
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_config *gconf = egl_g3d_config(conf);
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLint buffer_mask, api_mask;
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLBoolean valid;
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* skip single-buffered configs */
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!(nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)))
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return EGL_FALSE;
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   buffer_mask = 0x0;
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_RIGHT))
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_RIGHT))
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gconf->stvis.buffer_mask = buffer_mask;
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gconf->stvis.color_format = nconf->color_format;
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gconf->stvis.depth_stencil_format = depth_stencil_format;
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gconf->stvis.accum_format = PIPE_FORMAT_NONE;
274856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   gconf->stvis.samples = nconf->samples;
275856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
276856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   api_mask = dpy->ClientAPIsMask;
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* this is required by EGL, not by OpenGL ES */
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (nconf->window_bit &&
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!api_mask) {
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            nconf->native_visual_id);
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   valid = init_config_attributes(&gconf->base,
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         nconf, api_mask, depth_stencil_format);
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!valid) {
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return EGL_FALSE;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gconf->native = nconf;
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return EGL_TRUE;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Get all interested depth/stencil formats of a display.
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLint
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   enum pipe_format formats[8])
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct pipe_screen *screen = gdpy->native->screen;
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   const EGLint candidates[] = {
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      1, PIPE_FORMAT_Z16_UNORM,
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      1, PIPE_FORMAT_Z32_UNORM,
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      2, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      0
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   };
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   const EGLint *fmt = candidates;
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   EGLint count;
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   count = 0;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   formats[count++] = PIPE_FORMAT_NONE;
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   while (*fmt) {
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      EGLint i, n = *fmt++;
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /* pick the first supported format */
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (i = 0; i < n; i++) {
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         if (screen->is_format_supported(screen, fmt[i],
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) {
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            formats[count++] = fmt[i];
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         }
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      fmt += n;
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return count;
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Add configs to display and return the next config ID.
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLint
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   const struct native_config **native_configs;
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   enum pipe_format depth_stencil_formats[8];
351856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org   int num_formats, num_configs, i, j;
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!num_configs) {
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (native_configs)
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         FREE(native_configs);
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return id;
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         depth_stencil_formats);
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   for (i = 0; i < num_configs; i++) {
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (j = 0; j < num_formats; j++) {
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         struct egl_g3d_config *gconf;
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         gconf = CALLOC_STRUCT(egl_g3d_config);
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         if (gconf) {
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _eglInitConfig(&gconf->base, dpy, id);
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (!egl_g3d_init_config(drv, dpy, &gconf->base,
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     native_configs[i], depth_stencil_formats[j])) {
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               FREE(gconf);
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               break;
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _eglAddConfig(dpy, &gconf->base);
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            id++;
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         }
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(native_configs);
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return id;
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
385856edd527f7c49517d6d866b602defd743ca0bdbandrew@webrtc.org
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_invalid_surface(struct native_display *ndpy,
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        struct native_surface *nsurf,
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        unsigned int seq_num)
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* XXX not thread safe? */
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_context *gctx;
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /*
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    * Some functions such as egl_g3d_copy_buffers create a temporary native
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    * surface.  There is no gsurf associated with it.
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    */
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gctx)
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic struct pipe_screen *
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return gdpy->loader->create_drm_screen(name, fd);
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic struct pipe_screen *
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return gdpy->loader->create_sw_screen(ws);
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic struct native_event_handler egl_g3d_native_event_handler = {
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   egl_g3d_invalid_surface,
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   egl_g3d_new_drm_screen,
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   egl_g3d_new_sw_screen
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_free_config(void *conf)
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(gconf);
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_free_screen(void *scr)
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef EGL_MESA_screen_surface
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr);
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(gscr->native_modes);
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(gscr);
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLBoolean
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   _eglReleaseDisplayResources(drv, dpy);
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->pipe)
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gdpy->pipe->destroy(gdpy->pipe);
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (dpy->Configs) {
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglDestroyArray(dpy->Configs, egl_g3d_free_config);
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Configs = NULL;
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (dpy->Screens) {
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Screens = NULL;
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   _eglCleanupDisplay(dpy);
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->smapi)
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      egl_g3d_destroy_st_manager(gdpy->smapi);
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->native)
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      gdpy->native->destroy(gdpy->native);
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(gdpy);
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->DriverData = NULL;
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return EGL_TRUE;
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLBoolean
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   EGLint *major, EGLint *minor)
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_display *gdpy;
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   const struct native_platform *nplat;
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   nplat = egl_g3d_get_platform(drv, dpy->Platform);
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!nplat)
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return EGL_FALSE;
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdpy = CALLOC_STRUCT(egl_g3d_display);
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!gdpy) {
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglError(EGL_BAD_ALLOC, "eglInitialize");
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      goto fail;
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdpy->loader = gdrv->loader;
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->DriverData = gdpy;
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdpy->native = nplat->create_display(dpy->PlatformDisplay,
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         &egl_g3d_native_event_handler, (void *) dpy);
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!gdpy->native) {
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      goto fail;
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdpy->smapi = egl_g3d_create_st_manager(dpy);
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!gdpy->smapi) {
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglError(EGL_NOT_INITIALIZED,
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "eglInitialize(failed to create st manager)");
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      goto fail;
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef EGL_MESA_screen_surface
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* enable MESA_screen_surface before adding (and validating) configs */
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->native->modeset) {
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Extensions.MESA_screen_surface = EGL_TRUE;
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      egl_g3d_add_screens(drv, dpy);
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_image_base = EGL_TRUE;
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_fence_sync = EGL_TRUE;
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   dpy->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (dpy->Platform == _EGL_PLATFORM_DRM) {
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Extensions.MESA_drm_display = EGL_TRUE;
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dpy->Extensions.MESA_drm_image = EGL_TRUE;
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      goto fail;
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   }
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   *major = 1;
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   *minor = 4;
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return EGL_TRUE;
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfail:
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (gdpy)
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      egl_g3d_terminate(drv, dpy);
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return EGL_FALSE;
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic _EGLProc
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct st_api *stapi = NULL;
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (procname && procname[0] == 'v' && procname[1] == 'g')
567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   else if (procname && procname[0] == 'g' && procname[1] == 'l')
569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      stapi = gdrv->loader->get_st_api(ST_API_OPENGL);
570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return (_EGLProc) ((stapi) ?
572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         stapi->get_proc_address(stapi, procname) : NULL);
573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic EGLint
576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_EGLDriver *
582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_create_driver(const struct egl_g3d_loader *loader)
583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_driver *gdrv;
585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv = CALLOC_STRUCT(egl_g3d_driver);
587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   if (!gdrv)
588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return NULL;
589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->loader = loader;
591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   egl_g3d_init_driver_api(&gdrv->base);
593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.API.Initialize = egl_g3d_initialize;
594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.API.Terminate = egl_g3d_terminate;
595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.Probe = egl_g3d_probe;
598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   /* to be filled by the caller */
600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.Name = NULL;
601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   gdrv->base.Unload = NULL;
602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   return &gdrv->base;
604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgegl_g3d_destroy_driver(_EGLDriver *drv)
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org   FREE(gdrv);
611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org