Commit 22fc9523 by Jeff Vigil Committed by Commit Bot

EGL: implement EGL_EXT_buffer_age

Add extension flag. Add Validation check to surface query. Enable extension for vulkan. Modify AcquireNextImage to ++frame count and tag images with frame number. Buffer age is the difference between current frame count and the tagged frame number on the buffer. getBuffeAge may need to trigger AcquireNextImage to be current. Pass through egl extension and query. Add EGLBufferAgeTest Test: angle_end2end_test --gtest_filter=EGLBufferAgeTest Test: angle_deqp_egl_tests --deqp-case=dEQP-EGL.functional.buffer_age.* Bug: angleproject:3529 Change-Id: I0cb94be1c3e85d6f33e82a6a1ccdc9731b6a7f23 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2684724 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c11186c2
......@@ -1474,6 +1474,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_NV_robustness_video_memory_purge", robustnessVideoMemoryPurgeNV, &extensionStrings);
InsertExtensionString("EGL_KHR_reusable_sync", reusableSyncKHR, &extensionStrings);
InsertExtensionString("EGL_ANGLE_external_context_and_surface", externalContextAndSurface, &extensionStrings);
InsertExtensionString("EGL_EXT_buffer_age", bufferAgeEXT, &extensionStrings);
// clang-format on
return extensionStrings;
......
......@@ -1218,6 +1218,9 @@ struct DisplayExtensions
// EGL_ANGLE_external_context_and_surface
bool externalContextAndSurface = false;
// EGL_EXT_buffer_age
bool bufferAgeEXT = false;
};
struct DeviceExtensions
......
......@@ -17,7 +17,6 @@
#include "libANGLE/Display.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Texture.h"
#include "libANGLE/Thread.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/trace.h"
......@@ -586,6 +585,21 @@ GLuint Surface::getId() const
return 0;
}
Error Surface::getBufferAge(const gl::Context *context, EGLint *age) const
{
// When EGL_BUFFER_PRESERVED, the previous frame contents are copied to
// current frame, so the buffer age is always 1.
if (mSwapBehavior == EGL_BUFFER_PRESERVED)
{
if (age != nullptr)
{
*age = 1;
}
return egl::NoError();
}
return mImplementation->getBufferAge(context, age);
}
gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context,
egl::Surface *readSurface)
{
......
......@@ -186,6 +186,8 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
// otherwise.
const gl::Offset &getTextureOffset() const { return mTextureOffset; }
Error getBufferAge(const gl::Context *context, EGLint *age) const;
protected:
Surface(EGLint surfaceType,
const egl::Config *config,
......
......@@ -4155,6 +4155,7 @@ void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *va
}
egl::Error QuerySurfaceAttrib(const Display *display,
const gl::Context *context,
const Surface *surface,
EGLint attribute,
EGLint *value)
......@@ -4253,6 +4254,9 @@ egl::Error QuerySurfaceAttrib(const Display *display,
case EGL_TIMESTAMPS_ANDROID:
*value = surface->isTimestampsEnabled();
break;
case EGL_BUFFER_AGE_EXT:
ANGLE_TRY(surface->getBufferAge(context, value));
break;
default:
UNREACHABLE();
break;
......
......@@ -275,6 +275,7 @@ void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value);
void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value);
egl::Error QuerySurfaceAttrib(const Display *display,
const gl::Context *context,
const Surface *surface,
EGLint attribute,
EGLint *value);
......
......@@ -113,4 +113,11 @@ egl::Error SurfaceImpl::getUserHeight(const egl::Display *display, EGLint *value
*value = getHeight();
return egl::NoError();
}
egl::Error SurfaceImpl::getBufferAge(const gl::Context *context, EGLint *age)
{
UNREACHABLE();
return egl::EglBadMatch();
}
} // namespace rx
......@@ -109,6 +109,7 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
EGLint numTimestamps,
const EGLint *timestamps,
EGLnsecsANDROID *values) const;
virtual egl::Error getBufferAge(const gl::Context *context, EGLint *age);
protected:
const egl::SurfaceState &mState;
......
......@@ -699,6 +699,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->robustnessVideoMemoryPurgeNV = mHasNVRobustnessVideoMemoryPurge;
outExtensions->bufferAgeEXT = mEGL->hasExtension("EGL_EXT_buffer_age");
DisplayGL::generateExtensions(outExtensions);
}
......
......@@ -42,4 +42,15 @@ egl::Error WindowSurfaceEGL::initialize(const egl::Display *display)
return egl::NoError();
}
egl::Error WindowSurfaceEGL::getBufferAge(const gl::Context *context, EGLint *age)
{
ANGLE_UNUSED_VARIABLE(context);
EGLBoolean result = mEGL->querySurface(mSurface, EGL_BUFFER_AGE_EXT, age);
if (result == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglQuerySurface for EGL_BUFFER_AGE_EXT failed");
}
return egl::NoError();
}
} // namespace rx
......@@ -25,6 +25,8 @@ class WindowSurfaceEGL : public SurfaceEGL
egl::Error initialize(const egl::Display *display) override;
egl::Error getBufferAge(const gl::Context *context, EGLint *age) override;
private:
EGLNativeWindowType mWindow;
};
......
......@@ -245,6 +245,8 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->ggpStreamDescriptor = true;
outExtensions->swapWithFrameToken = getRenderer()->getFeatures().supportsGGPFrameToken.enabled;
#endif // defined(ANGLE_PLATFORM_GGP)
outExtensions->bufferAgeEXT = true;
}
void DisplayVk::generateCaps(egl::Caps *outCaps) const
......
......@@ -483,7 +483,8 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState, EGLNativ
mCurrentSwapchainImageIndex(0),
mDepthStencilImageBinding(this, kAnySurfaceImageSubjectIndex),
mColorImageMSBinding(this, kAnySurfaceImageSubjectIndex),
mNeedToAcquireNextSwapchainImage(false)
mNeedToAcquireNextSwapchainImage(false),
mFrameCount(1)
{
// Initialize the color render target with the multisampled targets. If not multisampled, the
// render target will be updated to refer to a swapchain image on every acquire.
......@@ -1063,6 +1064,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
Is90DegreeRotation(getPreTransform()), format, 1,
robustInit);
member.imageViews.init(renderer);
member.mFrameNumber = 0;
}
// Initialize depth/stencil if requested.
......@@ -1440,6 +1442,9 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
VkResult result = renderer->queuePresent(contextVk, contextVk->getPriority(), presentInfo);
// Set FrameNumber for the presented image.
mSwapchainImages[mCurrentSwapchainImageIndex].mFrameNumber = mFrameCount++;
ANGLE_TRY(computePresentOutOfDate(contextVk, result, presentOutOfDate));
return angle::Result::Continue;
......@@ -1897,4 +1902,33 @@ angle::Result WindowSurfaceVk::drawOverlay(ContextVk *contextVk, SwapchainImage
return angle::Result::Continue;
}
egl::Error WindowSurfaceVk::getBufferAge(const gl::Context *context, EGLint *age)
{
if (mNeedToAcquireNextSwapchainImage)
{
// Acquire the current image if needed.
DisplayVk *displayVk = vk::GetImpl(context->getDisplay());
egl::Error result =
angle::ToEGL(doDeferredAcquireNextImage(context, false), displayVk, EGL_BAD_SURFACE);
if (result.isError())
{
return result;
}
}
if (age != nullptr)
{
uint64_t frameNumber = mSwapchainImages[mCurrentSwapchainImageIndex].mFrameNumber;
if (frameNumber == 0)
{
*age = 0; // Has not been used for rendering yet, no age.
}
else
{
*age = static_cast<EGLint>(mFrameCount - frameNumber);
}
}
return egl::NoError();
}
} // namespace rx
......@@ -168,6 +168,7 @@ struct SwapchainImage : angle::NonCopyable
static constexpr size_t kPresentHistorySize = kSwapHistorySize + 1;
std::array<ImagePresentHistory, kPresentHistorySize> presentHistory;
size_t currentPresentHistoryIndex = 0;
uint64_t mFrameNumber = 0;
};
} // namespace impl
......@@ -243,6 +244,8 @@ class WindowSurfaceVk : public SurfaceVk
return mPreTransform;
}
egl::Error getBufferAge(const gl::Context *context, EGLint *age) override;
protected:
angle::Result swapImpl(const gl::Context *context,
const EGLint *rects,
......@@ -340,6 +343,9 @@ class WindowSurfaceVk : public SurfaceVk
// True when acquiring the next image is deferred.
bool mNeedToAcquireNextSwapchainImage;
// EGL_EXT_buffer_age: Track frame count.
uint64_t mFrameCount;
};
} // namespace rx
......
......@@ -4982,6 +4982,27 @@ bool ValidateQuerySurface(const ValidationContext *val,
}
break;
case EGL_BUFFER_AGE_EXT:
{
if (!display->getExtensions().bufferAgeEXT)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_BUFFER_AGE_EXT cannot be used without "
"EGL_EXT_buffer_age support.");
return false;
}
gl::Context *context = val->eglThread->getContext();
if ((context == nullptr) || (context->getCurrentDrawSurface() != surface))
{
val->setError(EGL_BAD_SURFACE,
"The surface must be current to the current context "
"in order to query buffer age per extension "
"EGL_EXT_buffer_age.");
return false;
}
}
break;
default:
val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute.");
return false;
......
......@@ -557,8 +557,9 @@ EGLBoolean QuerySurface(Thread *thread,
{
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, QuerySurfaceAttrib(display, eglSurface, attribute, value),
"eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(
thread, QuerySurfaceAttrib(display, thread->getContext(), eglSurface, attribute, value),
"eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
......
......@@ -6,6 +6,7 @@ angle_end2end_tests_sources = [
"egl_tests/EGLAndroidFrameBufferTargetTest.cpp",
"egl_tests/EGLBackwardsCompatibleContextTest.cpp",
"egl_tests/EGLBlobCacheTest.cpp",
"egl_tests/EGLBufferAgeTest.cpp",
"egl_tests/EGLChooseConfigTest.cpp",
"egl_tests/EGLContextASANTest.cpp",
"egl_tests/EGLContextCompatibilityTest.cpp",
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// EGLBufferAgeTest.cpp:
// EGL extension EGL_EXT_buffer_age
//
#include <gtest/gtest.h>
#include "test_utils/ANGLETest.h"
#include "util/EGLWindow.h"
#include "util/OSWindow.h"
using namespace angle;
class EGLBufferAgeTest : public ANGLETest
{
public:
EGLBufferAgeTest() : mDisplay(EGL_NO_DISPLAY) {}
void testSetUp() override
{
EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
mDisplay = eglGetPlatformDisplayEXT(
EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
mMajorVersion = GetParam().majorVersion;
mExtensionSupported = IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_buffer_age");
}
void testTearDown() override
{
if (mDisplay != EGL_NO_DISPLAY)
{
eglTerminate(mDisplay);
eglReleaseThread();
mDisplay = EGL_NO_DISPLAY;
}
ASSERT_EGL_SUCCESS() << "Error during test TearDown";
}
bool chooseConfig(EGLConfig *config)
{
bool result = false;
EGLint count = 0;
EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
EGLint attribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
0,
EGL_RENDERABLE_TYPE,
clientVersion,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_NONE};
result = eglChooseConfig(mDisplay, attribs, config, 1, &count);
EXPECT_EGL_TRUE(result && (count > 0));
return result;
}
bool createContext(EGLConfig config, EGLContext *context)
{
bool result = false;
EGLint attribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
*context = eglCreateContext(mDisplay, config, nullptr, attribs);
result = (*context != EGL_NO_CONTEXT);
EXPECT_TRUE(result);
return result;
}
bool createWindowSurface(EGLConfig config, EGLNativeWindowType win, EGLSurface *surface)
{
bool result = false;
EGLint attribs[] = {EGL_NONE};
*surface = eglCreateWindowSurface(mDisplay, config, win, attribs);
result = (*surface != EGL_NO_SURFACE);
EXPECT_TRUE(result);
return result;
}
EGLint queryAge(EGLSurface surface)
{
EGLint value = 0;
bool result = eglQuerySurface(mDisplay, surface, EGL_BUFFER_AGE_EXT, &value);
EXPECT_TRUE(result);
return value;
}
EGLDisplay mDisplay = EGL_NO_DISPLAY;
EGLint mMajorVersion = 0;
const EGLint kWidth = 64;
const EGLint kHeight = 64;
bool mExtensionSupported = false;
};
// Query for buffer age
TEST_P(EGLBufferAgeTest, QueryBufferAge)
{
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 = 15;
EGLint expectedAge = 0;
for (uint32_t i = 0; i < loopcount; i++)
{
EGLint age = queryAge(surface);
// Should start with zero age and then flip to buffer count - which we don't know.
if ((expectedAge == 0) && (age > 0))
{
expectedAge = age;
}
EXPECT_EQ(age, expectedAge);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR() << "glClear failed";
eglSwapBuffers(mDisplay, surface);
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
}
EXPECT_GT(expectedAge, 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)
{
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.";
const angle::GLColor kLightGray(191, 191, 191, 255); // 0.75
const angle::GLColor kDarkGray(64, 64, 64, 255); // 0.25
const angle::GLColor kColorSet[] = {
GLColor::blue, GLColor::cyan, kDarkGray, GLColor::green, GLColor::red,
GLColor::white, GLColor::yellow, GLColor::black, GLColor::magenta, kLightGray,
GLColor::black, // Extra loops until color cycled through
GLColor::black, GLColor::black, GLColor::black, GLColor::black};
EGLint age = 0;
angle::GLColor expectedColor = GLColor::black;
int loopCount = (sizeof(kColorSet) / sizeof(kColorSet[0]));
for (int i = 0; i < loopCount; i++)
{
age = queryAge(surface);
if (age > 0)
{
// Check that color/content is what we expect
expectedColor = kColorSet[i - age];
EXPECT_PIXEL_COLOR_EQ(1, 1, expectedColor);
}
float red = kColorSet[i].R / 255.0;
float green = kColorSet[i].G / 255.0;
float blue = kColorSet[i].B / 255.0;
float alpha = kColorSet[i].A / 255.0;
glClearColor(red, green, blue, alpha);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR() << "glClear failed";
eglSwapBuffers(mDisplay, surface);
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
}
EXPECT_GT(age, 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 EGL_BAD_SURFACE when not current
TEST_P(EGLBufferAgeTest, UncurrentContextBadSurface)
{
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.";
// No current context
EGLint value = 0;
EXPECT_EGL_FALSE(eglQuerySurface(mDisplay, surface, EGL_BUFFER_AGE_EXT, &value));
EXPECT_EGL_ERROR(EGL_BAD_SURFACE);
EGLContext otherContext = EGL_NO_CONTEXT;
EXPECT_TRUE(createContext(config, &otherContext));
ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
// Surface current to another context
EXPECT_TRUE(eglMakeCurrent(mDisplay, surface, surface, otherContext));
// Make context the active context
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
value = 0;
EXPECT_EGL_FALSE(eglQuerySurface(mDisplay, surface, EGL_BUFFER_AGE_EXT, &value));
EXPECT_EGL_ERROR(EGL_BAD_SURFACE);
eglDestroySurface(mDisplay, surface);
surface = EGL_NO_SURFACE;
osWindow->destroy();
OSWindow::Delete(&osWindow);
eglDestroyContext(mDisplay, otherContext);
otherContext = EGL_NO_CONTEXT;
eglDestroyContext(mDisplay, context);
context = EGL_NO_CONTEXT;
}
// Expect age always == 1 when EGL_BUFFER_PRESERVED is chosen
TEST_P(EGLBufferAgeTest, BufferPreserved)
{
ANGLE_SKIP_TEST_IF(!mExtensionSupported);
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint count = 0;
EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
EGLint attribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
0,
EGL_RENDERABLE_TYPE,
clientVersion,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT,
EGL_NONE};
EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
// Skip if no configs, this indicates EGL_BUFFER_PRESERVED is not supported.
ANGLE_SKIP_TEST_IF(count == 0);
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 = 10;
EGLint expectedAge = 1;
for (uint32_t i = 0; i < loopcount; i++)
{
EGLint age = queryAge(surface);
EXPECT_EQ(age, expectedAge);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR() << "glClear failed";
eglSwapBuffers(mDisplay, surface);
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
}
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;
}
ANGLE_INSTANTIATE_TEST(EGLBufferAgeTest,
WithNoFixture(ES2_OPENGLES()),
WithNoFixture(ES3_OPENGLES()),
WithNoFixture(ES2_OPENGL()),
WithNoFixture(ES3_OPENGL()),
WithNoFixture(ES2_VULKAN()),
WithNoFixture(ES3_VULKAN()));
\ No newline at end of file
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