Home | History | Annotate | Download | only in android
      1 /* Copyright (C) 2011 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 
     13 #include "config-host.h"
     14 #include "android/opengles.h"
     15 #include "android/globals.h"
     16 #include <android/utils/debug.h>
     17 #include <android/utils/path.h>
     18 #include <android/utils/bufprint.h>
     19 #include <android/utils/dll.h>
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 
     23 #define D(...)  VERBOSE_PRINT(init,__VA_ARGS__)
     24 #define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__)
     25 
     26 /* Declared in "android/globals.h" */
     27 int  android_gles_fast_pipes = 1;
     28 
     29 /* Name of the GLES rendering library we're going to use */
     30 #define RENDERER_LIB_NAME  "libOpenglRender"
     31 
     32 /* These definitions *must* match those under:
     33  * development/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
     34  */
     35 #define DYNLINK_FUNCTIONS  \
     36   DYNLINK_FUNC(int,initLibrary,(void),(),return) \
     37   DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \
     38   DYNLINK_FUNC(int,initOpenGLRenderer,(int width, int height, int port),(width,height,port),return) \
     39   DYNLINK_FUNC(int,createOpenGLSubwindow,(void* window, int x, int y, int width, int height, float zRot),(window,x,y,width,height,zRot),return)\
     40   DYNLINK_FUNC(int,destroyOpenGLSubwindow,(void),(),return)\
     41   DYNLINK_FUNC(void,repaintOpenGLDisplay,(void),(),)\
     42   DYNLINK_FUNC(void,stopOpenGLRenderer,(void),(),)
     43 
     44 #define STREAM_MODE_DEFAULT  0
     45 #define STREAM_MODE_TCP      1
     46 #define STREAM_MODE_UNIX     2
     47 #define STREAM_MODE_PIPE     3
     48 
     49 #ifndef CONFIG_STANDALONE_UI
     50 /* Defined in android/hw-pipe-net.c */
     51 extern int android_init_opengles_pipes(void);
     52 #endif
     53 
     54 static ADynamicLibrary*  rendererLib;
     55 
     56 /* Define the pointers and the wrapper functions to call them */
     57 #define DYNLINK_FUNC(result,name,sig,params,ret) \
     58     static result (*_ptr_##name) sig; \
     59     static result name sig { \
     60         ret (*_ptr_##name) params ; \
     61     }
     62 
     63 DYNLINK_FUNCTIONS
     64 
     65 #undef DYNLINK_FUNC
     66 
     67 static int
     68 initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib)
     69 {
     70     void*  symbol;
     71     char*  error;
     72 #define DYNLINK_FUNC(result,name,sig,params,ret) \
     73     symbol = adynamicLibrary_findSymbol( rendererLib, #name, &error ); \
     74     if (symbol != NULL) { \
     75         _ptr_##name = symbol; \
     76     } else { \
     77         derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \
     78         free(error); \
     79         return -1; \
     80     }
     81 DYNLINK_FUNCTIONS
     82 #undef DYNLINK_FUNC
     83     return 0;
     84 }
     85 
     86 int
     87 android_initOpenglesEmulation(void)
     88 {
     89     char* error = NULL;
     90 
     91     if (rendererLib != NULL)
     92         return 0;
     93 
     94     D("Initializing hardware OpenGLES emulation support");
     95 
     96     rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error);
     97     if (rendererLib == NULL) {
     98         derror("Could not load OpenGLES emulation library: %s", error);
     99         return -1;
    100     }
    101 
    102 #ifndef CONFIG_STANDALONE_UI
    103     android_init_opengles_pipes();
    104 #endif
    105 
    106 
    107     /* Resolve the functions */
    108     if (initOpenglesEmulationFuncs(rendererLib) < 0) {
    109         derror("OpenGLES emulation library mismatch. Be sure to use the correct version!");
    110         goto BAD_EXIT;
    111     }
    112 
    113     if (!initLibrary()) {
    114         derror("OpenGLES initialization failed!");
    115         goto BAD_EXIT;
    116     }
    117 
    118     if (android_gles_fast_pipes) {
    119 #ifdef _WIN32
    120         /* XXX: NEED Win32 pipe implementation */
    121         setStreamMode(STREAM_MODE_TCP);
    122 #else
    123 	setStreamMode(STREAM_MODE_UNIX);
    124 #endif
    125     } else {
    126 	setStreamMode(STREAM_MODE_TCP);
    127     }
    128     return 0;
    129 
    130 BAD_EXIT:
    131     derror("OpenGLES emulation library could not be initialized!");
    132     adynamicLibrary_close(rendererLib);
    133     rendererLib = NULL;
    134     return -1;
    135 }
    136 
    137 int
    138 android_startOpenglesRenderer(int width, int height)
    139 {
    140     if (!rendererLib) {
    141         D("Can't start OpenGLES renderer without support libraries");
    142         return -1;
    143     }
    144 
    145     if (initOpenGLRenderer(width, height,ANDROID_OPENGLES_BASE_PORT) != 0) {
    146         D("Can't start OpenGLES renderer?");
    147         return -1;
    148     }
    149     return 0;
    150 }
    151 
    152 void
    153 android_stopOpenglesRenderer(void)
    154 {
    155     if (rendererLib) {
    156         stopOpenGLRenderer();
    157     }
    158 }
    159 
    160 int
    161 android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation)
    162 {
    163     if (rendererLib) {
    164         return createOpenGLSubwindow(window, x, y, width, height, rotation);
    165     } else {
    166         return -1;
    167     }
    168 }
    169 
    170 int
    171 android_hideOpenglesWindow(void)
    172 {
    173     if (rendererLib) {
    174         return destroyOpenGLSubwindow();
    175     } else {
    176         return -1;
    177     }
    178 }
    179 
    180 void
    181 android_redrawOpenglesWindow(void)
    182 {
    183     if (rendererLib) {
    184         repaintOpenGLDisplay();
    185     }
    186 }
    187 
    188 void
    189 android_gles_unix_path(char* buff, size_t buffsize, int port)
    190 {
    191     const char* user = getenv("USER");
    192     char *p = buff, *end = buff + buffsize;
    193 
    194     /* The logic here must correspond to the one inside
    195      * development/tools/emulator/opengl/shared/libOpenglCodecCommon/UnixStream.cpp */
    196     p = bufprint(p, end, "/tmp/");
    197     if (user && user[0]) {
    198         p = bufprint(p, end, "android-%s/", user);
    199     }
    200     p = bufprint(p, end, "qemu-gles-%d", port);
    201 }
    202