Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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; |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 72 | using gfxstream::gl::EGLDispatch; |
| 73 | using gfxstream::gl::GLESv2Dispatch; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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; |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 90 | static gfxstream::RenderLib* sRenderLib = nullptr; |
| 91 | static gfxstream::RendererPtr sRenderer = nullptr; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 92 | |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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 | } |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 116 | |
| 117 | int android_setOpenglesEmulation(void* renderLib, void* eglDispatch, void* glesv2Dispatch) { |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 118 | sRenderLib = (gfxstream::RenderLib*)renderLib; |
Jason Macnak | e70b8e3 | 2023-01-20 13:59:35 -0800 | [diff] [blame] | 119 | (void)eglDispatch; |
| 120 | (void)glesv2Dispatch; |
| 121 | sEgl2egl = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1"; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 122 | return 0; |
| 123 | } |
| 124 | |
| 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 |
Jason Macnak | 2687212 | 2024-02-23 10:46:09 -0800 | [diff] [blame] | 131 | android_startOpenglesRenderer(int width, int height, |
| 132 | bool guestPhoneApi, int guestApiLevel, |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 133 | const QAndroidVmOperations *vm_operations, |
| 134 | const QAndroidEmulatorWindowAgent *window_agent, |
| 135 | const QAndroidMultiDisplayAgent *multi_display_agent, |
Jason Macnak | 2687212 | 2024-02-23 10:46:09 -0800 | [diff] [blame] | 136 | const void* gfxstreamFeatures, |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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 | |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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 | |
Jason Macnak | 2687212 | 2024-02-23 10:46:09 -0800 | [diff] [blame] | 180 | const auto* features = reinterpret_cast<const gfxstream::host::FeatureSet*>(gfxstreamFeatures); |
| 181 | sRenderer = sRenderLib->initRenderer(width, height, *features, sRendererUsesSubWindow, sEgl2egl); |
Joshua Duong | c256a3c | 2023-05-09 08:14:24 -0700 | [diff] [blame] | 182 | android_setOpenglesRenderer(&sRenderer); |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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 |
| 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 |
| 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 | |
| 275 | ReadPixelsFunc android_getReadPixelsFunc() { |
| 276 | if (sRenderer) { |
| 277 | return sRenderer->getReadPixelsCallback(); |
| 278 | } else { |
| 279 | return nullptr; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | FlushReadPixelPipeline android_getFlushReadPixelPipeline() { |
| 284 | if (sRenderer) { |
| 285 | return sRenderer->getFlushReadPixelPipeline(); |
| 286 | } else { |
| 287 | return nullptr; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | |
| 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 | |
| 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 | |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 329 | const gfxstream::Renderer::HardwareStrings strings = sRenderer->getHardwareStrings(); |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 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 | |
| 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 |
| 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 |
| 366 | android_finishOpenglesRenderer() |
| 367 | { |
| 368 | if (sRenderer) { |
| 369 | sRenderer->finish(); |
| 370 | } |
| 371 | } |
| 372 | |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 373 | static gfxstream::RenderOpt sOpt; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 374 | static int sWidth, sHeight; |
| 375 | static int sNewWidth, sNewHeight; |
| 376 | |
| 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 |
| 401 | android_setOpenglesTranslation(float px, float py) |
| 402 | { |
| 403 | if (sRenderer) { |
| 404 | sRenderer->setOpenGLDisplayTranslation(px, py); |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | void |
| 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 |
| 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 |
| 427 | android_redrawOpenglesWindow(void) |
| 428 | { |
| 429 | if (sRenderer) { |
| 430 | sRenderer->repaintOpenGLDisplay(); |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | bool |
| 435 | android_hasGuestPostedAFrame(void) |
| 436 | { |
| 437 | if (sRenderer) { |
| 438 | return sRenderer->hasGuestPostedAFrame(); |
| 439 | } |
| 440 | return false; |
| 441 | } |
| 442 | |
| 443 | void |
| 444 | android_resetGuestPostedAFrame(void) |
| 445 | { |
| 446 | if (sRenderer) { |
| 447 | sRenderer->resetGuestPostedAFrame(); |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | static ScreenshotFunc sScreenshotFunc = nullptr; |
| 452 | |
| 453 | void android_registerScreenshotFunc(ScreenshotFunc f) |
| 454 | { |
| 455 | sScreenshotFunc = f; |
| 456 | } |
| 457 | |
| 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 | |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 466 | const gfxstream::RendererPtr& android_getOpenglesRenderer() { return sRenderer; } |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 467 | |
Joshua Duong | c256a3c | 2023-05-09 08:14:24 -0700 | [diff] [blame] | 468 | void android_setOpenglesRenderer(gfxstream::RendererPtr* renderer) { |
| 469 | sRenderer = *renderer; |
| 470 | } |
| 471 | |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 472 | void android_onGuestGraphicsProcessCreate(uint64_t puid) { |
| 473 | if (sRenderer) { |
| 474 | sRenderer->onGuestGraphicsProcessCreate(puid); |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | void android_cleanupProcGLObjects(uint64_t puid) { |
| 479 | if (sRenderer) { |
| 480 | sRenderer->cleanupProcGLObjects(puid); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | void android_cleanupProcGLObjectsAndWaitFinished(uint64_t puid) { |
| 485 | if (sRenderer) { |
| 486 | sRenderer->cleanupProcGLObjects(puid); |
| 487 | } |
| 488 | } |
| 489 | |
| 490 | void android_waitForOpenglesProcessCleanup() { |
| 491 | if (sRenderer) { |
| 492 | sRenderer->waitForProcessCleanup(); |
| 493 | } |
| 494 | } |
| 495 | |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 496 | struct AndroidVirtioGpuOps* android_getVirtioGpuOps() { |
| 497 | if (sRenderer) { |
| 498 | return sRenderer->getVirtioGpuOps(); |
| 499 | } |
| 500 | return nullptr; |
| 501 | } |
| 502 | |
| 503 | const void* android_getEGLDispatch() { |
Jason Macnak | e70b8e3 | 2023-01-20 13:59:35 -0800 | [diff] [blame] | 504 | if (sRenderer) { |
| 505 | return sRenderer->getEglDispatch(); |
| 506 | } |
| 507 | return nullptr; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 508 | } |
| 509 | |
| 510 | const void* android_getGLESv2Dispatch() { |
Jason Macnak | e70b8e3 | 2023-01-20 13:59:35 -0800 | [diff] [blame] | 511 | if (sRenderer) { |
| 512 | return sRenderer->getGles2Dispatch(); |
| 513 | } |
| 514 | return nullptr; |
Joshua Duong | 9dfbd85 | 2022-11-14 13:12:59 -0800 | [diff] [blame] | 515 | } |
Lingfeng Yang | 66d9610 | 2021-07-30 16:01:15 -0700 | [diff] [blame] | 516 | |
| 517 | void android_setVsyncHz(int vsyncHz) { |
| 518 | if (sRenderer) { |
| 519 | sRenderer->setVsyncHz(vsyncHz); |
| 520 | } |
| 521 | } |
Huan Song | c3a1aeb | 2021-09-22 08:27:19 -0700 | [diff] [blame] | 522 | |
| 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 | |
| 530 | void android_setOpenglesDisplayActiveConfig(int configId) { |
| 531 | if (sRenderer) { |
| 532 | sRenderer->setDisplayActiveConfig(configId); |
| 533 | } |
| 534 | } |