• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if HOST_LONG_BITS == 32
31 #define RENDERER_LIB_NAME  "libOpenglRender"
32 #elif HOST_LONG_BITS == 64
33 #define RENDERER_LIB_NAME  "lib64OpenglRender"
34 #else
35 #error Unknown HOST_LONG_BITS
36 #endif
37 
38 /* These definitions *must* match those under:
39  * development/tools/emulator/opengl/host/include/libOpenglRender/render_api.h
40  */
41 #define DYNLINK_FUNCTIONS  \
42   DYNLINK_FUNC(int,initLibrary,(void),(),return) \
43   DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \
44   DYNLINK_FUNC(int,initOpenGLRenderer,(int width, int height, int port, OnPostFn onPost, void* onPostContext),(width,height,port,onPost,onPostContext),return) \
45   DYNLINK_FUNC(int,createOpenGLSubwindow,(void* window, int x, int y, int width, int height, float zRot),(window,x,y,width,height,zRot),return)\
46   DYNLINK_FUNC(int,destroyOpenGLSubwindow,(void),(),return)\
47   DYNLINK_FUNC(void,repaintOpenGLDisplay,(void),(),)\
48   DYNLINK_FUNC(void,stopOpenGLRenderer,(void),(),)
49 
50 #define STREAM_MODE_DEFAULT  0
51 #define STREAM_MODE_TCP      1
52 #define STREAM_MODE_UNIX     2
53 #define STREAM_MODE_PIPE     3
54 
55 #ifndef CONFIG_STANDALONE_UI
56 /* Defined in android/hw-pipe-net.c */
57 extern int android_init_opengles_pipes(void);
58 #endif
59 
60 static ADynamicLibrary*  rendererLib;
61 
62 /* Define the pointers and the wrapper functions to call them */
63 #define DYNLINK_FUNC(result,name,sig,params,ret) \
64     static result (*_ptr_##name) sig; \
65     static result name sig { \
66         ret (*_ptr_##name) params ; \
67     }
68 
69 DYNLINK_FUNCTIONS
70 
71 #undef DYNLINK_FUNC
72 
73 static int
initOpenglesEmulationFuncs(ADynamicLibrary * rendererLib)74 initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib)
75 {
76     void*  symbol;
77     char*  error;
78 #define DYNLINK_FUNC(result,name,sig,params,ret) \
79     symbol = adynamicLibrary_findSymbol( rendererLib, #name, &error ); \
80     if (symbol != NULL) { \
81         _ptr_##name = symbol; \
82     } else { \
83         derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \
84         free(error); \
85         return -1; \
86     }
87 DYNLINK_FUNCTIONS
88 #undef DYNLINK_FUNC
89     return 0;
90 }
91 
92 int
android_initOpenglesEmulation(void)93 android_initOpenglesEmulation(void)
94 {
95     char* error = NULL;
96 
97     if (rendererLib != NULL)
98         return 0;
99 
100     D("Initializing hardware OpenGLES emulation support");
101 
102     rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error);
103     if (rendererLib == NULL) {
104         derror("Could not load OpenGLES emulation library: %s", error);
105         return -1;
106     }
107 
108 #ifndef CONFIG_STANDALONE_UI
109     android_init_opengles_pipes();
110 #endif
111 
112 
113     /* Resolve the functions */
114     if (initOpenglesEmulationFuncs(rendererLib) < 0) {
115         derror("OpenGLES emulation library mismatch. Be sure to use the correct version!");
116         goto BAD_EXIT;
117     }
118 
119     if (!initLibrary()) {
120         derror("OpenGLES initialization failed!");
121         goto BAD_EXIT;
122     }
123 
124     if (android_gles_fast_pipes) {
125 #ifdef _WIN32
126         /* XXX: NEED Win32 pipe implementation */
127         setStreamMode(STREAM_MODE_TCP);
128 #else
129 	setStreamMode(STREAM_MODE_UNIX);
130 #endif
131     } else {
132 	setStreamMode(STREAM_MODE_TCP);
133     }
134     return 0;
135 
136 BAD_EXIT:
137     derror("OpenGLES emulation library could not be initialized!");
138     adynamicLibrary_close(rendererLib);
139     rendererLib = NULL;
140     return -1;
141 }
142 
143 int
android_startOpenglesRenderer(int width,int height,OnPostFn onPost,void * onPostContext)144 android_startOpenglesRenderer(int width, int height, OnPostFn onPost, void* onPostContext)
145 {
146     if (!rendererLib) {
147         D("Can't start OpenGLES renderer without support libraries");
148         return -1;
149     }
150 
151     if (initOpenGLRenderer(width, height, ANDROID_OPENGLES_BASE_PORT, onPost, onPostContext) != 0) {
152         D("Can't start OpenGLES renderer?");
153         return -1;
154     }
155     return 0;
156 }
157 
158 void
android_stopOpenglesRenderer(void)159 android_stopOpenglesRenderer(void)
160 {
161     if (rendererLib) {
162         stopOpenGLRenderer();
163     }
164 }
165 
166 int
android_showOpenglesWindow(void * window,int x,int y,int width,int height,float rotation)167 android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation)
168 {
169     if (rendererLib) {
170         return createOpenGLSubwindow(window, x, y, width, height, rotation);
171     } else {
172         return -1;
173     }
174 }
175 
176 int
android_hideOpenglesWindow(void)177 android_hideOpenglesWindow(void)
178 {
179     if (rendererLib) {
180         return destroyOpenGLSubwindow();
181     } else {
182         return -1;
183     }
184 }
185 
186 void
android_redrawOpenglesWindow(void)187 android_redrawOpenglesWindow(void)
188 {
189     if (rendererLib) {
190         repaintOpenGLDisplay();
191     }
192 }
193 
194 void
android_gles_unix_path(char * buff,size_t buffsize,int port)195 android_gles_unix_path(char* buff, size_t buffsize, int port)
196 {
197     const char* user = getenv("USER");
198     char *p = buff, *end = buff + buffsize;
199 
200     /* The logic here must correspond to the one inside
201      * development/tools/emulator/opengl/shared/libOpenglCodecCommon/UnixStream.cpp */
202     p = bufprint(p, end, "/tmp/");
203     if (user && user[0]) {
204         p = bufprint(p, end, "android-%s/", user);
205     }
206     p = bufprint(p, end, "qemu-gles-%d", port);
207 }
208