~darkxst/ubuntu/raring/cogl/lp1163025

« back to all changes in this revision

Viewing changes to cogl/winsys/cogl-winsys-egl-gdl.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2012-03-13 19:11:11 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120313191111-3hgk529qkh9m6uk2
Tags: 1.9.8-0ubuntu1
* New upstream release (LP: #941617)
* Updated symbols & library name for soname update
* debian/control.in: Bump minimum glib to 2.28
* debian/patches/02_disable_armv5t_specific_optimization.patch: Disabled

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Cogl
 
3
 *
 
4
 * An object oriented GL/GLES Abstraction/Utility Layer
 
5
 *
 
6
 * Copyright (C) 2011 Intel Corporation.
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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/>.
 
21
 *
 
22
 *
 
23
 * Authors:
 
24
 *   Robert Bragg <robert@linux.intel.com>
 
25
 *   Neil Roberts <neil@linux.intel.com>
 
26
 */
 
27
 
 
28
#ifdef HAVE_CONFIG_H
 
29
#include "config.h"
 
30
#endif
 
31
 
 
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"
 
39
 
 
40
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
 
41
 
 
42
typedef struct _CoglRendererGDL
 
43
{
 
44
  gboolean gdl_initialized;
 
45
} CoglRendererGDL;
 
46
 
 
47
typedef struct _CoglDisplayGDL
 
48
{
 
49
  int egl_surface_width;
 
50
  int egl_surface_height;
 
51
  gboolean have_onscreen;
 
52
} CoglDisplayGDL;
 
53
 
 
54
static void
 
55
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
 
56
{
 
57
  CoglRendererEGL *egl_renderer = renderer->winsys;
 
58
  CoglRendererGDL *gdl_renderer = egl_renderer->platform;
 
59
 
 
60
  if (gdl_renderer->gdl_initialized)
 
61
    gdl_close ();
 
62
 
 
63
  eglTerminate (egl_renderer->edpy);
 
64
 
 
65
  g_slice_free (CoglRendererEGL, egl_renderer);
 
66
}
 
67
 
 
68
static gboolean
 
69
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
 
70
                               GError **error)
 
71
{
 
72
  CoglRendererEGL *egl_renderer;
 
73
  CoglRendererGDL *gdl_renderer;
 
74
  gdl_ret_t rc = GDL_SUCCESS;
 
75
  gdl_display_info_t gdl_display_info;
 
76
 
 
77
  renderer->winsys = g_slice_new0 (CoglRendererEGL);
 
78
  egl_renderer = renderer->winsys;
 
79
 
 
80
  gdl_renderer = g_slice_new0 (CoglRendererGDL);
 
81
  egl_renderer->platform = gdl_renderer;
 
82
 
 
83
  egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
 
84
 
 
85
  egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
 
86
 
 
87
  if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
 
88
    goto error;
 
89
 
 
90
  /* Check we can talk to the GDL library */
 
91
  rc = gdl_init (NULL);
 
92
  if (rc != GDL_SUCCESS)
 
93
    {
 
94
      g_set_error (error, COGL_WINSYS_ERROR,
 
95
                   COGL_WINSYS_ERROR_INIT,
 
96
                   "GDL initialize failed. %s",
 
97
                   gdl_get_error_string (rc));
 
98
      goto error;
 
99
    }
 
100
 
 
101
  rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &gdl_display_info);
 
102
  if (rc != GDL_SUCCESS)
 
103
    {
 
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));
 
108
      gdl_close ();
 
109
      goto error;
 
110
    }
 
111
 
 
112
  gdl_close ();
 
113
 
 
114
  return TRUE;
 
115
 
 
116
error:
 
117
  _cogl_winsys_renderer_disconnect (renderer);
 
118
  return FALSE;
 
119
}
 
120
 
 
121
static gboolean
 
122
_cogl_winsys_egl_context_created (CoglDisplay *display,
 
123
                                  GError **error)
 
