From 308cfc62de6e2a43df9eff36b2c58e7b264cbcbe Mon Sep 17 00:00:00 2001 From: Yuxiang Qian Date: Mon, 13 Jan 2025 14:54:18 +0800 Subject: [PATCH] Do not reset buffer age after query The spec doesn't mention that we need to reset the buffer age if no rendering after last call of eglQuerySurface to query EGL_BUFFER_AGE_KHR. Age was also reset after first time of query. Remove it to align with spec. New end2end test is also added. Bug: angleproject:391039188 Change-Id: I00c96e3a71ea2c9abcb86ebaf520243408dedd52 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6185135 Reviewed-by: Shahbaz Youssefi Commit-Queue: Shahbaz Youssefi Reviewed-by: Geoff Lang --- src/libANGLE/renderer/vulkan/SurfaceVk.cpp | 6 +-- src/tests/egl_tests/EGLBufferAgeTest.cpp | 48 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp index 0fc3896648c..24ecd9020c5 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp @@ -2837,7 +2837,7 @@ VkResult WindowSurfaceVk::acquireNextSwapchainImage(vk::Context *context) AcquireNextImageUnlocked(context->getDevice(), mSwapchain, &mAcquireOperation); } - // After the above call result is alway ready for processing. + // After the above call result is always ready for processing. return postProcessUnlockedAcquire(context); } @@ -3322,9 +3322,9 @@ egl::Error WindowSurfaceVk::getBufferAge(const gl::Context *context, EGLint *age } uint64_t frameNumber = mSwapchainImages[mCurrentSwapchainImageIndex].frameNumber; - if (frameNumber < mBufferAgeQueryFrameNumber) + if (frameNumber == 0) { - *age = 0; // Has not been used for rendering yet or since age was queried, no age. + *age = 0; // Has not been used for rendering yet, no age. } else { diff --git a/src/tests/egl_tests/EGLBufferAgeTest.cpp b/src/tests/egl_tests/EGLBufferAgeTest.cpp index 267a35659c9..d914e510283 100644 --- a/src/tests/egl_tests/EGLBufferAgeTest.cpp +++ b/src/tests/egl_tests/EGLBufferAgeTest.cpp @@ -252,6 +252,54 @@ TEST_P(EGLBufferAgeTest, QueryBufferAge) context = EGL_NO_CONTEXT; } +// Query for buffer age after several loops of swapping buffers +TEST_P(EGLBufferAgeTest, QueryBufferAgeAfterLoop) +{ + ANGLE_SKIP_TEST_IF(!mExtensionSupported); + + EGLConfig config = EGL_NO_CONFIG_KHR; + EXPECT_TRUE(chooseConfig(&config)); + + EGLContext context = EGL_NO_CONTEXT; + EXPECT_TRUE(createContext(config, &context)); + ASSERT_EGL_SUCCESS() << "eglCreateContext failed."; + + EGLSurface surface = EGL_NO_SURFACE; + + OSWindow *osWindow = OSWindow::New(); + osWindow->initialize("EGLBufferAgeTest", kWidth, kHeight); + EXPECT_TRUE(createWindowSurface(config, osWindow->getNativeWindow(), &surface)); + ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed."; + + EXPECT_TRUE(eglMakeCurrent(mDisplay, surface, surface, context)); + ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed."; + + glClearColor(1.0, 0.0, 0.0, 1.0); + + const uint32_t loopcount = 5; + for (uint32_t i = 0; i < loopcount; i++) + { + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR() << "glClear failed"; + eglSwapBuffers(mDisplay, surface); + ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed."; + } + + // This query age should not reset age + EXPECT_GT(queryAge(surface), 0); + + EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context)); + ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed."; + + eglDestroySurface(mDisplay, surface); + surface = EGL_NO_SURFACE; + osWindow->destroy(); + OSWindow::Delete(&osWindow); + + eglDestroyContext(mDisplay, context); + context = EGL_NO_CONTEXT; +} + // Verify contents of buffer are as expected TEST_P(EGLBufferAgeTest, VerifyContents) {