blob: d1f4322f4f0b55e702823733e0222748eb50a445 [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"
Jesse Hall183e9272012-04-26 15:13:27 -070015
16/* Declared in "android/globals.h" */
17int android_gles_fast_pipes = 1;
18
19#if CONFIG_ANDROID_OPENGLES
20
David Turner7b56a4a2011-09-12 18:21:58 +020021#include "android/globals.h"
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020022#include <android/utils/debug.h>
23#include <android/utils/path.h>
24#include <android/utils/bufprint.h>
25#include <android/utils/dll.h>
Jesse Hall183e9272012-04-26 15:13:27 -070026
27#define RENDER_API_NO_PROTOTYPES 1
Jesse Hall6699b682012-04-18 10:28:46 -070028#include <libOpenglRender/render_api.h>
Jesse Hall183e9272012-04-26 15:13:27 -070029
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020030#include <stdio.h>
31#include <stdlib.h>
32
33#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
34#define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__)
35
36/* Name of the GLES rendering library we're going to use */
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070037#if HOST_LONG_BITS == 32
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020038#define RENDERER_LIB_NAME "libOpenglRender"
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070039#elif HOST_LONG_BITS == 64
40#define RENDERER_LIB_NAME "lib64OpenglRender"
41#else
42#error Unknown HOST_LONG_BITS
43#endif
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020044
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020045#define DYNLINK_FUNCTIONS \
Jesse Hall6699b682012-04-18 10:28:46 -070046 DYNLINK_FUNC(initLibrary) \
47 DYNLINK_FUNC(setStreamMode) \
48 DYNLINK_FUNC(initOpenGLRenderer) \
49 DYNLINK_FUNC(createOpenGLSubwindow) \
50 DYNLINK_FUNC(destroyOpenGLSubwindow) \
51 DYNLINK_FUNC(repaintOpenGLDisplay) \
52 DYNLINK_FUNC(stopOpenGLRenderer)
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020053
54#ifndef CONFIG_STANDALONE_UI
55/* Defined in android/hw-pipe-net.c */
56extern int android_init_opengles_pipes(void);
57#endif
58
59static ADynamicLibrary* rendererLib;
60
Jesse Hall6699b682012-04-18 10:28:46 -070061/* Define the function pointers */
62#define DYNLINK_FUNC(name) \
63 static name##Fn name = NULL;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020064DYNLINK_FUNCTIONS
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020065#undef DYNLINK_FUNC
66
67static int
68initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib)
69{
70 void* symbol;
71 char* error;
Jesse Hall6699b682012-04-18 10:28:46 -070072
73#define DYNLINK_FUNC(name) \
74 symbol = adynamicLibrary_findSymbol(rendererLib, #name, &error); \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020075 if (symbol != NULL) { \
Jesse Hall6699b682012-04-18 10:28:46 -070076 name = symbol; \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020077 } else { \
78 derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \
79 free(error); \
80 return -1; \
81 }
82DYNLINK_FUNCTIONS
83#undef DYNLINK_FUNC
Jesse Hall6699b682012-04-18 10:28:46 -070084
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020085 return 0;
86}
87
88int
89android_initOpenglesEmulation(void)
90{
91 char* error = NULL;
92
93 if (rendererLib != NULL)
94 return 0;
95
96 D("Initializing hardware OpenGLES emulation support");
97
98 rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error);
99 if (rendererLib == NULL) {
100 derror("Could not load OpenGLES emulation library: %s", error);
101 return -1;
102 }
103
104#ifndef CONFIG_STANDALONE_UI
105 android_init_opengles_pipes();
106#endif
107
108
109 /* Resolve the functions */
110 if (initOpenglesEmulationFuncs(rendererLib) < 0) {
111 derror("OpenGLES emulation library mismatch. Be sure to use the correct version!");
112 goto BAD_EXIT;
113 }
114
115 if (!initLibrary()) {
116 derror("OpenGLES initialization failed!");
117 goto BAD_EXIT;
118 }
119
David Turner7b56a4a2011-09-12 18:21:58 +0200120 if (android_gles_fast_pipes) {
121#ifdef _WIN32
122 /* XXX: NEED Win32 pipe implementation */
123 setStreamMode(STREAM_MODE_TCP);
124#else
Jesse Hall6699b682012-04-18 10:28:46 -0700125 setStreamMode(STREAM_MODE_UNIX);
David Turner7b56a4a2011-09-12 18:21:58 +0200126#endif
127 } else {
Jesse Hall6699b682012-04-18 10:28:46 -0700128 setStreamMode(STREAM_MODE_TCP);
David Turner7b56a4a2011-09-12 18:21:58 +0200129 }
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200130 return 0;
131
132BAD_EXIT:
133 derror("OpenGLES emulation library could not be initialized!");
134 adynamicLibrary_close(rendererLib);
135 rendererLib = NULL;
136 return -1;
137}
138
139int
Jesse Hall07ca7c22012-04-25 22:05:07 -0700140android_startOpenglesRenderer(int width, int height, OnPostFunc onPost, void* onPostContext)
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200141{
142 if (!rendererLib) {
143 D("Can't start OpenGLES renderer without support libraries");
144 return -1;
145 }
146
Jesse Hall6699b682012-04-18 10:28:46 -0700147 if (!initOpenGLRenderer(width, height, ANDROID_OPENGLES_BASE_PORT, onPost, onPostContext)) {
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200148 D("Can't start OpenGLES renderer?");
149 return -1;
150 }
151 return 0;
152}
153
154void
155android_stopOpenglesRenderer(void)
156{
157 if (rendererLib) {
158 stopOpenGLRenderer();
159 }
160}
161
162int
163android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation)
164{
165 if (rendererLib) {
Jesse Hall6699b682012-04-18 10:28:46 -0700166 int success = createOpenGLSubwindow((FBNativeWindowType)window, x, y, width, height, rotation);
167 return success ? 0 : -1;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200168 } else {
169 return -1;
170 }
171}
172
173int
174android_hideOpenglesWindow(void)
175{
176 if (rendererLib) {
Jesse Hall6699b682012-04-18 10:28:46 -0700177 int success = destroyOpenGLSubwindow();
178 return success ? 0 : -1;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200179 } else {
180 return -1;
181 }
182}
183
184void
185android_redrawOpenglesWindow(void)
186{
187 if (rendererLib) {
188 repaintOpenGLDisplay();
189 }
190}
David Turner7b56a4a2011-09-12 18:21:58 +0200191
192void
193android_gles_unix_path(char* buff, size_t buffsize, int port)
194{
195 const char* user = getenv("USER");
196 char *p = buff, *end = buff + buffsize;
197
198 /* The logic here must correspond to the one inside
199 * development/tools/emulator/opengl/shared/libOpenglCodecCommon/UnixStream.cpp */
200 p = bufprint(p, end, "/tmp/");
201 if (user && user[0]) {
202 p = bufprint(p, end, "android-%s/", user);
203 }
204 p = bufprint(p, end, "qemu-gles-%d", port);
205}
Jesse Hall183e9272012-04-26 15:13:27 -0700206
207#else // CONFIG_ANDROID_OPENGLES
208
209int android_initOpenglesEmulation(void)
210{
211 return -1;
212}
213
214int android_startOpenglesRenderer(int width, int height, OnPostFunc onPost, void* onPostContext)
215{
216 return -1;
217}
218
219void android_stopOpenglesRenderer(void)
220{}
221
222int android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation)
223{
224 return -1;
225}
226
227int android_hideOpenglesWindow(void)
228{
229 return -1;
230}
231
232void android_redrawOpenglesWindow(void)
233{}
234
235void android_gles_unix_path(char* buff, size_t buffsize, int port)
236{
237 buff[0] = '\0';
238}
239
240#endif // !CONFIG_ANDROID_OPENGLES