124
{
 
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;
 
130
 
 
131
  egl_display->egl_surface =
 
132
    eglCreateWindowSurface (egl_renderer->edpy,
 
133
                            egl_display->egl_config,
 
134
                            (NativeWindowType) display->gdl_plane,
 
135
                            NULL);
 
136
 
 
137
  if (egl_display->egl_surface == EGL_NO_SURFACE)
 
138
    {
 
139
      error_message = "Unable to create EGL window surface";
 
140
      goto fail;
 
141
    }
 
142
 
 
143
  if (!eglMakeCurrent (egl_renderer->edpy,
 
144
                       egl_display->egl_surface,
 
145
                       egl_display->egl_surface,
 
146
                       egl_display->egl_context))
 
147
    {
 
148
      error_message = "Unable to eglMakeCurrent with egl surface";
 
149
      goto fail;
 
150
    }
 
151
 
 
152
  eglQuerySurface (egl_renderer->edpy,
 
153
                   egl_display->egl_surface,
 
154
                   EGL_WIDTH,
 
155
                   &gdl_display->egl_surface_width);
 
156
 
 
157
  eglQuerySurface (egl_renderer->edpy,
 
158
                   egl_display->egl_surface,
 
159
                   EGL_HEIGHT,
 
160
                   &gdl_display->egl_surface_height);
 
161
 
 
162
  return TRUE;
 
163
 
 
164
 fail:
 
165
  g_set_error (error, COGL_WINSYS_ERROR,
 
166
               COGL_WINSYS_ERROR_CREATE_CONTEXT,
 
167
               "%s", error_message);
 
168
  return FALSE;
 
169
}
 
170
 
 
171
static gboolean
 
172
gdl_plane_init (CoglDisplay *display, GError **error)
 
173
{
 
174
  gboolean ret = TRUE;
 
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;
 
180
 
 
181
  if (!display->gdl_plane)
 
182
    {
 
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");
 
186
      return FALSE;
 
187
    }
 
188
 
 
189
  rc = gdl_init (NULL);
 
190
  if (rc != GDL_SUCCESS)
 
191
    {
 
192
      g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
 
193
                   "GDL initialize failed. %s", gdl_get_error_string (rc));
 
194
      return FALSE;
 
195
    }
 
196
 
 
197
  rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &display_info);
 
198
  if (rc != GDL_SUCCESS)
 
199
    {
 
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));
 
203
      gdl_close ();
 
204
      return FALSE;
 
205
    }
 
206
 
 
207
  dstRect.origin.x = 0;
 
208
  dstRect.origin.y = 0;
 
209
  dstRect.width = display_info.tvmode.width;
 
210
  dstRect.height = display_info.tvmode.height;
 
211
 
 
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);
 
216
 
 
217
  if (rc == GDL_SUCCESS)
 
218
    rc = gdl_plane_set_attr (GDL_PLANE_SRC_COLOR_SPACE, &colorSpace);
 
219
 
 
220
  if (rc == GDL_SUCCESS)
 
221
    rc = gdl_plane_set_attr (GDL_PLANE_PIXEL_FORMAT, &pixfmt);
 
222
 
 
223
  if (rc == GDL_SUCCESS)
 
224
    rc = gdl_plane_set_attr (GDL_PLANE_DST_RECT, &dstRect);
 
225
 
 
226
  /* Default to triple buffering if the swap_chain doesn't have an explicit
 
227
   * length */
 
228
  if (rc == GDL_SUCCESS)
 
229
    {
 
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);
 
235
      else
 
236
        rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES, 3);
 
237
    }
 
238
 
 
239
  if (rc == GDL_SUCCESS)
 
240
    rc = gdl_plane_config_end (GDL_FALSE);
 
241
  else
 
242
    gdl_plane_config_end (GDL_TRUE);
 
243
 
 
244
  if (rc != GDL_SUCCESS)
 
245
    {
 
246
      g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT,
 
247
                   "GDL configuration failed: %s.", gdl_get_error_string (rc));
 
