diff options
| author | 2018-03-02 16:47:08 -0700 | |
|---|---|---|
| committer | 2018-03-10 16:09:42 -0700 | |
| commit | 936799c1d4bb80f5595153ef9efddbef4983526b (patch) | |
| tree | 342e2268efa296472e09e0067f4184295b0600ab | |
| parent | b15829adaa2304676f935bf49edb78c1a42ae6e5 (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.cpp | 37 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_object.cpp | 59 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_object.h | 10 | ||||
| -rw-r--r-- | opengl/tests/EGLTest/EGL_test.cpp | 69 | ||||
| -rw-r--r-- | opengl/tests/gl2_basic/gl2_basic.cpp | 41 | ||||
| -rw-r--r-- | opengl/tests/gl_basic/gl_basic.cpp | 36 |
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); } |