When glSync is not available on android fake it out with EGL for our tests.
Change-Id: Ie1c98f1927146cce938204c2ea60899887a3bcea
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271746
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp b/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
index af6d110..d2e6ea9 100644
--- a/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
+++ b/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
@@ -69,6 +69,8 @@
void onPlatformSwapBuffers() const override;
GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
+ void setupFenceSync(sk_sp<const GrGLInterface>);
+
PFNEGLCREATEIMAGEKHRPROC fEglCreateImageProc = nullptr;
PFNEGLDESTROYIMAGEKHRPROC fEglDestroyImageProc = nullptr;
@@ -207,6 +209,8 @@
continue;
}
+ this->setupFenceSync(gl);
+
if (!gl->validate()) {
SkDebugf("Failed to validate gl interface.\n");
this->destroyGLContext();
@@ -224,6 +228,126 @@
}
}
+static bool supports_egl_extension(EGLDisplay display, const char* extension) {
+ size_t extensionLength = strlen(extension);
+ const char* extensionsStr = eglQueryString(display, EGL_EXTENSIONS);
+ while (const char* match = strstr(extensionsStr, extension)) {
+ // Ensure the string we found is its own extension, not a substring of a larger extension
+ // (e.g. GL_ARB_occlusion_query / GL_ARB_occlusion_query2).
+ if ((match == extensionsStr || match[-1] == ' ') &&
+ (match[extensionLength] == ' ' || match[extensionLength] == '\0')) {
+ return true;
+ }
+ extensionsStr = match + extensionLength;
+ }
+ return false;
+}
+
+void EGLGLTestContext::setupFenceSync(sk_sp<const GrGLInterface> interface) {
+ GrGLInterface* glInt = const_cast<GrGLInterface*>(interface.get());
+
+
+ if (kGL_GrGLStandard == glInt->fStandard) {
+ if (GrGLGetVersion(glInt) >= GR_GL_VER(3,2) || glInt->hasExtension("GL_ARB_sync")) {
+ return;
+ }
+ } else {
+ if (glInt->hasExtension("GL_APPLE_sync") || glInt->hasExtension("GL_NV_fence") ||
+ GrGLGetVersion(glInt) >= GR_GL_VER(3, 0)) {
+ return;
+ }
+ }
+
+ if (!supports_egl_extension(fDisplay, "EGL_KHR_fence_sync")) {
+ return;
+ }
+
+ auto grEGLCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR");
+ auto grEGLClientWaitSyncKHR =
+ (PFNEGLCLIENTWAITSYNCKHRPROC) eglGetProcAddress("eglClientWaitSyncKHR");
+ auto grEGLDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR");
+ auto grEGLGetSyncAttribKHR =
+ (PFNEGLGETSYNCATTRIBKHRPROC) eglGetProcAddress("eglGetSyncAttribKHR");
+ SkASSERT(grEGLCreateSyncKHR && grEGLClientWaitSyncKHR && grEGLDestroySyncKHR &&
+ grEGLGetSyncAttribKHR);
+
+ PFNEGLWAITSYNCKHRPROC grEGLWaitSyncKHR = nullptr;
+ if (supports_egl_extension(fDisplay, "EGL_KHR_wait_sync")) {
+ grEGLWaitSyncKHR = (PFNEGLWAITSYNCKHRPROC)eglGetProcAddress("eglWaitSyncKHR");
+ SkASSERT(grEGLWaitSyncKHR);
+ }
+
+ // Fake out glSync using eglSync
+ glInt->fExtensions.add("GL_APPLE_sync");
+
+ glInt->fFunctions.fFenceSync =
+ [grEGLCreateSyncKHR, display = fDisplay](GrGLenum condition, GrGLbitfield flags) {
+ SkASSERT(condition == GR_GL_SYNC_GPU_COMMANDS_COMPLETE);
+ SkASSERT(flags == 0);
+
+ EGLSyncKHR sync = grEGLCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
+
+ return reinterpret_cast<GrGLsync>(sync);
+ };
+
+ glInt->fFunctions.fDeleteSync = [grEGLDestroySyncKHR, display = fDisplay](GrGLsync sync) {
+ EGLSyncKHR eglSync = reinterpret_cast<EGLSyncKHR>(sync);
+ grEGLDestroySyncKHR(display, eglSync);
+ };
+
+ glInt->fFunctions.fClientWaitSync =
+ [grEGLClientWaitSyncKHR, display = fDisplay] (GrGLsync sync, GrGLbitfield flags,
+ GrGLuint64 timeout) -> GrGLenum {
+ EGLSyncKHR eglSync = reinterpret_cast<EGLSyncKHR>(sync);
+
+ EGLint egl_flags = 0;
+
+ if (flags & GR_GL_SYNC_FLUSH_COMMANDS_BIT) {
+ egl_flags |= EGL_SYNC_FLUSH_COMMANDS_BIT_KHR;
+ }
+
+ EGLint result = grEGLClientWaitSyncKHR(display, eglSync, egl_flags, timeout);
+
+ switch (result) {
+ case EGL_CONDITION_SATISFIED_KHR:
+ return GR_GL_CONDITION_SATISFIED;
+ case EGL_TIMEOUT_EXPIRED_KHR:
+ return GR_GL_TIMEOUT_EXPIRED;
+ case EGL_FALSE:
+ return GR_GL_WAIT_FAILED;
+ }
+ SkUNREACHABLE;
+ };
+
+ glInt->fFunctions.fWaitSync =
+ [grEGLClientWaitSyncKHR, grEGLWaitSyncKHR, display = fDisplay](GrGLsync sync,
+ GrGLbitfield flags,
+ GrGLuint64 timeout) {
+ EGLSyncKHR eglSync = reinterpret_cast<EGLSyncKHR>(sync);
+
+ SkASSERT(timeout == GR_GL_TIMEOUT_IGNORED);
+ SkASSERT(flags == 0);
+
+ if (!grEGLWaitSyncKHR) {
+ grEGLClientWaitSyncKHR(display, eglSync, 0, EGL_FOREVER_KHR);
+ return;
+ }
+
+ SkDEBUGCODE(EGLint result =) grEGLWaitSyncKHR(display, eglSync, 0);
+ SkASSERT(result);
+ };
+
+ glInt->fFunctions.fIsSync =
+ [grEGLGetSyncAttribKHR, display = fDisplay](GrGLsync sync) -> GrGLboolean {
+ EGLSyncKHR eglSync = reinterpret_cast<EGLSyncKHR>(sync);
+ EGLint value;
+ if (grEGLGetSyncAttribKHR(display, eglSync, EGL_SYNC_TYPE_KHR, &value)) {
+ return true;
+ }
+ return false;
+ };
+}
+
EGLGLTestContext::~EGLGLTestContext() {
this->teardown();
this->destroyGLContext();
@@ -331,21 +455,6 @@
return eglGetProcAddress(procName);
}
-static bool supports_egl_extension(EGLDisplay display, const char* extension) {
- size_t extensionLength = strlen(extension);
- const char* extensionsStr = eglQueryString(display, EGL_EXTENSIONS);
- while (const char* match = strstr(extensionsStr, extension)) {
- // Ensure the string we found is its own extension, not a substring of a larger extension
- // (e.g. GL_ARB_occlusion_query / GL_ARB_occlusion_query2).
- if ((match == extensionsStr || match[-1] == ' ') &&
- (match[extensionLength] == ' ' || match[extensionLength] == '\0')) {
- return true;
- }
- extensionsStr = match + extensionLength;
- }
- return false;
-}
-
std::unique_ptr<EGLFenceSync> EGLFenceSync::MakeIfSupported(EGLDisplay display) {
if (!display || !supports_egl_extension(display, "EGL_KHR_fence_sync")) {
return nullptr;