248
      ret = FALSE;
 
249
    }
 
250
 
 
251
  gdl_close ();
 
252
 
 
253
  return ret;
 
254
}
 
255
 
 
256
static gboolean
 
257
_cogl_winsys_egl_display_setup (CoglDisplay *display,
 
258
                                GError **error)
 
259
{
 
260
  CoglDisplayEGL *egl_display = display->winsys;
 
261
  CoglDisplayGDL *gdl_display;
 
262
 
 
263
  gdl_display = g_slice_new0 (CoglDisplayGDL);
 
264
  egl_display->platform = gdl_display;
 
265
 
 
266
  if (!gdl_plane_init (display, error))
 
267
    return FALSE;
 
268
 
 
269
  return TRUE;
 
270
}
 
271
 
 
272
static void
 
273
_cogl_winsys_egl_display_destroy (CoglDisplay *display)
 
274
{
 
275
  CoglDisplayEGL *egl_display = display->winsys;
 
276
 
 
277
  g_slice_free (CoglDisplayGDL, egl_display->platform);
 
278
}
 
279
 
 
280
static void
 
281
_cogl_winsys_egl_cleanup_context (CoglDisplay *display)
 
282
{
 
283
  CoglRenderer *renderer = display->renderer;
 
284
  CoglRendererEGL *egl_renderer = renderer->winsys;
 
285
  CoglDisplayEGL *egl_display = display->winsys;
 
286
 
 
287
  if (egl_display->egl_surface != EGL_NO_SURFACE)
 
288
    {
 
289
      eglDestroySurface (egl_renderer->edpy, egl_display->egl_surface);
 
290
      egl_display->egl_surface = EGL_NO_SURFACE;
 
291
    }
 
292
}
 
293
 
 
294
static gboolean
 
295
_cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
 
296
                                EGLConfig egl_config,
 
297
                                GError **error)
 
298
{
 
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;
 
305
 
 
306
  if (gdl_display->have_onscreen)
 
307
    {
 
308
      g_set_error (error, COGL_WINSYS_ERROR,
 
309
                   COGL_WINSYS_ERROR_CREATE_ONSCREEN,
 
310
                   "EGL platform only supports a single onscreen window");
 
311
      return FALSE;
 
312
    }
 
313
 
 
314
  egl_onscreen->egl_surface = egl_display->egl_surface;
 
315
 
 
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;
 
320
 
 
321
  return TRUE;
 
322
}
 
323
 
 
324
static int
 
325
_cogl_winsys_egl_add_config_attributes (CoglDisplay *display,
 
326
                                        CoglFramebufferConfig *config,
 
327
                                        EGLint *attributes)
 
328
{
 
329
  int i = 0;
 
330
 
 
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;
 
336
 
 
337
  return i;
 
338
}
 
339
 
 
340
static const CoglWinsysEGLVtable
 
341
_cogl_winsys_egl_vtable =
 
342
  {
 
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
 
349
  };
 
350
 
 
351
const CoglWinsysVtable *
 
352
_cogl_winsys_egl_gdl_get_vtable (void)
 
353
{
 
354
  static gboolean vtable_inited = FALSE;
 
355
  static CoglWinsysVtable vtable;
 
356
 
 
357
  if (!vtable_inited)
 
358
    {
 
359
      /* The EGL_GDL winsys is a subclass of the EGL winsys so we
 
360
         start by copying its vtable */
 
361
 
 
362
      vtable = *_cogl_winsys_egl_get_vtable ();
 
363
 
 
364
      vtable.id = COGL_WINSYS_ID_EGL_GDL;
 
365
      vtable.name = "EGL_GDL";
 
366
 
 
367
      vtable.renderer_connect = _cogl_winsys_renderer_connect;
 
368
      vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
 
369
 
 
370
      vtable_inited = TRUE;
 
371
    }
 
372
 
 
373
  return &vtable;
 
374
}