summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Courtney Goeltzenleuchter <courtneygo@google.com> 2018-03-02 16:47:08 -0700
committer Courtney Goeltzenleuchter <courtneygo@google.com> 2018-03-10 16:09:42 -0700
commit936799c1d4bb80f5595153ef9efddbef4983526b (patch)
tree342e2268efa296472e09e0067f4184295b0600ab
parentb15829adaa2304676f935bf49edb78c1a42ae6e5 (diff)
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
-rw-r--r--opengl/libs/EGL/eglApi.cpp37
-rw-r--r--opengl/libs/EGL/egl_object.cpp59
-rw-r--r--opengl/libs/EGL/egl_object.h10
-rw-r--r--opengl/tests/EGLTest/EGL_test.cpp69
-rw-r--r--opengl/tests/gl2_basic/gl2_basic.cpp41
-rw-r--r--opengl/tests/gl_basic/gl_basic.cpp36
6 files changed, 185 insertions, 67 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 46e7a97e2c..d9be9dbc67 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -700,34 +700,26 @@ void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig confi
}
}
-EGLBoolean setSurfaceMetadata(egl_surface_t* s, NativeWindowType window,
- const EGLint *attrib_list) {
- // set any HDR metadata
- bool smpte2086 = false;
- bool cta8613 = false;
- if (attrib_list == nullptr) return EGL_TRUE;
-
- for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
- smpte2086 |= s->setSmpte2086Attribute(attr[0], attr[1]);
- cta8613 |= s->setCta8613Attribute(attr[0], attr[1]);
- }
- if (smpte2086) {
- android_smpte2086_metadata metadata = s->getSmpte2086Metadata();
- int err = native_window_set_buffers_smpte2086_metadata(window, &metadata);
+EGLBoolean sendSurfaceMetadata(egl_surface_t* s) {
+ android_smpte2086_metadata smpteMetadata;
+ if (s->getSmpte2086Metadata(smpteMetadata)) {
+ int err =
+ native_window_set_buffers_smpte2086_metadata(s->getNativeWindow(), &smpteMetadata);
+ s->resetSmpte2086Metadata();
if (err != 0) {
ALOGE("error setting native window smpte2086 metadata: %s (%d)",
strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
return EGL_FALSE;
}
}
- if (cta8613) {
- android_cta861_3_metadata metadata = s->getCta8613Metadata();
- int err = native_window_set_buffers_cta861_3_metadata(window, &metadata);
+ android_cta861_3_metadata cta8613Metadata;
+ if (s->getCta8613Metadata(cta8613Metadata)) {
+ int err =
+ native_window_set_buffers_cta861_3_metadata(s->getNativeWindow(), &cta8613Metadata);
+ s->resetCta8613Metadata();
if (err != 0) {
ALOGE("error setting native window CTS 861.3 metadata: %s (%d)",
strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
return EGL_FALSE;
}
}
@@ -1424,7 +1416,7 @@ EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
if (!_s.get())
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
- egl_surface_t const * const s = get_surface(draw);
+ egl_surface_t* const s = get_surface(draw);
if (CC_UNLIKELY(dp->traceGpuCompletion)) {
EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
@@ -1443,6 +1435,11 @@ EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
}
}
+ if (!sendSurfaceMetadata(s)) {
+ native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
+ return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
+ }
+
if (n_rects == 0) {
return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
}
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index b68fd61c11..f879254f76 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -64,8 +64,17 @@ egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWind
cnx(cnx),
connected(true),
colorSpace(colorSpace),
- egl_smpte2086_metadata({}),
- egl_cta861_3_metadata({}) {
+ egl_smpte2086_dirty(false),
+ egl_cta861_3_dirty(false) {
+ egl_smpte2086_metadata.displayPrimaryRed = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.displayPrimaryGreen = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.displayPrimaryBlue = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.whitePoint = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.maxLuminance = EGL_DONT_CARE;
+ egl_smpte2086_metadata.minLuminance = EGL_DONT_CARE;
+ egl_cta861_3_metadata.maxFrameAverageLightLevel = EGL_DONT_CARE;
+ egl_cta861_3_metadata.maxContentLightLevel = EGL_DONT_CARE;
+
if (win) {
win->incStrong(this);
}
@@ -92,33 +101,43 @@ EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value)
switch (attribute) {
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
egl_smpte2086_metadata.displayPrimaryRed.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
egl_smpte2086_metadata.displayPrimaryRed.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
egl_smpte2086_metadata.displayPrimaryGreen.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
egl_smpte2086_metadata.displayPrimaryGreen.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
egl_smpte2086_metadata.displayPrimaryBlue.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
egl_smpte2086_metadata.displayPrimaryBlue.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
egl_smpte2086_metadata.whitePoint.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
egl_smpte2086_metadata.whitePoint.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
egl_smpte2086_metadata.maxLuminance = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
egl_smpte2086_metadata.minLuminance = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
}
return EGL_FALSE;
@@ -128,16 +147,32 @@ EGLBoolean egl_surface_t::setCta8613Attribute(EGLint attribute, EGLint value) {
switch (attribute) {
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
egl_cta861_3_metadata.maxContentLightLevel = value;
+ egl_cta861_3_dirty = true;
return EGL_TRUE;
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
+ egl_cta861_3_dirty = true;
return EGL_TRUE;
}
return EGL_FALSE;
}
-const android_smpte2086_metadata egl_surface_t::getSmpte2086Metadata() {
- android_smpte2086_metadata metadata;
+EGLBoolean egl_surface_t::getSmpte2086Metadata(android_smpte2086_metadata& metadata) const {
+ if (!egl_smpte2086_dirty) return EGL_FALSE;
+ if (egl_smpte2086_metadata.displayPrimaryRed.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryRed.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryGreen.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryGreen.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryBlue.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryBlue.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.whitePoint.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.whitePoint.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.maxLuminance == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.minLuminance == EGL_DONT_CARE) {
+ ALOGW("egl_surface_t: incomplete SMPTE 2086 metadata!");
+ return EGL_FALSE;
+ }
+
metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) / EGL_METADATA_SCALING_EXT;
metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) / EGL_METADATA_SCALING_EXT;
metadata.displayPrimaryGreen.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) / EGL_METADATA_SCALING_EXT;
@@ -149,14 +184,22 @@ const android_smpte2086_metadata egl_surface_t::getSmpte2086Metadata() {
metadata.maxLuminance = static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
metadata.minLuminance = static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;
- return metadata;
+ return EGL_TRUE;
}
-const android_cta861_3_metadata egl_surface_t::getCta8613Metadata() {
- android_cta861_3_metadata metadata;
+EGLBoolean egl_surface_t::getCta8613Metadata(android_cta861_3_metadata& metadata) const {
+ if (!egl_cta861_3_dirty) return EGL_FALSE;
+
+ if (egl_cta861_3_metadata.maxContentLightLevel == EGL_DONT_CARE ||
+ egl_cta861_3_metadata.maxFrameAverageLightLevel == EGL_DONT_CARE) {
+ ALOGW("egl_surface_t: incomplete CTA861.3 metadata!");
+ return EGL_FALSE;
+ }
+
metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) / EGL_METADATA_SCALING_EXT;
metadata.maxFrameAverageLightLevel = static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) / EGL_METADATA_SCALING_EXT;
- return metadata;
+
+ return EGL_TRUE;
}
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index bda91bb280..4e1de5cec4 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -142,8 +142,10 @@ public:
EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
- const android_smpte2086_metadata getSmpte2086Metadata();
- const android_cta861_3_metadata getCta8613Metadata();
+ EGLBoolean getSmpte2086Metadata(android_smpte2086_metadata& smpte2086) const;
+ EGLBoolean getCta8613Metadata(android_cta861_3_metadata& cta861_3) const;
+ void resetSmpte2086Metadata() { egl_smpte2086_dirty = false; }
+ void resetCta8613Metadata() { egl_cta861_3_dirty = false; }
// Try to keep the order of these fields and size unchanged. It's not public API, but
// it's not hard to imagine native games accessing them.
@@ -176,6 +178,10 @@ private:
EGLint maxContentLightLevel;
EGLint maxFrameAverageLightLevel;
};
+
+ bool egl_smpte2086_dirty;
+ bool egl_cta861_3_dirty;
+
egl_smpte2086_metadata egl_smpte2086_metadata;
egl_cta861_3_metadata egl_cta861_3_metadata;
};
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 9ffe036abe..5927dc14e8 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -61,8 +61,8 @@ static bool hasHdrDisplay =
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 @@ void EGLTest::get8BitConfig(EGLConfig& config) {
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 @@ TEST_F(EGLTest, EGLBT2020Linear) {
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 @@ TEST_F(EGLTest, EGLBT2020Linear) {
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 @@ TEST_F(EGLTest, EGLBT2020PQ) {
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 @@ TEST_F(EGLTest, EGLBT2020PQ) {
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 13f6fba92e..0bb77f35f9 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 @@ int printEGLConfigurations(EGLDisplay dpy) {
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 @@ int main(int /*argc*/, char** /*argv*/) {
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 @@ int main(int /*argc*/, char** /*argv*/) {
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 a675c7c5bd..63d94be6ec 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 @@ void create_texture(void)
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 @@ void render()
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);
}