blob: 4913d0c0a373353e927159ca5a0b106eaa2c6d16 [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 */
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) \
David Turner7b56a4a2011-09-12 18:21:58 +020037 DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020038 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
David Turner7b56a4a2011-09-12 18:21:58 +020044#define STREAM_MODE_DEFAULT 0
45#define STREAM_MODE_TCP 1
46#define STREAM_MODE_UNIX 2
47#define STREAM_MODE_PIPE 3
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020048
49#ifndef CONFIG_STANDALONE_UI
50/* Defined in android/hw-pipe-net.c */
51extern int android_init_opengles_pipes(void);
52#endif
53
54static 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
63DYNLINK_FUNCTIONS
64
65#undef DYNLINK_FUNC
66
67static int
68initOpenglesEmulationFuncs(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 }
81DYNLINK_FUNCTIONS
82#undef DYNLINK_FUNC
83 return 0;
84}
85
86int
87android_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
David Turner7b56a4a2011-09-12 18:21:58 +0200118 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 }
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200128 return 0;
129
130BAD_EXIT:
131 derror("OpenGLES emulation library could not be initialized!");
132 adynamicLibrary_close(rendererLib);
133 rendererLib = NULL;
134 return -1;
135}
136
137int
138android_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
152void
153android_stopOpenglesRenderer(void)
154{
155 if (rendererLib) {
156 stopOpenGLRenderer();
157 }
158}
159
160int
161android_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
170int
171android_hideOpenglesWindow(void)
172{
173 if (rendererLib) {
174 return destroyOpenGLSubwindow();
175 } else {
176 return -1;
177 }
178}
179
180void
181android_redrawOpenglesWindow(void)
182{
183 if (rendererLib) {
184 repaintOpenGLDisplay();
185 }
186}
David Turner7b56a4a2011-09-12 18:21:58 +0200187
188void
189android_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}