blob: 5a29d3afa244faf1d805caf60836e25e685ee25a [file] [log] [blame]
David 'Digit' Turnercb88e792011-08-26 01:35:14 +02001/* 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"
David Turner7b56a4a2011-09-12 18:21:58 +020015#include "android/globals.h"
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020016#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
David Turner7b56a4a2011-09-12 18:21:58 +020026/* Declared in "android/globals.h" */
27int android_gles_fast_pipes = 1;
28
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020029/* Name of the GLES rendering library we're going to use */
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070030#if HOST_LONG_BITS == 32
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020031#define RENDERER_LIB_NAME "libOpenglRender"
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070032#elif HOST_LONG_BITS == 64
33#define RENDERER_LIB_NAME "lib64OpenglRender"
34#else
35#error Unknown HOST_LONG_BITS
36#endif
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020037
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) \
David Turner7b56a4a2011-09-12 18:21:58 +020043 DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020044 DYNLINK_FUNC(int,initOpenGLRenderer,(int width, int height, int port),(width,height,port),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
David Turner7b56a4a2011-09-12 18:21:58 +020050#define STREAM_MODE_DEFAULT 0
51#define STREAM_MODE_TCP 1
52#define STREAM_MODE_UNIX 2
53#define STREAM_MODE_PIPE 3
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020054
55#ifndef CONFIG_STANDALONE_UI
56/* Defined in android/hw-pipe-net.c */
57extern int android_init_opengles_pipes(void);
58#endif
59
60static 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
69DYNLINK_FUNCTIONS
70
71#undef DYNLINK_FUNC
72
73static int
74initOpenglesEmulationFuncs(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 }
87DYNLINK_FUNCTIONS
88#undef DYNLINK_FUNC
89 return 0;
90}
91
92int
93android_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
David Turner7b56a4a2011-09-12 18:21:58 +0200124 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 }
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200134 return 0;
135
136BAD_EXIT:
137 derror("OpenGLES emulation library could not be initialized!");
138 adynamicLibrary_close(rendererLib);
139 rendererLib = NULL;
140 return -1;
141}
142
143int
144android_startOpenglesRenderer(int width, int height)
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) != 0) {
152 D("Can't start OpenGLES renderer?");
153 return -1;
154 }
155 return 0;
156}
157
158void
159android_stopOpenglesRenderer(void)
160{
161 if (rendererLib) {
162 stopOpenGLRenderer();
163 }
164}
165
166int
167android_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
176int
177android_hideOpenglesWindow(void)
178{
179 if (rendererLib) {
180 return destroyOpenGLSubwindow();
181 } else {
182 return -1;
183 }
184}
185
186void
187android_redrawOpenglesWindow(void)
188{
189 if (rendererLib) {
190 repaintOpenGLDisplay();
191 }
192}
David Turner7b56a4a2011-09-12 18:21:58 +0200193
194void
195android_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}