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