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