Search
lxdream.org :: lxdream/src/drivers/video_egl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_egl.c
changeset 1258:f8a9c0fd2abb
prev1256:a9d29fe74bf3
next1275:83b15705cdde
author nkeynes
date Mon Mar 05 11:41:03 2012 +1000 (9 years ago)
permissions -rw-r--r--
last change Small cleanups:
Refactor the post-windowing setup into gl_init_driver() in video_gl.c
Move gl_sl.c into src/drivers and tidy up a bit.
Fix OS X compiling plugins with -mdynamic-no-pic
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * Window management using EGL.
     5  *
     6  * Copyright (c) 2012 Nathan Keynes.
     7  *
     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.
    12  *
    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.
    17  */
    19 #include "lxdream.h"
    20 #include "display.h"
    21 #include "video_egl.h"
    22 #include "video_gl.h"
    23 #include "pvr2/pvr2.h"
    24 #include "pvr2/glutil.h"
    26 static const char *getEGLErrorString( EGLint code )
    27 {
    28     switch( 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";
    43     }
    44 }
    47 static void logEGLError(const char *msg)
    48 {
    49     EGLint error = eglGetError();
    50     const char *errorStr = getEGLErrorString(error);
    52     ERROR( "%s: %s (%x)", msg, errorStr, error );
    53 }
    55 static const EGLint RGB888_attributes[] = {
    56         EGL_RED_SIZE,       8,
    57         EGL_GREEN_SIZE,     8,
    58         EGL_BLUE_SIZE,      8,
    59         EGL_DEPTH_SIZE,     16,
    60         EGL_STENCIL_SIZE,   8,
    61         EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
    62         EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
    63         EGL_NONE, EGL_NONE };
    65 static const EGLint RGB565_attributes[] = {
    66         EGL_RED_SIZE,       5,
    67         EGL_GREEN_SIZE,     6,
    68         EGL_BLUE_SIZE,      5,
    69         EGL_DEPTH_SIZE,     16,
    70         EGL_STENCIL_SIZE,   8,
    71         EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
    72         EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
    73         EGL_NONE, EGL_NONE };
    75 static const EGLint context_attributes[] = {
    76         EGL_CONTEXT_CLIENT_VERSION, 2,
    77         EGL_NONE, EGL_NONE };
    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)
    85 {
    86     EGLConfig config;
    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" );
    93         return FALSE;
    94     }
    96     if( format == COLFMT_RGB565 || format == COLFMT_BGRA1555 ) {
    97         attribute_list = RGB565_attributes;
    98     } else {
    99         attribute_list = RGB888_attributes;
   100     }
   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();
   109         return FALSE;
   110     }
   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();
   116         return FALSE;
   117     }
   119     if( eglMakeCurrent( display, surface, surface, context ) == EGL_FALSE ) {
   120         video_egl_clear_window();
   121         return FALSE;
   122     }
   124     display_egl_driver.capabilities.depth_bits = 16; /* TODO: get from config info */
   125     if( !gl_init_driver(&display_egl_driver, TRUE) ) {
   126         video_egl_clear_window();
   127         return FALSE;
   128     }
   129     fbo_created = TRUE;
   130     gl_set_video_size(width, height, 0);
   131     pvr2_setup_gl_context();
   132     INFO( "Initialised EGL %d.%d\n", major, minor );
   133     return TRUE;
   134 }
   136 void video_egl_clear_window()
   137 {
   138     if( fbo_created ) {
   139         gl_fbo_shutdown();
   140         fbo_created = FALSE;
   141     }
   142     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
   143     if( surface != EGL_NO_SURFACE )  {
   144         eglDestroySurface(display, surface);
   145         surface = EGL_NO_SURFACE;
   146     }
   147     if( context != EGL_NO_CONTEXT ) {
   148         eglDestroyContext(display, context);
   149         context = EGL_NO_CONTEXT;
   150     }
   151     eglTerminate(display);
   152 }
   154 static void video_egl_swap_buffers()
   155 {
   156     eglSwapBuffers(display, surface);
   157 }
   160 /**
   161  * Minimal init and shutdown. The real work is done from set_window
   162  */
   163 struct display_driver display_egl_driver = {
   164         "egl", N_("OpenGLES driver"), NULL, NULL,
   165         NULL, NULL, NULL,
   166         NULL, NULL, NULL, NULL,
   167         gl_load_frame_buffer, gl_display_render_buffer, gl_display_blank,
   168         video_egl_swap_buffers, gl_read_render_buffer, NULL, NULL
   169 };
.