EGL: Plumb HDR metadata
HDR metadata comes in bit by bit via eglSurfaceAttribute.
Don't want to call native_window_set_buffers_smpte2086_metadata
for every piece, instead wait until eglSwapBuffers and call
native_window_set_buffers_smpte2086_metadata then.
Does require changing the state of the surface, so some const
goes away.
Bug: 63710530
Test: adb -d shell am start -n \
com.drawelements.deqp/android.app.NativeActivity \
-e cmdLine '"deqp --deqp-case=dEQP-EGL.functional.hdr_metadata.* \
--deqp-log-filename=/sdcard/dEQP-Log.qpa"'
Test: adb shell /data/nativetest/test-opengl-gl2_basic/test-opengl-gl2_basic
Test: adb shell /data/nativetest/test-opengl-gl_basic/test-opengl-gl_basic
Change-Id: I2e428ec18737f6caa8c0e1893705b7796fd77272
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 9ffe036..5927dc1 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -61,8 +61,8 @@
class EGLTest : public ::testing::Test {
public:
void get8BitConfig(EGLConfig& config);
- void addOptionalWindowMetadata(std::vector<EGLint>& attrs);
- void checkOptionalWindowMetadata(EGLSurface eglSurface);
+ void setSurfaceSmpteMetadata(EGLSurface surface);
+ void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
protected:
EGLDisplay mEglDisplay;
@@ -421,39 +421,39 @@
EXPECT_EQ(components[3], 8);
}
-void EGLTest::addOptionalWindowMetadata(std::vector<EGLint>& attrs) {
+void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT);
- attrs.push_back(METADATA_SCALE(0.640));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT);
- attrs.push_back(METADATA_SCALE(0.330));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT);
- attrs.push_back(METADATA_SCALE(0.290));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT);
- attrs.push_back(METADATA_SCALE(0.600));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT);
- attrs.push_back(METADATA_SCALE(0.150));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT);
- attrs.push_back(METADATA_SCALE(0.060));
- attrs.push_back(EGL_SMPTE2086_WHITE_POINT_X_EXT);
- attrs.push_back(METADATA_SCALE(0.3127));
- attrs.push_back(EGL_SMPTE2086_WHITE_POINT_Y_EXT);
- attrs.push_back(METADATA_SCALE(0.3290));
- attrs.push_back(EGL_SMPTE2086_MAX_LUMINANCE_EXT);
- attrs.push_back(METADATA_SCALE(300));
- attrs.push_back(EGL_SMPTE2086_MIN_LUMINANCE_EXT);
- attrs.push_back(METADATA_SCALE(0.7));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
+ METADATA_SCALE(0.640));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
+ METADATA_SCALE(0.330));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
+ METADATA_SCALE(0.290));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
+ METADATA_SCALE(0.600));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
+ METADATA_SCALE(0.150));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
+ METADATA_SCALE(0.060));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
+ METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
+ METADATA_SCALE(0.3290));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
+ METADATA_SCALE(300));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
+ METADATA_SCALE(0.7));
}
if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
- attrs.push_back(EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT);
- attrs.push_back(METADATA_SCALE(300));
- attrs.push_back(EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT);
- attrs.push_back(METADATA_SCALE(75));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
}
}
-void EGLTest::checkOptionalWindowMetadata(EGLSurface eglSurface) {
+void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
EGLBoolean success;
EGLint value;
@@ -534,8 +534,6 @@
winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
- ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
-
winAttrs.push_back(EGL_NONE);
EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
@@ -547,7 +545,9 @@
ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
- ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
+ ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
+
+ ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
}
@@ -584,9 +584,6 @@
std::vector<EGLint> winAttrs;
winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
-
- ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
-
winAttrs.push_back(EGL_NONE);
EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
@@ -598,7 +595,9 @@
ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
- ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
+ ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
+
+ ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
}
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 13f6fba..0bb77f3 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -32,6 +32,8 @@
using namespace android;
extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
+
static void printGLString(const char *name, GLenum s) {
// fprintf(stderr, "printGLString %s, %d\n", name, s);
const char *v = (const char *) glGetString(s);
@@ -265,6 +267,39 @@
return true;
}
+void setSurfaceMetadata(EGLDisplay dpy, EGLSurface surface) {
+ static EGLBoolean toggle = GL_FALSE;
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_SMPTE2086_metadata")) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.640));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.330));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.290));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.600));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.150));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.060));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.3290));
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(350));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(300));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.7));
+ }
+
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_CTA861_3_metadata")) {
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(325));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
+ }
+ toggle = !toggle;
+}
+
int main(int /*argc*/, char** /*argv*/) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};
@@ -318,10 +353,11 @@
printf("Chose this configuration:\n");
printEGLConfiguration(dpy, myConfig);
- surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+ EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE};
+ surface = eglCreateWindowSurface(dpy, myConfig, window, winAttribs);
checkEglError("eglCreateWindowSurface");
if (surface == EGL_NO_SURFACE) {
- printf("gelCreateWindowSurface failed.\n");
+ printf("eglCreateWindowSurface failed.\n");
return 0;
}
@@ -356,6 +392,7 @@
for (;;) {
renderFrame();
+ setSurfaceMetadata(dpy, surface);
eglSwapBuffers(dpy, surface);
checkEglError("eglSwapBuffers");
}
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index a675c7c..63d94be 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -15,6 +15,8 @@
using namespace android;
+#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
+
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
@@ -330,6 +332,39 @@
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
+void setSurfaceMetadata(EGLDisplay dpy, EGLSurface surface) {
+ static EGLBoolean toggle = GL_FALSE;
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_SMPTE2086_metadata")) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.640));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.330));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.290));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.600));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.150));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.060));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.3290));
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(350));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(300));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.7));
+ }
+
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_CTA861_3_metadata")) {
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(325));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
+ }
+ toggle = !toggle;
+}
+
void render()
{
const GLfloat vertices[] = {
@@ -354,5 +389,6 @@
int nelem = sizeof(indices)/sizeof(indices[0]);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
+ setSurfaceMetadata(eglDisplay, eglSurface);
eglSwapBuffers(eglDisplay, eglSurface);
}