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