4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2011 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
24 * Robert Bragg <robert@linux.intel.com>
25 * Neil Roberts <neil@linux.intel.com>
32 #include "cogl-winsys-egl-gdl-private.h"
33 #include "cogl-winsys-egl-private.h"
34 #include "cogl-renderer-private.h"
35 #include "cogl-framebuffer-private.h"
36 #include "cogl-onscreen-private.h"
37 #include "cogl-onscreen-template-private.h"
38 #include "cogl-swap-chain-private.h"
40 static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
42 typedef struct _CoglRendererGDL
44 gboolean gdl_initialized;
47 typedef struct _CoglDisplayGDL
49 int egl_surface_width;
50 int egl_surface_height;
51 gboolean have_onscreen;
55 _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
57 CoglRendererEGL *egl_renderer = renderer->winsys;
58 CoglRendererGDL *gdl_renderer = egl_renderer->platform;
60 if (gdl_renderer->gdl_initialized)
63 eglTerminate (egl_renderer->edpy);
65 g_slice_free (CoglRendererEGL, egl_renderer);
69 _cogl_winsys_renderer_connect (CoglRenderer *renderer,
72 CoglRendererEGL *egl_renderer;
73 CoglRendererGDL *gdl_renderer;
74 gdl_ret_t rc = GDL_SUCCESS;
75 gdl_display_info_t gdl_display_info;
77 renderer->winsys = g_slice_new0 (CoglRendererEGL);
78 egl_renderer = renderer->winsys;
80 gdl_renderer = g_slice_new0 (CoglRendererGDL);
81 egl_renderer->platform = gdl_renderer;
83 egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
85 egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
87 if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
90 /* Check we can talk to the GDL library */
92 if (rc != GDL_SUCCESS)
94 g_set_error (error, COGL_WINSYS_ERROR,
95 COGL_WINSYS_ERROR_INIT,
96 "GDL initialize failed. %s",
97 gdl_get_error_string (rc));
101 rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &gdl_display_info);
102 if (rc != GDL_SUCCESS)
104 g_set_error (error, COGL_WINSYS_ERROR,
105 COGL_WINSYS_ERROR_INIT,
106 "GDL failed to get display information: %s",
107 gdl_get_error_string (rc));
117 _cogl_winsys_renderer_disconnect (renderer);
122 _cogl_winsys_egl_context_created (CoglDisplay *display,
125 CoglRenderer *renderer = display->renderer;
126 CoglRendererEGL *egl_renderer = renderer->winsys;
127 CoglDisplayEGL *egl_display = display->winsys;
128 CoglDisplayGDL *gdl_display = egl_display->platform;
129 const char *error_message;
131 egl_display->egl_surface =
132 eglCreateWindowSurface (egl_renderer->edpy,
133 egl_display->egl_config,
134 (NativeWindowType) display->gdl_plane,
137 if (egl_display->egl_surface == EGL_NO_SURFACE)
139 error_message = "Unable to create EGL window surface";
143 if (!eglMakeCurrent (egl_renderer->edpy,
144 egl_display->egl_surface,
145 egl_display->egl_surface,
146 egl_display->egl_context))
148 error_message = "Unable to eglMakeCurrent with egl surface";
152 eglQuerySurface (egl_renderer->edpy,
153 egl_display->egl_surface,
155 &gdl_display->egl_surface_width);
157 eglQuerySurface (egl_renderer->edpy,
158 egl_display->egl_surface,
160 &gdl_display->egl_surface_height);
165 g_set_error (error, COGL_WINSYS_ERROR,
166 COGL_WINSYS_ERROR_CREATE_CONTEXT,
167 "%s", error_message);
172 gdl_plane_init (CoglDisplay *display, GError **error)
175 gdl_color_space_t colorSpace = GDL_COLOR_SPACE_RGB;
176 gdl_pixel_format_t pixfmt = GDL_PF_ARGB_32;
177 gdl_rectangle_t dstRect;
178 gdl_display_info_t display_info;
179 gdl_ret_t rc = GDL_SUCCESS;
181 if (!display->gdl_plane)
183 g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
184 "No GDL plane specified with "
185 "cogl_gdl_display_set_plane");
189 rc = gdl_init (NULL);
190 if (rc != GDL_SUCCESS)
192 g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
193 "GDL initialize failed. %s", gdl_get_error_string (rc));
197 rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &display_info);
198 if (rc != GDL_SUCCESS)
200 g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
201 "GDL failed to get display infomation: %s",
202 gdl_get_error_string (rc));
207 dstRect.origin.x = 0;
208 dstRect.origin.y = 0;
209 dstRect.width = display_info.tvmode.width;
210 dstRect.height = display_info.tvmode.height;
212 /* Configure the plane attribute. */
213 rc = gdl_plane_reset (display->gdl_plane);
214 if (rc == GDL_SUCCESS)
215 rc = gdl_plane_config_begin (display->gdl_plane);
217 if (rc == GDL_SUCCESS)
218 rc = gdl_plane_set_attr (GDL_PLANE_SRC_COLOR_SPACE, &colorSpace);
220 if (rc == GDL_SUCCESS)
221 rc = gdl_plane_set_attr (GDL_PLANE_PIXEL_FORMAT, &pixfmt);
223 if (rc == GDL_SUCCESS)
224 rc = gdl_plane_set_attr (GDL_PLANE_DST_RECT, &dstRect);
226 /* Default to triple buffering if the swap_chain doesn't have an explicit
228 if (rc == GDL_SUCCESS)
230 if (display->onscreen_template->config.swap_chain &&
231 display->onscreen_template->config.swap_chain->length != -1)
232 rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES,
233 display->onscreen_template->
234 config.swap_chain->length);
236 rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES, 3);
239 if (rc == GDL_SUCCESS)
240 rc = gdl_plane_config_end (GDL_FALSE);
242 gdl_plane_config_end (GDL_TRUE);
244 if (rc != GDL_SUCCESS)
246 g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
247 "GDL configuration failed: %s.", gdl_get_error_string (rc));
257 _cogl_winsys_egl_display_setup (CoglDisplay *display,
260 CoglDisplayEGL *egl_display = display->winsys;
261 CoglDisplayGDL *gdl_display;
263 gdl_display = g_slice_new0 (CoglDisplayGDL);
264 egl_display->platform = gdl_display;
266 if (!gdl_plane_init (display, error))
273 _cogl_winsys_egl_display_destroy (CoglDisplay *display)
275 CoglDisplayEGL *egl_display = display->winsys;
277 g_slice_free (CoglDisplayGDL, egl_display->platform);
281 _cogl_winsys_egl_cleanup_context (CoglDisplay *display)
283 CoglRenderer *renderer = display->renderer;
284 CoglRendererEGL *egl_renderer = renderer->winsys;
285 CoglDisplayEGL *egl_display = display->winsys;
287 if (egl_display->egl_surface != EGL_NO_SURFACE)
289 eglDestroySurface (egl_renderer->edpy, egl_display->egl_surface);
290 egl_display->egl_surface = EGL_NO_SURFACE;
295 _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
296 EGLConfig egl_config,
299 CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
300 CoglContext *context = framebuffer->context;
301 CoglDisplay *display = context->display;
302 CoglDisplayEGL *egl_display = display->winsys;
303 CoglDisplayGDL *gdl_display = egl_display->platform;
304 CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
306 if (gdl_display->have_onscreen)
308 g_set_error (error, COGL_WINSYS_ERROR,
309 COGL_WINSYS_ERROR_CREATE_ONSCREEN,
310 "EGL platform only supports a single onscreen window");
314 egl_onscreen->egl_surface = egl_display->egl_surface;
316 _cogl_framebuffer_winsys_update_size (framebuffer,
317 gdl_display->egl_surface_width,
318 gdl_display->egl_surface_height);
319 gdl_display->have_onscreen = TRUE;
325 _cogl_winsys_egl_add_config_attributes (CoglDisplay *display,
326 CoglFramebufferConfig *config,
331 /* XXX: Why does the GDL platform choose these by default? */
332 attributes[i++] = EGL_BIND_TO_TEXTURE_RGBA;
333 attributes[i++] = EGL_TRUE;
334 attributes[i++] = EGL_BIND_TO_TEXTURE_RGB;
335 attributes[i++] = EGL_TRUE;
340 static const CoglWinsysEGLVtable
341 _cogl_winsys_egl_vtable =
343 .display_setup = _cogl_winsys_egl_display_setup,
344 .display_destroy = _cogl_winsys_egl_display_destroy,
345 .context_created = _cogl_winsys_egl_context_created,
346 .cleanup_context = _cogl_winsys_egl_cleanup_context,
347 .onscreen_init = _cogl_winsys_egl_onscreen_init,
348 .add_config_attributes = _cogl_winsys_egl_add_config_attributes
351 const CoglWinsysVtable *
352 _cogl_winsys_egl_gdl_get_vtable (void)
354 static gboolean vtable_inited = FALSE;
355 static CoglWinsysVtable vtable;
359 /* The EGL_GDL winsys is a subclass of the EGL winsys so we
360 start by copying its vtable */
362 vtable = *_cogl_winsys_egl_get_vtable ();
364 vtable.id = COGL_WINSYS_ID_EGL_GDL;
365 vtable.name = "EGL_GDL";
367 vtable.renderer_connect = _cogl_winsys_renderer_connect;
368 vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
370 vtable_inited = TRUE;