Remove wrapping of GL sync objects around EGL syncs in EGL test contexts
We did this to allow pipelining of GPU/CPU work in nanobench on devices that don't have GL sync objects (or NV fence). However, we've found that on the AndroidOne/Mali400 and Nexus7/Tegra3 devices that the majority of a frame's work can be reordered to complete before an earlier EGL sync. This makes the results unreliable, especially the min_ms result. Just accept that we will sync the CPU and GPU on these devices. Change-Id: I04d168cbb05504d367f6a06b7b4903163ab2aa79 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/414897 Commit-Queue: Brian Salomon <bsalomon@google.com> Commit-Queue: Adlai Holler <adlai@google.com> Auto-Submit: Brian Salomon <bsalomon@google.com> Reviewed-by: Adlai Holler <adlai@google.com>
This commit is contained in:
parent
5e6a1fec93
commit
7db0e2f942
@ -43,8 +43,6 @@ private:
|
||||
std::function<void()> onPlatformGetAutoContextRestore() const override;
|
||||
GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
|
||||
|
||||
void setupFenceSync(sk_sp<const GrGLInterface>);
|
||||
|
||||
PFNEGLCREATEIMAGEKHRPROC fEglCreateImageProc = nullptr;
|
||||
PFNEGLDESTROYIMAGEKHRPROC fEglDestroyImageProc = nullptr;
|
||||
|
||||
@ -184,8 +182,6 @@ EGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext*
|
||||
continue;
|
||||
}
|
||||
|
||||
this->setupFenceSync(gl);
|
||||
|
||||
if (!gl->validate()) {
|
||||
SkDebugf("Failed to validate gl interface.\n");
|
||||
this->destroyGLContext();
|
||||
@ -209,134 +205,6 @@ EGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext*
|
||||
}
|
||||
}
|
||||
|
||||
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, surface = fSurface](GrGLenum condition,
|
||||
GrGLbitfield flags) {
|
||||
SkASSERT(condition == GR_GL_SYNC_GPU_COMMANDS_COMPLETE);
|
||||
SkASSERT(flags == 0);
|
||||
|
||||
EGLSyncKHR sync = grEGLCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
|
||||
|
||||
// It seems that, at least on the 2012 N7, later render passes will be reordered before a
|
||||
// fence. This really messes up benchmark timings where a large fraction of the work for
|
||||
// sample N can occur before the fence for sample N-1 signals. This causes sample N-1 to be
|
||||
// artificially slow and N artificially fast. Inserting a swap buffers (to the unused
|
||||
// display surface) blocks that reordering.
|
||||
eglSwapBuffers(display, surface);
|
||||
|
||||
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();
|
||||
|
Loading…
Reference in New Issue
Block a user