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