• 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 #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
initOpenglesEmulationFuncs(ADynamicLibrary * rendererLib)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
android_initOpenglesEmulation(void)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
android_startOpenglesRenderer(int width,int height)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
android_stopOpenglesRenderer(void)153 android_stopOpenglesRenderer(void)
154 {
155     if (rendererLib) {
156         stopOpenGLRenderer();
157     }
158 }
159 
160 int
android_showOpenglesWindow(void * window,int x,int y,int width,int height,float rotation)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
android_hideOpenglesWindow(void)171 android_hideOpenglesWindow(void)
172 {
173     if (rendererLib) {
174         return destroyOpenGLSubwindow();
175     } else {
176         return -1;
177     }
178 }
179 
180 void
android_redrawOpenglesWindow(void)181 android_redrawOpenglesWindow(void)
182 {
183     if (rendererLib) {
184         repaintOpenGLDisplay();
185     }
186 }
187 
188 void
android_gles_unix_path(char * buff,size_t buffsize,int port)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