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 <android/native_window.h>
34 #include "cogl-winsys-egl-android-private.h"
35 #include "cogl-winsys-egl-private.h"
36 #include "cogl-renderer-private.h"
37 #include "cogl-framebuffer-private.h"
38 #include "cogl-onscreen-private.h"
39 #include "cogl-private.h"
41 static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
43 typedef struct _CoglDisplayAndroid
45 int egl_surface_width;
46 int egl_surface_height;
47 gboolean have_onscreen;
50 static ANativeWindow *android_native_window;
53 cogl_android_set_native_window (ANativeWindow *window)
57 android_native_window = window;
61 _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
63 CoglRendererEGL *egl_renderer = renderer->winsys;
65 eglTerminate (egl_renderer->edpy);
67 g_slice_free (CoglRendererEGL, egl_renderer);
71 _cogl_winsys_renderer_connect (CoglRenderer *renderer,
74 CoglRendererEGL *egl_renderer;
76 renderer->winsys = g_slice_new0 (CoglRendererEGL);
77 egl_renderer = renderer->winsys;
79 egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
81 egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
83 if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
89 _cogl_winsys_renderer_disconnect (renderer);
94 _cogl_winsys_egl_context_created (CoglDisplay *display,
97 CoglRenderer *renderer = display->renderer;
98 CoglRendererEGL *egl_renderer = renderer->winsys;
99 CoglDisplayEGL *egl_display = display->winsys;
100 CoglDisplayAndroid *android_display = egl_display->platform;
101 const char *error_message;
104 if (android_native_window == NULL)
106 error_message = "No ANativeWindow window specified with "
107 "cogl_android_set_native_window()";
111 /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
112 * guaranteed to be accepted by ANativeWindow_setBuffersGeometry ().
113 * As soon as we picked a EGLConfig, we can safely reconfigure the
114 * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
115 eglGetConfigAttrib (egl_renderer->edpy,
116 egl_display->egl_config,
117 EGL_NATIVE_VISUAL_ID, &format);
119 ANativeWindow_setBuffersGeometry (android_native_window,
124 egl_display->egl_surface =
125 eglCreateWindowSurface (egl_renderer->edpy,
126 egl_display->egl_config,
127 (NativeWindowType) android_native_window,
129 if (egl_display->egl_surface == EGL_NO_SURFACE)
131 error_message = "Unable to create EGL window surface";
135 if (!eglMakeCurrent (egl_renderer->edpy,
136 egl_display->egl_surface,
137 egl_display->egl_surface,
138 egl_display->egl_context))
140 error_message = "Unable to eglMakeCurrent with egl surface";
144 eglQuerySurface (egl_renderer->edpy,
145 egl_display->egl_surface,
147 &android_display->egl_surface_width);
149 eglQuerySurface (egl_renderer->edpy,
150 egl_display->egl_surface,
152 &android_display->egl_surface_height);
157 g_set_error (error, COGL_WINSYS_ERROR,
158 COGL_WINSYS_ERROR_CREATE_CONTEXT,
159 "%s", error_message);
164 _cogl_winsys_egl_display_setup (CoglDisplay *display,
167 CoglDisplayEGL *egl_display = display->winsys;
168 CoglDisplayAndroid *android_display;
170 android_display = g_slice_new0 (CoglDisplayAndroid);
171 egl_display->platform = android_display;
177 _cogl_winsys_egl_display_destroy (CoglDisplay *display)
179 CoglDisplayEGL *egl_display = display->winsys;
181 g_slice_free (CoglDisplayAndroid, egl_display->platform);
185 _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
186 EGLConfig egl_config,
189 CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
190 CoglContext *context = framebuffer->context;
191 CoglDisplay *display = context->display;
192 CoglDisplayEGL *egl_display = display->winsys;
193 CoglDisplayAndroid *android_display = egl_display->platform;
194 CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
196 if (android_display->have_onscreen)
198 g_set_error (error, COGL_WINSYS_ERROR,
199 COGL_WINSYS_ERROR_CREATE_ONSCREEN,
200 "EGL platform only supports a single onscreen window");
204 egl_onscreen->egl_surface = egl_display->egl_surface;
206 _cogl_framebuffer_winsys_update_size (framebuffer,
207 android_display->egl_surface_width,
208 android_display->egl_surface_height);
210 android_display->have_onscreen = TRUE;
215 static const CoglWinsysEGLVtable
216 _cogl_winsys_egl_vtable =
218 .display_setup = _cogl_winsys_egl_display_setup,
219 .display_destroy = _cogl_winsys_egl_display_destroy,
220 .context_created = _cogl_winsys_egl_context_created,
221 .onscreen_init = _cogl_winsys_egl_onscreen_init,
224 const CoglWinsysVtable *
225 _cogl_winsys_egl_android_get_vtable (void)
227 static gboolean vtable_inited = FALSE;
228 static CoglWinsysVtable vtable;
232 /* The EGL_ANDROID winsys is a subclass of the EGL winsys so we
233 start by copying its vtable */
235 vtable = *_cogl_winsys_egl_get_vtable ();
237 vtable.id = COGL_WINSYS_ID_EGL_ANDROID;
238 vtable.name = "EGL_ANDROID";
240 vtable.renderer_connect = _cogl_winsys_renderer_connect;
241 vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
243 vtable_inited = TRUE;