4 * Window management using EGL.
6 * Copyright (c) 2012 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program 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
16 * GNU General Public License for more details.
21 #include "video_egl.h"
23 #include "pvr2/pvr2.h"
24 #include "pvr2/glutil.h"
26 static const char *getEGLErrorString( EGLint code )
29 case EGL_SUCCESS: return "OK";
30 case EGL_NOT_INITIALIZED: return "EGL not initialized";
31 case EGL_BAD_ACCESS: return "Bad access";
32 case EGL_BAD_ALLOC: return "Allocation failed";
33 case EGL_BAD_ATTRIBUTE: return "Bad attribute";
34 case EGL_BAD_CONTEXT: return "Bad context";
35 case EGL_BAD_CONFIG: return "Bad config";
36 case EGL_BAD_CURRENT_SURFACE: return "Bad current surface";
37 case EGL_BAD_DISPLAY: return "Bad display";
38 case EGL_BAD_MATCH: return "Bad match";
39 case EGL_BAD_PARAMETER: return "Bad parameter";
40 case EGL_BAD_NATIVE_PIXMAP: return "Bad native pixmap";
41 case EGL_BAD_NATIVE_WINDOW: return "Bad native window";
42 default: return "Unknown error";
47 static void logEGLError(const char *msg)
49 EGLint error = eglGetError();
50 const char *errorStr = getEGLErrorString(error);
52 ERROR( "%s: %s (%x)", msg, errorStr, error );
55 static const EGLint RGB888_attributes[] = {
61 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
62 EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
65 static const EGLint RGB565_attributes[] = {
71 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
72 EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
75 static const EGLint context_attributes[] = {
76 EGL_CONTEXT_CLIENT_VERSION, 2,
79 static EGLDisplay display;
80 static EGLContext context = EGL_NO_CONTEXT;
81 static EGLSurface surface = EGL_NO_SURFACE;
82 static gboolean fbo_created = FALSE;
84 gboolean video_egl_set_window(EGLNativeWindowType window, int width, int height, int format)
87 EGLint num_config, major = 0, minor = 0;
88 const EGLint *attribute_list;
90 display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
91 if( eglInitialize(display, &major, &minor) != EGL_TRUE ) {
92 logEGLError( "Unable to initialise EGL display" );
96 if( format == COLFMT_RGB565 || format == COLFMT_BGRA1555 ) {
97 attribute_list = RGB565_attributes;
99 attribute_list = RGB888_attributes;
103 eglChooseConfig(display, attribute_list, &config, 1, &num_config);
105 context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
106 if( context == EGL_NO_CONTEXT ) {
107 logEGLError( "Unable to create EGL context" );
108 video_egl_clear_window();
112 surface = eglCreateWindowSurface(display, config, window, NULL);
113 if( surface == EGL_NO_SURFACE ) {
114 logEGLError( "Unable to create EGL surface" );
115 video_egl_clear_window();
119 if( eglMakeCurrent( display, surface, surface, context ) == EGL_FALSE ) {
120 video_egl_clear_window();
124 if( gl_fbo_is_supported() ) {
125 display_egl_driver.capabilities.has_gl = TRUE;
126 display_egl_driver.capabilities.depth_bits = 16; /* TODO: get from config info */
127 gl_fbo_init(&display_egl_driver);
128 gl_vbo_init(&display_egl_driver);
129 glsl_init(&display_egl_driver);
132 ERROR( "Display does not support FBO" );
133 video_egl_clear_window();
136 gl_set_video_size(width, height, 0);
137 pvr2_setup_gl_context();
138 INFO( "Initialised EGL %d.%d\n", major, minor );
142 void video_egl_clear_window()
148 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
149 if( surface != EGL_NO_SURFACE ) {
150 eglDestroySurface(display, surface);
151 surface = EGL_NO_SURFACE;
153 if( context != EGL_NO_CONTEXT ) {
154 eglDestroyContext(display, context);
155 context = EGL_NO_CONTEXT;
157 eglTerminate(display);
160 static void video_egl_swap_buffers()
162 eglSwapBuffers(display, surface);
167 * Minimal init and shutdown. The real work is done from set_window
169 struct display_driver display_egl_driver = {
170 "egl", N_("OpenGLES driver"), NULL, NULL,
172 NULL, NULL, NULL, NULL,
173 gl_load_frame_buffer, gl_display_render_buffer, gl_display_blank,
174 video_egl_swap_buffers, gl_read_render_buffer, NULL, NULL
.