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;