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 1245:01e0020adf88
next1251:b8ab59d39756
author nkeynes
date Fri Mar 02 23:49:10 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Android WIP:
* Rename gui_jni.c to gui_android.c - now quite android specific.
* Implement generic EGL driver with very minimal Java wrapper
* Run emulation in separate thread, and implement simple queue for
inter-thread communication.
* Add menu/action-bar items for start + reset
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     if( gl_fbo_is_supported() ) {
   125         display_gl_driver.capabilities.has_gl = TRUE;
   126         gl_fbo_init(&display_egl_driver);
   127         gl_vbo_init(&display_egl_driver);
   128         fbo_created = TRUE;
   129     } else {
   130         ERROR( "Display does not support FBO" );
   131         video_egl_clear_window();
   132         return FALSE;
   133     }
   134     pvr2_setup_gl_context();
   135     INFO( "Initialised EGL %d.%d\n", major, minor );
   136     return TRUE;
   137 }
   139 void video_egl_clear_window()
   140 {
   141     if( fbo_created ) {
   142         gl_fbo_shutdown();
   143         fbo_created = FALSE;
   144     }
   145     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
   146     if( surface != EGL_NO_SURFACE )  {
   147         eglDestroySurface(display, surface);
   148         surface = EGL_NO_SURFACE;
   149     }
   150     if( context != EGL_NO_CONTEXT ) {
   151         eglDestroyContext(display, context);
   152         context = EGL_NO_CONTEXT;
   153     }
   154     eglTerminate(display);
   155 }
   159 /**
   160  * Minimal init and shutdown. The real work is done from set_window
   161  */
   162 struct display_driver display_egl_driver = {
   163         "egl", N_("OpenGLES driver"), NULL, NULL,
   164         NULL, NULL, NULL,
   165         NULL, NULL, NULL, NULL,
   166         gl_load_frame_buffer, gl_display_render_buffer, gl_display_blank,
   167         NULL, gl_read_render_buffer, NULL, NULL
   168 };
.