diff options
| author | Lingfeng Yang <lfy@google.com> | 2020-06-05 15:07:42 +0000 |
|---|---|---|
| committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-06-05 15:07:42 +0000 |
| commit | a9b9597664feb120c8c06fe00c97c58ea684b46b (patch) | |
| tree | 835e2a01639ddf090e4f9ab4016a61ea02b86b89 | |
| parent | c16dbd574d012437448b62e09f5e7bf14ba7ffb5 (diff) | |
| parent | 2f818f89d927ac0944c8ff78b31d1d2fb8d52c1d (diff) | |
| download | device_generic_goldfish-opengl-a9b9597664feb120c8c06fe00c97c58ea684b46b.tar.gz device_generic_goldfish-opengl-a9b9597664feb120c8c06fe00c97c58ea684b46b.tar.bz2 device_generic_goldfish-opengl-a9b9597664feb120c8c06fe00c97c58ea684b46b.zip | |
support EGL_ANDROID_native_fence_sync via virtio-gpu am: f9fc6ad22e am: 2f818f89d9
Original change: https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/1318677
Change-Id: I7d1020740d6f54fd1b393a695b0f4d5a41f50fb5
| -rw-r--r-- | system/OpenglSystemCommon/EmulatorFeatureInfo.h | 7 | ||||
| -rw-r--r-- | system/OpenglSystemCommon/HostConnection.cpp | 45 | ||||
| -rw-r--r-- | system/OpenglSystemCommon/HostConnection.h | 10 | ||||
| -rw-r--r-- | system/OpenglSystemCommon/VirtioGpuPipeStream.cpp | 11 | ||||
| -rw-r--r-- | system/OpenglSystemCommon/VirtioGpuPipeStream.h | 1 | ||||
| -rw-r--r-- | system/egl/Android.mk | 7 | ||||
| -rw-r--r-- | system/egl/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | system/egl/egl.cpp | 160 | ||||
| -rw-r--r-- | system/egl/eglDisplay.cpp | 4 |
9 files changed, 222 insertions, 25 deletions
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h index 626048fd..f1505fea 100644 --- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h +++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h @@ -105,6 +105,9 @@ static const char kHasSharedSlotsHostMemoryAllocator[] = "ANDROID_EMU_has_shared // Vulkan free memory sync static const char kVulkanFreeMemorySync[] = "ANDROID_EMU_vulkan_free_memory_sync"; +// virtio-gpu syncfd support +static const char kVirtioGpuNativeSync[] = "ANDROID_EMU_virtio_gpu_native_sync"; + // Struct describing available emulator features struct EmulatorFeatureInfo { @@ -123,7 +126,8 @@ struct EmulatorFeatureInfo { hasAsyncUnmapBuffer (false), hasVirtioGpuNext (false), hasSharedSlotsHostMemoryAllocator(false), - hasVulkanFreeMemorySync(false) + hasVulkanFreeMemorySync(false), + hasVirtioGpuNativeSync(false) { } SyncImpl syncImpl; @@ -141,6 +145,7 @@ struct EmulatorFeatureInfo { bool hasVirtioGpuNext; bool hasSharedSlotsHostMemoryAllocator; bool hasVulkanFreeMemorySync; + bool hasVirtioGpuNativeSync; }; enum HostConnectionType { diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp index b9c97c93..7a888d0c 100644 --- a/system/OpenglSystemCommon/HostConnection.cpp +++ b/system/OpenglSystemCommon/HostConnection.cpp @@ -354,7 +354,9 @@ HostConnection::HostConnection() : m_checksumHelper(), m_glExtensions(), m_grallocOnly(true), - m_noHostError(false) { } + m_noHostError(false), + m_rendernodeFd(-1), + m_rendernodeFdOwned(false) { } HostConnection::~HostConnection() { @@ -370,6 +372,10 @@ HostConnection::~HostConnection() delete m_glEnc; delete m_gl2Enc; delete m_rcEnc; + + if (m_rendernodeFdOwned) { + close(m_rendernodeFd); + } } // static @@ -459,6 +465,8 @@ HostConnection* HostConnection::connect(HostConnection* con) { con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU; con->m_grallocType = GRALLOC_TYPE_MINIGBM; con->m_stream = stream; + con->m_rendernodeFdOwned = false; + con->m_rendernodeFdOwned = stream->getRendernodeFd(); MinigbmGralloc* m = new MinigbmGralloc; m->setFd(stream->getRendernodeFd()); con->m_grallocHelper = m; @@ -481,6 +489,8 @@ HostConnection* HostConnection::connect(HostConnection* con) { con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU_PIPE; con->m_grallocType = getGrallocTypeFromProperty(); con->m_stream = stream; + con->m_rendernodeFdOwned = false; + con->m_rendernodeFdOwned = stream->getRendernodeFd(); switch (con->m_grallocType) { case GRALLOC_TYPE_RANCHU: con->m_grallocHelper = &m_goldfishGralloc; @@ -615,6 +625,7 @@ ExtendedRCEncoderContext *HostConnection::rcEncoder() queryAndSetVirtioGpuNext(m_rcEnc); queryHasSharedSlotsHostMemoryAllocator(m_rcEnc); queryAndSetVulkanFreeMemorySync(m_rcEnc); + queryAndSetVirtioGpuNativeSync(m_rcEnc); if (m_processPipe) { m_processPipe->processPipeInit(m_connectionType, m_rcEnc); } @@ -622,6 +633,30 @@ ExtendedRCEncoderContext *HostConnection::rcEncoder() return m_rcEnc; } +int HostConnection::getOrCreateRendernodeFd() { + if (m_rendernodeFd >= 0) return m_rendernodeFd; +#ifdef __Fuchsia__ + return -1; +#else +#ifdef VIRTIO_GPU + m_rendernodeFd = VirtioGpuPipeStream::openRendernode(); + if (m_rendernodeFd < 0) { + ALOGE("%s: failed to create secondary " + "rendernode for host connection. " + "error: %s (%d)\n", __FUNCTION__, + strerror(errno), errno); + return -1; + } + + // Remember to close it on exit + m_rendernodeFdOwned = true; + return m_rendernodeFd; +#else + return -1; +#endif +#endif +} + gl_client_context_t *HostConnection::s_getGLContext() { EGLThreadInfo *ti = getEGLThreadInfo(); @@ -832,3 +867,11 @@ void HostConnection::queryAndSetVulkanFreeMemorySync(ExtendedRCEncoderContext *r rcEnc->featureInfo()->hasVulkanFreeMemorySync = true; } } + +void HostConnection::queryAndSetVirtioGpuNativeSync(ExtendedRCEncoderContext* rcEnc) { + std::string glExtensions = queryGLExtensions(rcEnc); + if (glExtensions.find(kVirtioGpuNativeSync) != std::string::npos) { + rcEnc->featureInfo()->hasVirtioGpuNativeSync = true; + } +} + diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h index 02c86815..6acefee3 100644 --- a/system/OpenglSystemCommon/HostConnection.h +++ b/system/OpenglSystemCommon/HostConnection.h @@ -55,6 +55,7 @@ public: bool hasNativeSync() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; } bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; } bool hasNativeSyncV4() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V4; } + bool hasVirtioGpuNativeSync() const { return m_featureInfo.hasVirtioGpuNativeSync; } bool hasHostCompositionV1() const { return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; } bool hasHostCompositionV2() const { @@ -152,6 +153,12 @@ public: GL2Encoder *gl2Encoder(); goldfish_vk::VkEncoder *vkEncoder(); ExtendedRCEncoderContext *rcEncoder(); + + // Returns rendernode fd, in case the stream is virtio-gpu based. + // Otherwise, attempts to create a rendernode fd assuming + // virtio-gpu is available. + int getOrCreateRendernodeFd(); + ChecksumCalculator *checksumHelper() { return &m_checksumHelper; } Gralloc *grallocHelper() { return m_grallocHelper; } @@ -206,6 +213,7 @@ private: void queryAndSetVirtioGpuNext(ExtendedRCEncoderContext *rcEnc); void queryHasSharedSlotsHostMemoryAllocator(ExtendedRCEncoderContext *rcEnc); void queryAndSetVulkanFreeMemorySync(ExtendedRCEncoderContext *rcEnc); + void queryAndSetVirtioGpuNativeSync(ExtendedRCEncoderContext *rcEnc); private: HostConnectionType m_connectionType; @@ -226,6 +234,8 @@ private: #else mutable android::Mutex m_lock; #endif + int m_rendernodeFd; + bool m_rendernodeFdOwned; }; #endif diff --git a/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp b/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp index d3618f39..238d5559 100644 --- a/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp +++ b/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp @@ -74,7 +74,7 @@ VirtioGpuPipeStream::~VirtioGpuPipeStream() int VirtioGpuPipeStream::connect(const char* serviceName) { if (m_fd < 0) { - m_fd = drmOpenRender(RENDERNODE_MINOR); + m_fd = VirtioGpuPipeStream::openRendernode(); if (m_fd < 0) { ERR("%s: failed with fd %d (%s)", __func__, m_fd, strerror(errno)); return -1; @@ -154,6 +154,15 @@ int VirtioGpuPipeStream::connect(const char* serviceName) return 0; } +int VirtioGpuPipeStream::openRendernode() { + int fd = drmOpenRender(RENDERNODE_MINOR); + if (fd < 0) { + ERR("%s: failed with fd %d (%s)", __func__, fd, strerror(errno)); + return -1; + } + return fd; +} + uint64_t VirtioGpuPipeStream::initProcessPipe() { connect("pipe:GLProcessPipe"); int32_t confirmInt = 100; diff --git a/system/OpenglSystemCommon/VirtioGpuPipeStream.h b/system/OpenglSystemCommon/VirtioGpuPipeStream.h index 3f3c537f..91c76fc6 100644 --- a/system/OpenglSystemCommon/VirtioGpuPipeStream.h +++ b/system/OpenglSystemCommon/VirtioGpuPipeStream.h @@ -33,6 +33,7 @@ public: explicit VirtioGpuPipeStream(size_t bufsize = 10000); ~VirtioGpuPipeStream(); int connect(const char* serviceName = 0); + static int openRendernode(); uint64_t initProcessPipe(); virtual void *allocBuffer(size_t minSize); diff --git a/system/egl/Android.mk b/system/egl/Android.mk index 6e239b2a..a5e1c1fd 100644 --- a/system/egl/Android.mk +++ b/system/egl/Android.mk @@ -23,7 +23,12 @@ LOCAL_SRC_FILES := \ ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST)) LOCAL_SHARED_LIBRARIES += libdl -endif +ifeq (true,$(BUILD_EMULATOR_VULKAN)) +LOCAL_CFLAGS += -DVIRTIO_GPU +LOCAL_C_INCLUDES += external/libdrm +LOCAL_SHARED_LIBRARIES += libdrm +endif # BUILD_EMULATOR_VULKAN +endif # GOLDFISH_OPENGL_BUILD_FOR_HOST ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST)) ifdef IS_AT_LEAST_OPM1 diff --git a/system/egl/CMakeLists.txt b/system/egl/CMakeLists.txt index 08db0c82..301ef627 100644 --- a/system/egl/CMakeLists.txt +++ b/system/egl/CMakeLists.txt @@ -1,7 +1,7 @@ # This is an autogenerated file! Do not edit! # instead run make from .../device/generic/goldfish-opengl # which will re-generate this file. -android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/egl/Android.mk" "597fba46fce0876a62ef3c0bc8f3a0264503214b62b0b0da092ee90fe60f09e1") +android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/egl/Android.mk" "729a65bbc7934fa79a239b55b801e4ebaa44d02c2deeab7ab43e42196376c7c7") set(EGL_emulation_src eglDisplay.cpp egl.cpp ClientAPIExts.cpp) android_add_library(TARGET EGL_emulation SHARED LICENSE Apache-2.0 SRC eglDisplay.cpp egl.cpp ClientAPIExts.cpp) target_include_directories(EGL_emulation PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/gralloc_cb/include ${GOLDFISH_DEVICE_ROOT}/shared/GoldfishAddressSpace/include ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include-types ${GOLDFISH_DEVICE_ROOT}/shared/qemupipe/include ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest) diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp index 834207b6..fbd2405f 100644 --- a/system/egl/egl.cpp +++ b/system/egl/egl.cpp @@ -43,6 +43,12 @@ #include <GLES3/gl31.h> +#ifdef VIRTIO_GPU +#include <drm/virtgpu_drm.h> +#include <xf86drm.h> +#include <poll.h> +#endif // VIRTIO_GPU + #if PLATFORM_SDK_VERSION < 18 #define override #endif @@ -494,6 +500,101 @@ static uint64_t createNativeSync(EGLenum type, return sync_handle; } +// our cmd +#define VIRTIO_GPU_NATIVE_SYNC_CREATE_EXPORT_FD 0x9000 +#define VIRTIO_GPU_NATIVE_SYNC_CREATE_IMPORT_FD 0x9001 + +// createNativeSync_virtioGpu() +// creates an OpenGL sync object on the host +// using rcCreateSyncKHR. +// If necessary, a native fence FD will be exported or imported. +// Returns a handle to the host-side FenceSync object. +static uint64_t createNativeSync_virtioGpu( + EGLenum type, + const EGLint* attrib_list, + int num_actual_attribs, + bool destroy_when_signaled, + int fd_in, + int* fd_out) { +#ifndef VIRTIO_GPU + ALOGE("%s: Error: called with no virtio-gpu support built in\n", __func__); + return 0; +#else + DEFINE_HOST_CONNECTION; + + uint64_t sync_handle; + uint64_t thread_handle; + + EGLint* actual_attribs = + (EGLint*)(num_actual_attribs == 0 ? NULL : attrib_list); + + // Create a normal sync obj + rcEnc->rcCreateSyncKHR(rcEnc, type, + actual_attribs, + num_actual_attribs * sizeof(EGLint), + destroy_when_signaled, + &sync_handle, + &thread_handle); + + // Import fence fd; dup and close + if (type == EGL_SYNC_NATIVE_FENCE_ANDROID && fd_in >= 0) { + int importedFd = dup(fd_in); + + if (importedFd < 0) { + ALOGE("%s: error: failed to dup imported fd. original: %d errno %d\n", + __func__, fd_in, errno); + } + + *fd_out = importedFd; + + if (close(fd_in)) { + ALOGE("%s: error: failed to close imported fd. original: %d errno %d\n", + __func__, fd_in, errno); + } + + } else if (type == EGL_SYNC_NATIVE_FENCE_ANDROID && fd_in < 0) { + // Export fence fd + + uint32_t sync_handle_lo = (uint32_t)sync_handle; + uint32_t sync_handle_hi = (uint32_t)(sync_handle >> 32); + + uint32_t cmdDwords[3] = { + VIRTIO_GPU_NATIVE_SYNC_CREATE_EXPORT_FD, + sync_handle_lo, + sync_handle_hi, + }; + + drm_virtgpu_execbuffer createSyncExport = { + .flags = VIRTGPU_EXECBUF_FENCE_FD_OUT, + .size = 3 * sizeof(uint32_t), + .command = (uint64_t)(cmdDwords), + .bo_handles = 0, + .num_bo_handles = 0, + .fence_fd = -1, + }; + + int queue_work_err = + drmIoctl( + hostCon->getOrCreateRendernodeFd(), + DRM_IOCTL_VIRTGPU_EXECBUFFER, &createSyncExport); + + if (queue_work_err) { + ERR("%s: failed with %d executing command buffer (%s)", __func__, + queue_work_err, strerror(errno)); + return 0; + } + + *fd_out = createSyncExport.fence_fd; + + DPRINT("virtio-gpu: got native fence fd=%d queue_work_err=%d", + *fd_out, queue_work_err); + + } + + return sync_handle; +#endif +} + // createGoldfishOpenGLNativeSync() is for creating host-only sync objects // that are needed by only this goldfish opengl driver, // such as in swapBuffers(). @@ -544,7 +645,16 @@ EGLBoolean egl_window_surface_t::swapBuffers() eglWaitClient(); nativeWindow->queueBuffer(nativeWindow, buffer); #else - if (rcEnc->hasNativeSync()) { + if (rcEnc->hasVirtioGpuNativeSync()) { + rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface); + createNativeSync_virtioGpu(EGL_SYNC_NATIVE_FENCE_ANDROID, + NULL /* empty attrib list */, + 0 /* 0 attrib count */, + true /* destroy when signaled. this is host-only + and there will only be one waiter */, + -1 /* we want a new fd */, + &presentFenceFd); + } else if (rcEnc->hasNativeSync()) { rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface); createGoldfishOpenGLNativeSync(&presentFenceFd); } else { @@ -2097,7 +2207,8 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, if ((type != EGL_SYNC_FENCE_KHR && type != EGL_SYNC_NATIVE_FENCE_ANDROID) || (type != EGL_SYNC_FENCE_KHR && - !rcEnc->hasNativeSync())) { + !rcEnc->hasNativeSync() && + !rcEnc->hasVirtioGpuNativeSync())) { setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); } @@ -2150,14 +2261,23 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, uint64_t sync_handle = 0; int newFenceFd = -1; - if (rcEnc->hasNativeSync()) { + if (rcEnc->hasVirtioGpuNativeSync()) { sync_handle = - createNativeSync(type, attrib_list, num_actual_attribs, - false /* don't destroy when signaled on the host; - let the guest clean this up, - because the guest called eglCreateSyncKHR. */, - inputFenceFd, - &newFenceFd); + createNativeSync_virtioGpu( + type, attrib_list, num_actual_attribs, + false /* don't destroy when signaled on the host; + let the guest clean this up, + because the guest called eglCreateSyncKHR. */, + inputFenceFd, &newFenceFd); + } else if (rcEnc->hasNativeSync()) { + sync_handle = + createNativeSync( + type, attrib_list, num_actual_attribs, + false /* don't destroy when signaled on the host; + let the guest clean this up, + because the guest called eglCreateSyncKHR. */, + inputFenceFd, + &newFenceFd); } else { // Just trigger a glFinish if the native sync on host @@ -2170,17 +2290,21 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, if (type == EGL_SYNC_NATIVE_FENCE_ANDROID) { syncRes->type = EGL_SYNC_NATIVE_FENCE_ANDROID; - if (inputFenceFd < 0) { + if (rcEnc->hasVirtioGpuNativeSync()) { syncRes->android_native_fence_fd = newFenceFd; } else { - DPRINT("has input fence fd %d", - inputFenceFd); - syncRes->android_native_fence_fd = inputFenceFd; + if (inputFenceFd < 0) { + syncRes->android_native_fence_fd = newFenceFd; + } else { + DPRINT("has input fence fd %d", + inputFenceFd); + syncRes->android_native_fence_fd = inputFenceFd; + } } } else { syncRes->type = EGL_SYNC_FENCE_KHR; syncRes->android_native_fence_fd = -1; - if (!rcEnc->hasNativeSync()) { + if (!rcEnc->hasNativeSync() && !rcEnc->hasVirtioGpuNativeSync()) { syncRes->status = EGL_SIGNALED_KHR; } } @@ -2206,7 +2330,7 @@ EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync) if (sync) { DEFINE_HOST_CONNECTION; - if (rcEnc->hasNativeSync()) { + if (rcEnc->hasVirtioGpuNativeSync() || rcEnc->hasNativeSync()) { rcEnc->rcDestroySyncKHR(rcEnc, sync->handle); } delete sync; @@ -2233,7 +2357,7 @@ EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags, DEFINE_HOST_CONNECTION; EGLint retval; - if (rcEnc->hasNativeSync()) { + if (rcEnc->hasVirtioGpuNativeSync() || rcEnc->hasNativeSync()) { retval = rcEnc->rcClientWaitSyncKHR (rcEnc, sync->handle, flags, timeout); } else { @@ -2272,7 +2396,7 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR eglsync, } else { // ask the host again DEFINE_HOST_CONNECTION; - if (rcEnc->hasNativeSyncV4()) { + if (rcEnc->hasVirtioGpuNativeSync() || rcEnc->hasNativeSyncV4()) { if (rcEnc->rcIsSyncSignaled(rcEnc, sync->handle)) { sync->status = EGL_SIGNALED_KHR; } @@ -2317,7 +2441,7 @@ EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags) { } DEFINE_HOST_CONNECTION; - if (rcEnc->hasNativeSyncV3()) { + if (rcEnc->hasVirtioGpuNativeSync() || rcEnc->hasNativeSyncV3()) { EGLSync_t* sync = (EGLSync_t*)eglsync; rcEnc->rcWaitSyncKHR(rcEnc, sync->handle, flags); } diff --git a/system/egl/eglDisplay.cpp b/system/egl/eglDisplay.cpp index b3f14da6..2508f487 100644 --- a/system/egl/eglDisplay.cpp +++ b/system/egl/eglDisplay.cpp @@ -357,11 +357,11 @@ static char *buildExtensionString() std::string dynamicEGLExtensions; - if (hcon->rcEncoder()->hasNativeSync() && + if ((hcon->rcEncoder()->hasVirtioGpuNativeSync() || hcon->rcEncoder()->hasNativeSync()) && !strstr(initialEGLExts, kDynamicEGLExtNativeSync)) { dynamicEGLExtensions += kDynamicEGLExtNativeSync; - if (hcon->rcEncoder()->hasNativeSyncV3()) { + if (hcon->rcEncoder()->hasVirtioGpuNativeSync() || hcon->rcEncoder()->hasNativeSyncV3()) { dynamicEGLExtensions += kDynamicEGLExtWaitSync; } } |
