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,int * glesMajorVersion_out,int * glesMinorVersion_out)131 android_startOpenglesRenderer(int width, int height, bool guestPhoneApi, int guestApiLevel,
132 const QAndroidVmOperations *vm_operations,
133 const QAndroidEmulatorWindowAgent *window_agent,
134 const QAndroidMultiDisplayAgent *multi_display_agent,
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 android_opengl_logger_write("%s: gpu info", __func__);
150 android_opengl_logger_write("%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 emugl_logger_struct logfuncs;
164 logfuncs.coarse = android_opengl_logger_write;
165 logfuncs.fine = android_opengl_cxt_logger_write;
166 sRenderLib->setLogger(logfuncs);
167 sRenderLib->setGLObjectCounter(android::base::GLObjectCounter::get());
168 emugl_dma_ops dma_ops;
169 dma_ops.get_host_addr = android_goldfish_dma_ops.get_host_addr;
170 dma_ops.unlock = android_goldfish_dma_ops.unlock;
171 sRenderLib->setDmaOps(dma_ops);
172 sRenderLib->setVmOps(*vm_operations);
173 sRenderLib->setAddressSpaceDeviceControlOps(get_address_space_device_control_ops());
174 sRenderLib->setWindowOps(*window_agent, *multi_display_agent);
175 // sRenderLib->setUsageTracker(android::base::CpuUsage::get(),
176 // android::base::MemoryTracker::get());
177
178 sRenderer = sRenderLib->initRenderer(width, height, sRendererUsesSubWindow, sEgl2egl);
179 android_setOpenglesRenderer(&sRenderer);
180
181 // android::snapshot::Snapshotter::get().addOperationCallback(
182 // [](android::snapshot::Snapshotter::Operation op,
183 // android::snapshot::Snapshotter::Stage stage) {
184 // sRenderer->snapshotOperationCallback(op, stage);
185 // });
186
187 android::emulation::registerOnLastRefCallback(
188 sRenderLib->getOnLastColorBufferRef());
189
190 ConsumerInterface iface = {
191 // create
192 [](struct asg_context context,
193 android::base::Stream* loadStream, ConsumerCallbacks callbacks,
194 uint32_t contextId, uint32_t capsetId,
195 std::optional<std::string> nameOpt) {
196 return sRenderer->addressSpaceGraphicsConsumerCreate(
197 context, loadStream, callbacks, contextId, capsetId, std::move(nameOpt));
198 },
199 // destroy
200 [](void* consumer) {
201 sRenderer->addressSpaceGraphicsConsumerDestroy(consumer);
202 },
203 // pre save
204 [](void* consumer) {
205 sRenderer->addressSpaceGraphicsConsumerPreSave(consumer);
206 },
207 // global presave
208 []() {
209 sRenderer->pauseAllPreSave();
210 },
211 // save
212 [](void* consumer, android::base::Stream* stream) {
213 sRenderer->addressSpaceGraphicsConsumerSave(consumer, stream);
214 },
215 // global postsave
216 []() {
217 sRenderer->resumeAll();
218 },
219 // postSave
220 [](void* consumer) {
221 sRenderer->addressSpaceGraphicsConsumerPostSave(consumer);
222 },
223 // postLoad
224 [](void* consumer) {
225 sRenderer->addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(consumer);
226 },
227 // global preload
228 []() {
229 // This wants to address that when using asg, pipe wants to clean
230 // up all render threads and wait for gl objects, but framebuffer
231 // notices that there is a render thread info that is still not
232 // cleaned up because these render threads come from asg.
233 android::opengl::forEachProcessPipeIdRunAndErase([](uint64_t id) {
234 android_cleanupProcGLObjects(id);
235 });
236 android_waitForOpenglesProcessCleanup();
237 },
238 };
239 AddressSpaceGraphicsContext::setConsumer(iface);
240
241 if (!sRenderer) {
242 D("Can't start OpenGLES renderer?");
243 return -1;
244 }
245
246 // after initRenderer is a success, the maximum GLES API is calculated depending
247 // on feature control and host GPU support. Set the obtained GLES version here.
248 if (glesMajorVersion_out && glesMinorVersion_out)
249 sRenderLib->getGlesVersion(glesMajorVersion_out, glesMinorVersion_out);
250 return 0;
251 }
252
253 bool
android_asyncReadbackSupported()254 android_asyncReadbackSupported() {
255 if (sRenderer) {
256 return sRenderer->asyncReadbackSupported();
257 } else {
258 D("tried to query async readback support "
259 "before renderer initialized. Likely guest rendering");
260 return false;
261 }
262 }
263
264 void
android_setPostCallback(OnPostFunc onPost,void * onPostContext,bool useBgraReadback,uint32_t displayId)265 android_setPostCallback(OnPostFunc onPost, void* onPostContext, bool useBgraReadback, uint32_t displayId)
266 {
267 if (sRenderer) {
268 sRenderer->setPostCallback(onPost, onPostContext, useBgraReadback, displayId);
269 }
270 }
271
android_getReadPixelsFunc()272 ReadPixelsFunc android_getReadPixelsFunc() {
273 if (sRenderer) {
274 return sRenderer->getReadPixelsCallback();
275 } else {
276 return nullptr;
277 }
278 }
279
android_getFlushReadPixelPipeline()280 FlushReadPixelPipeline android_getFlushReadPixelPipeline() {
281 if (sRenderer) {
282 return sRenderer->getFlushReadPixelPipeline();
283 } else {
284 return nullptr;
285 }
286 }
287
288
strdupBaseString(const char * src)289 static char* strdupBaseString(const char* src) {
290 const char* begin = strchr(src, '(');
291 if (!begin) {
292 return strdup(src);
293 }
294
295 const char* end = strrchr(begin + 1, ')');
296 if (!end) {
297 return strdup(src);
298 }
299
300 // src is of the form:
301 // "foo (barzzzzzzzzzz)"
302 // ^ ^
303 // (b+1) e
304 // = 5 18
305 int len;
306 begin += 1;
307 len = end - begin;
308
309 char* result;
310 result = (char*)malloc(len + 1);
311 memcpy(result, begin, len);
312 result[len] = '\0';
313 return result;
314 }
315
android_getOpenglesHardwareStrings(char ** vendor,char ** renderer,char ** version)316 void android_getOpenglesHardwareStrings(char** vendor,
317 char** renderer,
318 char** version) {
319 assert(vendor != NULL && renderer != NULL && version != NULL);
320 assert(*vendor == NULL && *renderer == NULL && *version == NULL);
321 if (!sRenderer) {
322 D("Can't get OpenGL ES hardware strings when renderer not started");
323 return;
324 }
325
326 const gfxstream::Renderer::HardwareStrings strings = sRenderer->getHardwareStrings();
327 D("OpenGL Vendor=[%s]", strings.vendor.c_str());
328 D("OpenGL Renderer=[%s]", strings.renderer.c_str());
329 D("OpenGL Version=[%s]", strings.version.c_str());
330
331 /* Special case for the default ES to GL translators: extract the strings
332 * of the underlying OpenGL implementation. */
333 if (strncmp(strings.vendor.c_str(), "Google", 6) == 0 &&
334 strncmp(strings.renderer.c_str(), "Android Emulator OpenGL ES Translator", 37) == 0) {
335 *vendor = strdupBaseString(strings.vendor.c_str());
336 *renderer = strdupBaseString(strings.renderer.c_str());
337 *version = strdupBaseString(strings.version.c_str());
338 } else {
339 *vendor = strdup(strings.vendor.c_str());
340 *renderer = strdup(strings.renderer.c_str());
341 *version = strdup(strings.version.c_str());
342 }
343 }
344
android_getOpenglesVersion(int * maj,int * min)345 void android_getOpenglesVersion(int* maj, int* min) {
346 sRenderLib->getGlesVersion(maj, min);
347 fprintf(stderr, "%s: maj min %d %d\n", __func__, *maj, *min);
348 }
349
350 void
android_stopOpenglesRenderer(bool wait)351 android_stopOpenglesRenderer(bool wait)
352 {
353 if (sRenderer) {
354 sRenderer->stop(wait);
355 if (wait) {
356 sRenderer.reset();
357 android_stop_opengl_logger();
358 }
359 }
360 }
361
362 void
android_finishOpenglesRenderer()363 android_finishOpenglesRenderer()
364 {
365 if (sRenderer) {
366 sRenderer->finish();
367 }
368 }
369
370 static gfxstream::RenderOpt sOpt;
371 static int sWidth, sHeight;
372 static int sNewWidth, sNewHeight;
373
android_showOpenglesWindow(void * window,int wx,int wy,int ww,int wh,int fbw,int fbh,float dpr,float rotation,bool deleteExisting,bool hideWindow)374 int android_showOpenglesWindow(void* window,
375 int wx,
376 int wy,
377 int ww,
378 int wh,
379 int fbw,
380 int fbh,
381 float dpr,
382 float rotation,
383 bool deleteExisting,
384 bool hideWindow) {
385 if (!sRenderer) {
386 return -1;
387 }
388 FBNativeWindowType win = (FBNativeWindowType)(uintptr_t)window;
389 bool success = sRenderer->showOpenGLSubwindow(win, wx, wy, ww, wh, fbw, fbh,
390 dpr, rotation, deleteExisting,
391 hideWindow);
392 sNewWidth = ww * dpr;
393 sNewHeight = wh * dpr;
394 return success ? 0 : -1;
395 }
396
397 void
android_setOpenglesTranslation(float px,float py)398 android_setOpenglesTranslation(float px, float py)
399 {
400 if (sRenderer) {
401 sRenderer->setOpenGLDisplayTranslation(px, py);
402 }
403 }
404
405 void
android_setOpenglesScreenMask(int width,int height,const unsigned char * rgbaData)406 android_setOpenglesScreenMask(int width, int height, const unsigned char* rgbaData)
407 {
408 if (sRenderer) {
409 sRenderer->setScreenMask(width, height, rgbaData);
410 }
411 }
412
413 int
android_hideOpenglesWindow(void)414 android_hideOpenglesWindow(void)
415 {
416 if (!sRenderer) {
417 return -1;
418 }
419 bool success = sRenderer->destroyOpenGLSubwindow();
420 return success ? 0 : -1;
421 }
422
423 void
android_redrawOpenglesWindow(void)424 android_redrawOpenglesWindow(void)
425 {
426 if (sRenderer) {
427 sRenderer->repaintOpenGLDisplay();
428 }
429 }
430
431 bool
android_hasGuestPostedAFrame(void)432 android_hasGuestPostedAFrame(void)
433 {
434 if (sRenderer) {
435 return sRenderer->hasGuestPostedAFrame();
436 }
437 return false;
438 }
439
440 void
android_resetGuestPostedAFrame(void)441 android_resetGuestPostedAFrame(void)
442 {
443 if (sRenderer) {
444 sRenderer->resetGuestPostedAFrame();
445 }
446 }
447
448 static ScreenshotFunc sScreenshotFunc = nullptr;
449
android_registerScreenshotFunc(ScreenshotFunc f)450 void android_registerScreenshotFunc(ScreenshotFunc f)
451 {
452 sScreenshotFunc = f;
453 }
454
android_screenShot(const char * dirname,uint32_t displayId)455 bool android_screenShot(const char* dirname, uint32_t displayId)
456 {
457 if (sScreenshotFunc) {
458 return sScreenshotFunc(dirname, displayId);
459 }
460 return false;
461 }
462
android_getOpenglesRenderer()463 const gfxstream::RendererPtr& android_getOpenglesRenderer() { return sRenderer; }
464
android_setOpenglesRenderer(gfxstream::RendererPtr * renderer)465 void android_setOpenglesRenderer(gfxstream::RendererPtr* renderer) {
466 sRenderer = *renderer;
467 }
468
android_onGuestGraphicsProcessCreate(uint64_t puid)469 void android_onGuestGraphicsProcessCreate(uint64_t puid) {
470 if (sRenderer) {
471 sRenderer->onGuestGraphicsProcessCreate(puid);
472 }
473 }
474
android_cleanupProcGLObjects(uint64_t puid)475 void android_cleanupProcGLObjects(uint64_t puid) {
476 if (sRenderer) {
477 sRenderer->cleanupProcGLObjects(puid);
478 }
479 }
480
android_cleanupProcGLObjectsAndWaitFinished(uint64_t puid)481 void android_cleanupProcGLObjectsAndWaitFinished(uint64_t puid) {
482 if (sRenderer) {
483 sRenderer->cleanupProcGLObjects(puid);
484 }
485 }
486
android_waitForOpenglesProcessCleanup()487 void android_waitForOpenglesProcessCleanup() {
488 if (sRenderer) {
489 sRenderer->waitForProcessCleanup();
490 }
491 }
492
android_getVirtioGpuOps()493 struct AndroidVirtioGpuOps* android_getVirtioGpuOps() {
494 if (sRenderer) {
495 return sRenderer->getVirtioGpuOps();
496 }
497 return nullptr;
498 }
499
android_getEGLDispatch()500 const void* android_getEGLDispatch() {
501 if (sRenderer) {
502 return sRenderer->getEglDispatch();
503 }
504 return nullptr;
505 }
506
android_getGLESv2Dispatch()507 const void* android_getGLESv2Dispatch() {
508 if (sRenderer) {
509 return sRenderer->getGles2Dispatch();
510 }
511 return nullptr;
512 }
513
android_setVsyncHz(int vsyncHz)514 void android_setVsyncHz(int vsyncHz) {
515 if (sRenderer) {
516 sRenderer->setVsyncHz(vsyncHz);
517 }
518 }
519
android_setOpenglesDisplayConfigs(int configId,int w,int h,int dpiX,int dpiY)520 void android_setOpenglesDisplayConfigs(int configId, int w, int h, int dpiX,
521 int dpiY) {
522 if (sRenderer) {
523 sRenderer->setDisplayConfigs(configId, w, h, dpiX, dpiY);
524 }
525 }
526
android_setOpenglesDisplayActiveConfig(int configId)527 void android_setOpenglesDisplayActiveConfig(int configId) {
528 if (sRenderer) {
529 sRenderer->setDisplayActiveConfig(configId);
530 }
531 }
532