• 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 <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