1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "host-common/opengles.h"
16
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 #include <optional>
22
23 #include "aemu/base/GLObjectCounter.h"
24 #include "aemu/base/SharedLibrary.h"
25 #include "host-common/address_space_device.h"
26 #include "host-common/address_space_graphics.h"
27 #include "host-common/address_space_graphics_types.h"
28 #include "host-common/GfxstreamFatalError.h"
29 #include "host-common/logging.h"
30 #include "host-common/opengl/GLProcessPipe.h"
31 #include "host-common/opengl/emugl_config.h"
32 #include "host-common/opengl/logger.h"
33 #include "host-common/opengl/gpuinfo.h"
34
35 using android::base::SharedLibrary;
36 using android::emulation::asg::AddressSpaceGraphicsContext;
37 using android::emulation::asg::ConsumerCallbacks;
38 using android::emulation::asg::ConsumerInterface;
39 using emugl::ABORT_REASON_OTHER;
40 using emugl::FatalError;
41
42 static bool sOpenglLoggerInitialized = false;
43 static bool sRendererUsesSubWindow = false;
44 static bool sEgl2egl = false;
45 static gfxstream::RenderLib* sRenderLib = nullptr;
46 static gfxstream::RendererPtr sRenderer = nullptr;
47
android_prepareOpenglesEmulation()48 int android_prepareOpenglesEmulation() {
49 android_init_opengl_logger();
50
51 bool glFineLogging = (android::base::getEnvironmentVariable("ANDROID_EMUGL_FINE_LOG") == "1") ||
52 (android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1");
53 bool glLogPrinting = android::base::getEnvironmentVariable("ANDROID_EMUGL_LOG_PRINT") == "1";
54
55 AndroidOpenglLoggerFlags loggerFlags =
56 static_cast<AndroidOpenglLoggerFlags>(
57 (glFineLogging ? OPENGL_LOGGER_DO_FINE_LOGGING : 0) |
58 (glLogPrinting ? OPENGL_LOGGER_PRINT_TO_STDOUT : 0));
59
60 android_opengl_logger_set_flags(loggerFlags);
61
62 sOpenglLoggerInitialized = true;
63 sRendererUsesSubWindow = true;
64
65 sEgl2egl = false;
66 if (android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1") {
67 sEgl2egl = true;
68 }
69
70 return 0;
71 }
72
android_setOpenglesEmulation(void * renderLib,void * eglDispatch,void * glesv2Dispatch)73 int android_setOpenglesEmulation(void* renderLib, void* eglDispatch, void* glesv2Dispatch) {
74 sRenderLib = (gfxstream::RenderLib*)renderLib;
75 (void)eglDispatch;
76 (void)glesv2Dispatch;
77 sEgl2egl = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1";
78 return 0;
79 }
80
android_initOpenglesEmulation()81 int android_initOpenglesEmulation() {
82 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
83 << "Not meant to call android_initOpenglesEmulation in the new build.";
84 }
85
86 int
android_startOpenglesRenderer(int width,int height,bool guestPhoneApi,int guestApiLevel,const QAndroidVmOperations * vm_operations,const QAndroidEmulatorWindowAgent * window_agent,const QAndroidMultiDisplayAgent * multi_display_agent,const void * gfxstreamFeatures,int * glesMajorVersion_out,int * glesMinorVersion_out)87 android_startOpenglesRenderer(int width, int height,
88 bool guestPhoneApi, int guestApiLevel,
89 const QAndroidVmOperations *vm_operations,
90 const QAndroidEmulatorWindowAgent *window_agent,
91 const QAndroidMultiDisplayAgent *multi_display_agent,
92 const void* gfxstreamFeatures,
93 int* glesMajorVersion_out,
94 int* glesMinorVersion_out)
95 {
96 if (!sRenderLib) {
97 return -1;
98 }
99
100 if (sRenderer) {
101 return 0;
102 }
103
104 const GpuInfoList& gpuList = globalGpuInfoList();
105 std::string gpuInfoAsString = gpuList.dump();
106 INFO("%s: gpu info", __func__);
107 INFO("%s", gpuInfoAsString.c_str());
108
109 sRenderLib->setRenderer(emuglConfig_get_current_renderer());
110 sRenderLib->setAvdInfo(guestPhoneApi, guestApiLevel);
111 sRenderLib->setSyncDevice(goldfish_sync_create_timeline,
112 goldfish_sync_create_fence,
113 goldfish_sync_timeline_inc,
114 goldfish_sync_destroy_timeline,
115 goldfish_sync_register_trigger_wait,
116 goldfish_sync_device_exists);
117
118 sRenderLib->setLogger(android_opengl_logger_write);
119 sRenderLib->setGLObjectCounter(android::base::GLObjectCounter::get());
120 emugl_dma_ops dma_ops;
121 dma_ops.get_host_addr = android_goldfish_dma_ops.get_host_addr;
122 dma_ops.unlock = android_goldfish_dma_ops.unlock;
123 sRenderLib->setDmaOps(dma_ops);
124 sRenderLib->setVmOps(*vm_operations);
125 sRenderLib->setAddressSpaceDeviceControlOps(get_address_space_device_control_ops());
126 sRenderLib->setWindowOps(*window_agent, *multi_display_agent);
127
128 const auto* features = reinterpret_cast<const gfxstream::host::FeatureSet*>(gfxstreamFeatures);
129 sRenderer = sRenderLib->initRenderer(width, height, *features, sRendererUsesSubWindow, sEgl2egl);
130 android_setOpenglesRenderer(&sRenderer);
131
132 android::emulation::registerOnLastRefCallback(
133 sRenderLib->getOnLastColorBufferRef());
134
135 ConsumerInterface iface = {
136 // create
137 [](struct asg_context context,
138 android::base::Stream* loadStream, ConsumerCallbacks callbacks,
139 uint32_t contextId, uint32_t capsetId,
140 std::optional<std::string> nameOpt) {
141 return sRenderer->addressSpaceGraphicsConsumerCreate(
142 context, loadStream, callbacks, contextId, capsetId, std::move(nameOpt));
143 },
144 // destroy
145 [](void* consumer) {
146 sRenderer->addressSpaceGraphicsConsumerDestroy(consumer);
147 },
148 // pre save
149 [](void* consumer) {
150 sRenderer->addressSpaceGraphicsConsumerPreSave(consumer);
151 },
152 // global presave
153 []() {
154 sRenderer->pauseAllPreSave();
155 },
156 // save
157 [](void* consumer, android::base::Stream* stream) {
158 sRenderer->addressSpaceGraphicsConsumerSave(consumer, stream);
159 },
160 // global postsave
161 []() {
162 sRenderer->resumeAll();
163 },
164 // postSave
165 [](void* consumer) {
166 sRenderer->addressSpaceGraphicsConsumerPostSave(consumer);
167 },
168 // postLoad
169 [](void* consumer) {
170 sRenderer->addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(consumer);
171 },
172 // global preload
173 []() {
174 // This wants to address that when using asg, pipe wants to clean
175 // up all render threads and wait for gl objects, but framebuffer
176 // notices that there is a render thread info that is still not
177 // cleaned up because these render threads come from asg.
178 android::opengl::forEachProcessPipeIdRunAndErase([](uint64_t id) {
179 android_cleanupProcGLObjects(id);
180 });
181 android_waitForOpenglesProcessCleanup();
182 },
183 };
184 AddressSpaceGraphicsContext::setConsumer(iface);
185
186 if (!sRenderer) {
187 ERR("Can't start OpenGLES renderer?");
188 return -1;
189 }
190
191 // after initRenderer is a success, the maximum GLES API is calculated depending
192 // on feature control and host GPU support. Set the obtained GLES version here.
193 if (glesMajorVersion_out && glesMinorVersion_out)
194 sRenderLib->getGlesVersion(glesMajorVersion_out, glesMinorVersion_out);
195 return 0;
196 }
197
198 bool
android_asyncReadbackSupported()199 android_asyncReadbackSupported() {
200 if (sRenderer) {
201 return sRenderer->asyncReadbackSupported();
202 } else {
203 VERBOSE("tried to query async readback support "
204 "before renderer initialized. Likely guest rendering");
205 return false;
206 }
207 }
208
209 void
android_setPostCallback(OnPostFunc onPost,void * onPostContext,bool useBgraReadback,uint32_t displayId)210 android_setPostCallback(OnPostFunc onPost, void* onPostContext, bool useBgraReadback, uint32_t displayId)
211 {
212 if (sRenderer) {
213 sRenderer->setPostCallback(onPost, onPostContext, useBgraReadback, displayId);
214 }
215 }
216
android_getReadPixelsFunc()217 ReadPixelsFunc android_getReadPixelsFunc() {
218 if (sRenderer) {
219 return sRenderer->getReadPixelsCallback();
220 } else {
221 return nullptr;
222 }
223 }
224
android_getFlushReadPixelPipeline()225 FlushReadPixelPipeline android_getFlushReadPixelPipeline() {
226 if (sRenderer) {
227 return sRenderer->getFlushReadPixelPipeline();
228 } else {
229 return nullptr;
230 }
231 }
232
233
strdupBaseString(const char * src)234 static char* strdupBaseString(const char* src) {
235 const char* begin = strchr(src, '(');
236 if (!begin) {
237 return strdup(src);
238 }
239
240 const char* end = strrchr(begin + 1, ')');
241 if (!end) {
242 return strdup(src);
243 }
244
245 // src is of the form:
246 // "foo (barzzzzzzzzzz)"
247 // ^ ^
248 // (b+1) e
249 // = 5 18
250 int len;
251 begin += 1;
252 len = end - begin;
253
254 char* result;
255 result = (char*)malloc(len + 1);
256 memcpy(result, begin, len);
257 result[len] = '\0';
258 return result;
259 }
260
android_getOpenglesHardwareStrings(char ** vendor,char ** renderer,char ** version)261 void android_getOpenglesHardwareStrings(char** vendor,
262 char** renderer,
263 char** version) {
264 assert(vendor != NULL && renderer != NULL && version != NULL);
265 assert(*vendor == NULL && *renderer == NULL && *version == NULL);
266 if (!sRenderer) {
267 ERR("Can't get OpenGL ES hardware strings when renderer not started");
268 return;
269 }
270
271 const gfxstream::Renderer::HardwareStrings strings = sRenderer->getHardwareStrings();
272 INFO("OpenGL Vendor=[%s]", strings.vendor.c_str());
273 INFO("OpenGL Renderer=[%s]", strings.renderer.c_str());
274 INFO("OpenGL Version=[%s]", strings.version.c_str());
275
276 /* Special case for the default ES to GL translators: extract the strings
277 * of the underlying OpenGL implementation. */
278 if (strncmp(strings.vendor.c_str(), "Google", 6) == 0 &&
279 strncmp(strings.renderer.c_str(), "Android Emulator OpenGL ES Translator", 37) == 0) {
280 *vendor = strdupBaseString(strings.vendor.c_str());
281 *renderer = strdupBaseString(strings.renderer.c_str());
282 *version = strdupBaseString(strings.version.c_str());
283 } else {
284 *vendor = strdup(strings.vendor.c_str());
285 *renderer = strdup(strings.renderer.c_str());
286 *version = strdup(strings.version.c_str());
287 }
288 }
289
android_getOpenglesVersion(int * maj,int * min)290 void android_getOpenglesVersion(int* maj, int* min) {
291 sRenderLib->getGlesVersion(maj, min);
292 INFO("OpenGL ES version major:%d minor:%d", *maj, *min);
293 }
294
295 void
android_stopOpenglesRenderer(bool wait)296 android_stopOpenglesRenderer(bool wait)
297 {
298 if (sRenderer) {
299 sRenderer->stop(wait);
300 if (wait) {
301 sRenderer.reset();
302 android_stop_opengl_logger();
303 }
304 }
305 }
306
307 void
android_finishOpenglesRenderer()308 android_finishOpenglesRenderer()
309 {
310 if (sRenderer) {
311 sRenderer->finish();
312 }
313 }
314
315 static int sWidth, sHeight;
316 static int sNewWidth, sNewHeight;
317
android_showOpenglesWindow(void * window,int wx,int wy,int ww,int wh,int fbw,int fbh,float dpr,float rotation,bool deleteExisting,bool hideWindow)318 int android_showOpenglesWindow(void* window,
319 int wx,
320 int wy,
321 int ww,
322 int wh,
323 int fbw,
324 int fbh,
325 float dpr,
326 float rotation,
327 bool deleteExisting,
328 bool hideWindow) {
329 if (!sRenderer) {
330 return -1;
331 }
332 FBNativeWindowType win = (FBNativeWindowType)(uintptr_t)window;
333 bool success = sRenderer->showOpenGLSubwindow(win, wx, wy, ww, wh, fbw, fbh,
334 dpr, rotation, deleteExisting,
335 hideWindow);
336 sNewWidth = ww * dpr;
337 sNewHeight = wh * dpr;
338 return success ? 0 : -1;
339 }
340
341 void
android_setOpenglesTranslation(float px,float py)342 android_setOpenglesTranslation(float px, float py)
343 {
344 if (sRenderer) {
345 sRenderer->setOpenGLDisplayTranslation(px, py);
346 }
347 }
348
349 void
android_setOpenglesScreenMask(int width,int height,const unsigned char * rgbaData)350 android_setOpenglesScreenMask(int width, int height, const unsigned char* rgbaData)
351 {
352 if (sRenderer) {
353 sRenderer->setScreenMask(width, height, rgbaData);
354 }
355 }
356
357 int
android_hideOpenglesWindow(void)358 android_hideOpenglesWindow(void)
359 {
360 if (!sRenderer) {
361 return -1;
362 }
363 bool success = sRenderer->destroyOpenGLSubwindow();
364 return success ? 0 : -1;
365 }
366
367 void
android_redrawOpenglesWindow(void)368 android_redrawOpenglesWindow(void)
369 {
370 if (sRenderer) {
371 sRenderer->repaintOpenGLDisplay();
372 }
373 }
374
375 bool
android_hasGuestPostedAFrame(void)376 android_hasGuestPostedAFrame(void)
377 {
378 if (sRenderer) {
379 return sRenderer->hasGuestPostedAFrame();
380 }
381 return false;
382 }
383
384 void
android_resetGuestPostedAFrame(void)385 android_resetGuestPostedAFrame(void)
386 {
387 if (sRenderer) {
388 sRenderer->resetGuestPostedAFrame();
389 }
390 }
391
392 static ScreenshotFunc sScreenshotFunc = nullptr;
393
android_registerScreenshotFunc(ScreenshotFunc f)394 void android_registerScreenshotFunc(ScreenshotFunc f)
395 {
396 sScreenshotFunc = f;
397 }
398
android_screenShot(const char * dirname,uint32_t displayId)399 bool android_screenShot(const char* dirname, uint32_t displayId)
400 {
401 if (sScreenshotFunc) {
402 return sScreenshotFunc(dirname, displayId);
403 }
404 return false;
405 }
406
android_getOpenglesRenderer()407 const gfxstream::RendererPtr& android_getOpenglesRenderer() { return sRenderer; }
408
android_setOpenglesRenderer(gfxstream::RendererPtr * renderer)409 void android_setOpenglesRenderer(gfxstream::RendererPtr* renderer) {
410 sRenderer = *renderer;
411 }
412
android_onGuestGraphicsProcessCreate(uint64_t puid)413 void android_onGuestGraphicsProcessCreate(uint64_t puid) {
414 if (sRenderer) {
415 sRenderer->onGuestGraphicsProcessCreate(puid);
416 }
417 }
418
android_cleanupProcGLObjects(uint64_t puid)419 void android_cleanupProcGLObjects(uint64_t puid) {
420 if (sRenderer) {
421 sRenderer->cleanupProcGLObjects(puid);
422 }
423 }
424
android_cleanupProcGLObjectsAndWaitFinished(uint64_t puid)425 void android_cleanupProcGLObjectsAndWaitFinished(uint64_t puid) {
426 if (sRenderer) {
427 sRenderer->cleanupProcGLObjects(puid);
428 }
429 }
430
android_waitForOpenglesProcessCleanup()431 void android_waitForOpenglesProcessCleanup() {
432 if (sRenderer) {
433 sRenderer->waitForProcessCleanup();
434 }
435 }
436
android_getVirtioGpuOps()437 struct AndroidVirtioGpuOps* android_getVirtioGpuOps() {
438 if (sRenderer) {
439 return sRenderer->getVirtioGpuOps();
440 }
441 return nullptr;
442 }
443
android_getEGLDispatch()444 const void* android_getEGLDispatch() {
445 if (sRenderer) {
446 return sRenderer->getEglDispatch();
447 }
448 return nullptr;
449 }
450
android_getGLESv2Dispatch()451 const void* android_getGLESv2Dispatch() {
452 if (sRenderer) {
453 return sRenderer->getGles2Dispatch();
454 }
455 return nullptr;
456 }
457
android_setVsyncHz(int vsyncHz)458 void android_setVsyncHz(int vsyncHz) {
459 if (sRenderer) {
460 sRenderer->setVsyncHz(vsyncHz);
461 }
462 }
463
android_setOpenglesDisplayConfigs(int configId,int w,int h,int dpiX,int dpiY)464 void android_setOpenglesDisplayConfigs(int configId, int w, int h, int dpiX,
465 int dpiY) {
466 if (sRenderer) {
467 sRenderer->setDisplayConfigs(configId, w, h, dpiX, dpiY);
468 }
469 }
470
android_setOpenglesDisplayActiveConfig(int configId)471 void android_setOpenglesDisplayActiveConfig(int configId) {
472 if (sRenderer) {
473 sRenderer->setDisplayActiveConfig(configId);
474 }
475 }
476