Commit 904ac340 by Mohan Maiya Committed by Commit Bot

Bug fix for WaitClient, WaitGL and WaitNative

It is valid to call eglWaitClient, eglWaitGL and eglWaitNative when there is no active context in the current thread. Update code to account for that possibility. Bug: angleproject:5898 Test: EGLSyncTest.WaitClient* EGLSyncTest.WaitGL* EGLSyncTest.WaitNative* Change-Id: I81f05a27f1f641cf8986e2e6c05c183ea8471889 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2849587Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent 8abb778c
...@@ -4368,6 +4368,13 @@ bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val, ...@@ -4368,6 +4368,13 @@ bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val,
bool ValidateWaitNative(const ValidationContext *val, const EGLint engine) bool ValidateWaitNative(const ValidationContext *val, const EGLint engine)
{ {
if (val->eglThread->getDisplay() == nullptr)
{
// EGL spec says this about eglWaitNative -
// eglWaitNative is ignored if there is no current EGL rendering context.
return true;
}
ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
if (engine != EGL_CORE_NATIVE_ENGINE) if (engine != EGL_CORE_NATIVE_ENGINE)
...@@ -5760,6 +5767,13 @@ bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked, ...@@ -5760,6 +5767,13 @@ bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked,
bool ValidateWaitGL(const ValidationContext *val) bool ValidateWaitGL(const ValidationContext *val)
{ {
if (val->eglThread->getDisplay() == nullptr)
{
// EGL spec says this about eglWaitGL -
// eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
return true;
}
ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay())); ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
return true; return true;
} }
...@@ -5776,6 +5790,15 @@ bool ValidateReleaseThread(const ValidationContext *val) ...@@ -5776,6 +5790,15 @@ bool ValidateReleaseThread(const ValidationContext *val)
bool ValidateWaitClient(const ValidationContext *val) bool ValidateWaitClient(const ValidationContext *val)
{ {
if (val->eglThread->getDisplay() == nullptr)
{
// EGL spec says this about eglWaitClient -
// If there is no current context for the current rendering API,
// the function has no effect but still returns EGL_TRUE.
return true;
}
ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
return true; return true;
} }
......
...@@ -692,7 +692,15 @@ EGLBoolean Terminate(Thread *thread, Display *display) ...@@ -692,7 +692,15 @@ EGLBoolean Terminate(Thread *thread, Display *display)
EGLBoolean WaitClient(Thread *thread) EGLBoolean WaitClient(Thread *thread)
{ {
Display *display = thread->getDisplay(); Display *display = thread->getDisplay();
if (display == nullptr)
{
// EGL spec says this about eglWaitClient -
// If there is no current context for the current rendering API,
// the function has no effect but still returns EGL_TRUE.
return EGL_TRUE;
}
gl::Context *context = thread->getContext(); gl::Context *context = thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitClient", ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitClient",
...@@ -707,6 +715,12 @@ EGLBoolean WaitClient(Thread *thread) ...@@ -707,6 +715,12 @@ EGLBoolean WaitClient(Thread *thread)
EGLBoolean WaitGL(Thread *thread) EGLBoolean WaitGL(Thread *thread)
{ {
Display *display = thread->getDisplay(); Display *display = thread->getDisplay();
if (display == nullptr)
{
// EGL spec says this about eglWaitGL -
// eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
return EGL_TRUE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitGL", GetDisplayIfValid(display), ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitGL", GetDisplayIfValid(display),
EGL_FALSE); EGL_FALSE);
...@@ -723,6 +737,13 @@ EGLBoolean WaitGL(Thread *thread) ...@@ -723,6 +737,13 @@ EGLBoolean WaitGL(Thread *thread)
EGLBoolean WaitNative(Thread *thread, EGLint engine) EGLBoolean WaitNative(Thread *thread, EGLint engine)
{ {
Display *display = thread->getDisplay(); Display *display = thread->getDisplay();
if (display == nullptr)
{
// EGL spec says this about eglWaitNative -
// eglWaitNative is ignored if there is no current EGL rendering context.
return EGL_TRUE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitNative", ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitNative",
GetDisplayIfValid(display), EGL_FALSE); GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative", ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative",
......
...@@ -235,6 +235,42 @@ TEST_P(EGLSyncTest, BasicOperations) ...@@ -235,6 +235,42 @@ TEST_P(EGLSyncTest, BasicOperations)
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync)); EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
} }
// Test eglWaitClient api
TEST_P(EGLSyncTest, WaitClient)
{
// Clear to red color
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EGL_TRUE(eglWaitClient());
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
EGLDisplay display = getEGLWindow()->getDisplay();
EGLContext context = getEGLWindow()->getContext();
EGLSurface surface = getEGLWindow()->getSurface();
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EGL_TRUE(eglWaitClient());
eglMakeCurrent(display, surface, surface, context);
}
// Test eglWaitGL api
TEST_P(EGLSyncTest, WaitGL)
{
// Clear to red color
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EGL_TRUE(eglWaitGL());
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
EGLDisplay display = getEGLWindow()->getDisplay();
EGLContext context = getEGLWindow()->getContext();
EGLSurface surface = getEGLWindow()->getSurface();
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EGL_TRUE(eglWaitGL());
eglMakeCurrent(display, surface, surface, context);
}
// Test eglWaitNative api // Test eglWaitNative api
TEST_P(EGLSyncTest, WaitNative) TEST_P(EGLSyncTest, WaitNative)
{ {
...@@ -244,6 +280,13 @@ TEST_P(EGLSyncTest, WaitNative) ...@@ -244,6 +280,13 @@ TEST_P(EGLSyncTest, WaitNative)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE)); EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red); EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
EGLDisplay display = getEGLWindow()->getDisplay();
EGLContext context = getEGLWindow()->getContext();
EGLSurface surface = getEGLWindow()->getSurface();
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
eglMakeCurrent(display, surface, surface, context);
} }
// Verify eglDupNativeFence for EGL_ANDROID_native_fence_sync // Verify eglDupNativeFence for EGL_ANDROID_native_fence_sync
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment