blob: e90a477850e6d8a83d74c939f70077a2ae84b4f1 [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
Jesse Hall6699b682012-04-18 10:28:46 -070013#define RENDER_API_NO_PROTOTYPES 1
14
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020015#include "config-host.h"
16#include "android/opengles.h"
David Turner7b56a4a2011-09-12 18:21:58 +020017#include "android/globals.h"
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020018#include <android/utils/debug.h>
19#include <android/utils/path.h>
20#include <android/utils/bufprint.h>
21#include <android/utils/dll.h>
Jesse Hall6699b682012-04-18 10:28:46 -070022#include <libOpenglRender/render_api.h>
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020023#include <stdio.h>
24#include <stdlib.h>
25
26#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
27#define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__)
28
David Turner7b56a4a2011-09-12 18:21:58 +020029/* Declared in "android/globals.h" */
30int android_gles_fast_pipes = 1;
31
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020032/* Name of the GLES rendering library we're going to use */
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070033#if HOST_LONG_BITS == 32
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020034#define RENDERER_LIB_NAME "libOpenglRender"
Andrew Hsiehc7389bd2012-03-13 02:13:40 -070035#elif HOST_LONG_BITS == 64
36#define RENDERER_LIB_NAME "lib64OpenglRender"
37#else
38#error Unknown HOST_LONG_BITS
39#endif
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020040
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020041#define DYNLINK_FUNCTIONS \
Jesse Hall6699b682012-04-18 10:28:46 -070042 DYNLINK_FUNC(initLibrary) \
43 DYNLINK_FUNC(setStreamMode) \
44 DYNLINK_FUNC(initOpenGLRenderer) \
45 DYNLINK_FUNC(createOpenGLSubwindow) \
46 DYNLINK_FUNC(destroyOpenGLSubwindow) \
47 DYNLINK_FUNC(repaintOpenGLDisplay) \
48 DYNLINK_FUNC(stopOpenGLRenderer)
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020049
50#ifndef CONFIG_STANDALONE_UI
51/* Defined in android/hw-pipe-net.c */
52extern int android_init_opengles_pipes(void);
53#endif
54
55static ADynamicLibrary* rendererLib;
56
Jesse Hall6699b682012-04-18 10:28:46 -070057/* Define the function pointers */
58#define DYNLINK_FUNC(name) \
59 static name##Fn name = NULL;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020060DYNLINK_FUNCTIONS
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020061#undef DYNLINK_FUNC
62
63static int
64initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib)
65{
66 void* symbol;
67 char* error;
Jesse Hall6699b682012-04-18 10:28:46 -070068
69#define DYNLINK_FUNC(name) \
70 symbol = adynamicLibrary_findSymbol(rendererLib, #name, &error); \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020071 if (symbol != NULL) { \
Jesse Hall6699b682012-04-18 10:28:46 -070072 name = symbol; \
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020073 } else { \
74 derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \
75 free(error); \
76 return -1; \
77 }
78DYNLINK_FUNCTIONS
79#undef DYNLINK_FUNC
Jesse Hall6699b682012-04-18 10:28:46 -070080
David 'Digit' Turnercb88e792011-08-26 01:35:14 +020081 return 0;
82}
83
84int
85android_initOpenglesEmulation(void)
86{
87 char* error = NULL;
88
89 if (rendererLib != NULL)
90 return 0;
91
92 D("Initializing hardware OpenGLES emulation support");
93
94 rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error);
95 if (rendererLib == NULL) {
96 derror("Could not load OpenGLES emulation library: %s", error);
97 return -1;
98 }
99
100#ifndef CONFIG_STANDALONE_UI
101 android_init_opengles_pipes();
102#endif
103
104
105 /* Resolve the functions */
106 if (initOpenglesEmulationFuncs(rendererLib) < 0) {
107 derror("OpenGLES emulation library mismatch. Be sure to use the correct version!");
108 goto BAD_EXIT;
109 }
110
111 if (!initLibrary()) {
112 derror("OpenGLES initialization failed!");
113 goto BAD_EXIT;
114 }
115
David Turner7b56a4a2011-09-12 18:21:58 +0200116 if (android_gles_fast_pipes) {
117#ifdef _WIN32
118 /* XXX: NEED Win32 pipe implementation */
119 setStreamMode(STREAM_MODE_TCP);
120#else
Jesse Hall6699b682012-04-18 10:28:46 -0700121 setStreamMode(STREAM_MODE_UNIX);
David Turner7b56a4a2011-09-12 18:21:58 +0200122#endif
123 } else {
Jesse Hall6699b682012-04-18 10:28:46 -0700124 setStreamMode(STREAM_MODE_TCP);
David Turner7b56a4a2011-09-12 18:21:58 +0200125 }
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200126 return 0;
127
128BAD_EXIT:
129 derror("OpenGLES emulation library could not be initialized!");
130 adynamicLibrary_close(rendererLib);
131 rendererLib = NULL;
132 return -1;
133}
134
135int
Jesse Hall07ca7c22012-04-25 22:05:07 -0700136android_startOpenglesRenderer(int width, int height, OnPostFunc onPost, void* onPostContext)
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200137{
138 if (!rendererLib) {
139 D("Can't start OpenGLES renderer without support libraries");
140 return -1;
141 }
142
Jesse Hall6699b682012-04-18 10:28:46 -0700143 if (!initOpenGLRenderer(width, height, ANDROID_OPENGLES_BASE_PORT, onPost, onPostContext)) {
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200144 D("Can't start OpenGLES renderer?");
145 return -1;
146 }
147 return 0;
148}
149
150void
151android_stopOpenglesRenderer(void)
152{
153 if (rendererLib) {
154 stopOpenGLRenderer();
155 }
156}
157
158int
159android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation)
160{
161 if (rendererLib) {
Jesse Hall6699b682012-04-18 10:28:46 -0700162 int success = createOpenGLSubwindow((FBNativeWindowType)window, x, y, width, height, rotation);
163 return success ? 0 : -1;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200164 } else {
165 return -1;
166 }
167}
168
169int
170android_hideOpenglesWindow(void)
171{
172 if (rendererLib) {
Jesse Hall6699b682012-04-18 10:28:46 -0700173 int success = destroyOpenGLSubwindow();
174 return success ? 0 : -1;
David 'Digit' Turnercb88e792011-08-26 01:35:14 +0200175 } 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}