Merge changes I2b89dce1,I5412eae0,I2e428ec1 into pi-dev am: 990cc3e31d
am: d828b8f5f5
Change-Id: I5f8173f6cb7505355d4d89f554d0e6389e1ed384
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 23a9853..3e4a42c 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -39,6 +39,7 @@
"android.frameworks.vr.composer@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"libbinder",
"libbase",
"libbufferhubqueue",
@@ -62,6 +63,7 @@
headerLibraries = [
"android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
"libdvr_headers",
"libsurfaceflinger_headers",
]
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 46e7a97..b453d19 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -87,6 +87,8 @@
"EGL_ANDROID_get_native_client_buffer "
"EGL_ANDROID_front_buffer_auto_refresh "
"EGL_ANDROID_get_frame_timestamps "
+ "EGL_EXT_surface_SMPTE2086_metadata "
+ "EGL_EXT_surface_CTA861_3_metadata "
;
char const * const gExtensionString =
@@ -240,8 +242,6 @@
!strcmp((procname), "eglHibernateProcessIMG") || \
!strcmp((procname), "eglAwakenProcessIMG"))
-
-
// accesses protected by sExtensionMapMutex
static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
@@ -476,26 +476,61 @@
return dataSpace;
}
-// Return true if we stripped any EGL_GL_COLORSPACE_KHR or HDR metadata attributes.
-// Protect devices from attributes they don't recognize that are managed by Android
+// stripAttributes is used by eglCreateWindowSurface, eglCreatePbufferSurface
+// and eglCreatePixmapSurface to clean up color space related Window parameters
+// that a driver does not advertise support for.
+// Return true if stripped_attrib_list has stripped contents.
+
static EGLBoolean stripAttributes(egl_display_ptr dp, const EGLint* attrib_list,
EGLint format,
std::vector<EGLint>& stripped_attrib_list) {
std::vector<EGLint> allowedColorSpaces;
+ bool haveColorSpaceSupport = dp->haveExtension("EGL_KHR_gl_colorspace");
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- // driver okay with linear & sRGB for 8888, but can't handle
- // Display-P3 or other spaces.
- allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
- allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
+ if (haveColorSpaceSupport) {
+ // Spec says:
+ // [fn1] Only OpenGL and OpenGL ES contexts which support sRGB
+ // rendering must respect requests for EGL_GL_COLORSPACE_SRGB_KHR, and
+ // only to sRGB formats supported by the context (normally just SRGB8)
+ // Older versions not supporting sRGB rendering will ignore this
+ // surface attribute.
+ //
+ // We support sRGB and pixel format is SRGB8, so allow
+ // the EGL_GL_COLORSPACE_SRGB_KHR and
+ // EGL_GL_COLORSPACE_LINEAR_KHR
+ // colorspaces to be specified.
+
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_display_p3_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_display_p3")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_bt2020_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_bt2020_pq")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_scrgb_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
+ }
break;
case HAL_PIXEL_FORMAT_RGBA_FP16:
case HAL_PIXEL_FORMAT_RGBA_1010102:
- default:
- // driver does not want to see colorspace attributes for 1010102 or fp16.
+ case HAL_PIXEL_FORMAT_RGB_565:
// Future: if driver supports XXXX extension, we can pass down that colorspace
+ default:
break;
}
@@ -513,40 +548,23 @@
found = true;
}
}
- if (found || !dp->haveExtension("EGL_KHR_gl_colorspace")) {
+ if (found) {
+ // Found supported attribute
+ stripped_attrib_list.push_back(attr[0]);
+ stripped_attrib_list.push_back(attr[1]);
+ } else if (!haveColorSpaceSupport) {
+ // Device does not support colorspace extension
+ // pass on the attribute and let downstream
+ // components validate like normal
stripped_attrib_list.push_back(attr[0]);
stripped_attrib_list.push_back(attr[1]);
} else {
+ // Found supported attribute that driver does not
+ // support, strip it.
stripped = true;
}
}
break;
- case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
- case EGL_SMPTE2086_WHITE_POINT_X_EXT:
- case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
- case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
- case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
- if (dp->haveExtension("EGL_EXT_surface_SMPTE2086_metadata")) {
- stripped = true;
- } else {
- stripped_attrib_list.push_back(attr[0]);
- stripped_attrib_list.push_back(attr[1]);
- }
- break;
- case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
- case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
- if (dp->haveExtension("EGL_EXT_surface_CTA861_3_metadata")) {
- stripped = true;
- } else {
- stripped_attrib_list.push_back(attr[0]);
- stripped_attrib_list.push_back(attr[1]);
- }
- break;
default:
stripped_attrib_list.push_back(attr[0]);
stripped_attrib_list.push_back(attr[1]);
@@ -700,34 +718,26 @@
}
}
-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;
}
}
@@ -812,11 +822,7 @@
if (surface != EGL_NO_SURFACE) {
egl_surface_t* s =
new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
-
- if (setSurfaceMetadata(s, window, origAttribList)) {
- return s;
- }
- eglDestroySurface(dpy, s);
+ return s;
}
// EGLSurface creation failed
@@ -1424,7 +1430,7 @@
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 +1449,11 @@
}
}
+ 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_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 0f36614..74ddd1c 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -51,8 +51,11 @@
// ----------------------------------------------------------------------------
-static bool findExtension(const char* exts, const char* name, size_t nameLen) {
+bool findExtension(const char* exts, const char* name, size_t nameLen) {
if (exts) {
+ if (!nameLen) {
+ nameLen = strlen(name);
+ }
for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
if (match[nameLen] == '\0' || match[nameLen] == ' ') {
return true;
@@ -226,11 +229,6 @@
"EGL_EXT_gl_colorspace_bt2020_linear EGL_EXT_gl_colorspace_bt2020_pq ");
}
- // Always advertise HDR metadata extensions since it's okay for an application
- // to specify such information even though it may not be used by the system.
- mExtensionString.append(
- "EGL_EXT_surface_SMPTE2086_metadata EGL_EXT_surface_CTA861_3_metadata ");
-
char const* start = gExtensionString;
do {
// length of the extension name
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 661f47e..ccd333d 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -42,6 +42,8 @@
class egl_context_t;
struct egl_connection_t;
+bool findExtension(const char* exts, const char* name, size_t nameLen = 0);
+
// ----------------------------------------------------------------------------
class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index b68fd61..f879254 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -64,8 +64,17 @@
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 @@
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 @@
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 @@
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 bda91bb..4e1de5c 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -142,8 +142,10 @@
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 @@
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 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);
}
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 5d68696..eeeba2e 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -24,6 +24,7 @@
"android.hardware.configstore@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"android.hardware.power@1.0",
"libbase",
"libbinder",
@@ -57,6 +58,7 @@
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
],
export_static_lib_headers: [
"libserviceutils",
@@ -64,6 +66,7 @@
export_shared_lib_headers: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"libhidlbase",
"libhidltransport",
"libhwbinder",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index d07a52b..ec47551 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -618,6 +618,13 @@
to_string(error).c_str(), static_cast<int32_t>(error));
}
+ const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
+ error = hwcLayer->setHdrMetadata(metadata);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
getBE().mHwcLayers[hwcId].bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot,
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 03b714f..bb720f7 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -19,15 +19,23 @@
#include <inttypes.h>
#include <log/log.h>
-#include <gui/BufferQueue.h>
#include "ComposerHal.h"
+#include <android/hardware/graphics/composer/2.2/IComposer.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <gui/BufferQueue.h>
+#include <hidl/HidlTransportUtils.h>
+
namespace android {
using hardware::Return;
using hardware::hidl_vec;
using hardware::hidl_handle;
+using namespace hardware::graphics::composer;
+using PerFrameMetadata = hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadata;
+using PerFrameMetadataKey =
+ hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
namespace Hwc2 {
@@ -117,10 +125,9 @@
void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
{
constexpr uint16_t kSetLayerInfoLength = 2;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_LAYER_INFO),
- kSetLayerInfoLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_INFO),
+ kSetLayerInfoLength);
write(type);
write(appId);
endCommand();
@@ -130,10 +137,9 @@
const IVrComposerClient::BufferMetadata& metadata)
{
constexpr uint16_t kSetClientTargetMetadataLength = 7;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
- kSetClientTargetMetadataLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
+ kSetClientTargetMetadataLength);
writeBufferMetadata(metadata);
endCommand();
}
@@ -142,10 +148,9 @@
const IVrComposerClient::BufferMetadata& metadata)
{
constexpr uint16_t kSetLayerBufferMetadataLength = 7;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
- kSetLayerBufferMetadataLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
+ kSetLayerBufferMetadataLength);
writeBufferMetadata(metadata);
endCommand();
}
@@ -182,6 +187,13 @@
LOG_ALWAYS_FATAL("failed to create composer client");
}
+ // 2.2 support is optional
+ sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer);
+ if (composer_2_2 != nullptr) {
+ mClient_2_2 = IComposerClient::castFrom(mClient);
+ LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr, "IComposer 2.2 did not return IComposerClient 2.2");
+ }
+
if (mIsUsingVrComposer) {
sp<IVrComposerClient> vrClient = IVrComposerClient::castFrom(mClient);
if (vrClient == nullptr) {
@@ -451,6 +463,25 @@
return error;
}
+Error Composer::getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) {
+ if (!mClient_2_2) {
+ return Error::UNSUPPORTED;
+ }
+
+ Error error = kDefaultError;
+ mClient_2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outKeys = tmpKeys;
+ });
+
+ return error;
+}
+
Error Composer::getReleaseFences(Display display,
std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
{
@@ -530,7 +561,15 @@
Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
{
- auto ret = mClient->setPowerMode(display, mode);
+ hardware::Return<Error> ret(Error::UNSUPPORTED);
+ if (mClient_2_2) {
+ ret = mClient_2_2->setPowerMode_2_2(display, mode);
+ } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
+ ret = mClient->setPowerMode(display,
+ static_cast<hardware::graphics::composer::V2_1::
+ IComposerClient::PowerMode>(mode));
+ }
+
return unwrapRet(ret);
}
@@ -666,6 +705,44 @@
return Error::NONE;
}
+Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) {
+
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+
+ std::vector<PerFrameMetadata> composerMetadata;
+ if (metadata.validTypes & HdrMetadata::SMPTE2086) {
+ composerMetadata
+ .insert(composerMetadata.end(),
+ {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryRed.x},
+ {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryRed.y},
+ {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryGreen.x},
+ {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryGreen.y},
+ {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryBlue.x},
+ {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryBlue.y},
+ {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x},
+ {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y},
+ {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance},
+ {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}});
+ }
+ if (metadata.validTypes & HdrMetadata::CTA861_3) {
+ composerMetadata.insert(composerMetadata.end(),
+ {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
+ metadata.cta8613.maxContentLightLevel},
+ {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+ metadata.cta8613.maxFrameAverageLightLevel}});
+ }
+
+ mWriter.setPerFrameMetadata(composerMetadata);
+ return Error::NONE;
+}
+
Error Composer::setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame)
{
@@ -810,7 +887,8 @@
mReader.takeErrors();
for (const auto& cmdErr : commandErrors) {
- auto command = mWriter.getCommand(cmdErr.location);
+ auto command =
+ static_cast<IComposerClient::Command>(mWriter.getCommand(cmdErr.location));
if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
command == IComposerClient::Command::PRESENT_DISPLAY ||
@@ -841,7 +919,10 @@
uint16_t length = 0;
while (!isEmpty()) {
- if (!beginCommand(&command, &length)) {
+ auto command_2_1 =
+ reinterpret_cast<hardware::graphics::composer::V2_1::IComposerClient::Command*>(
+ &command);
+ if (!beginCommand(command_2_1, &length)) {
break;
}
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 77675fb..c0373aa 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -24,8 +24,10 @@
#include <vector>
#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
-#include <android/hardware/graphics/composer/2.1/IComposer.h>
-#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
+#include <android/hardware/graphics/composer/2.2/IComposer.h>
+#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <gui/HdrMetadata.h>
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
@@ -42,16 +44,16 @@
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::composer::V2_1::Config;
+using android::hardware::graphics::composer::V2_1::Display;
+using android::hardware::graphics::composer::V2_1::Error;
using android::hardware::graphics::composer::V2_1::IComposer;
using android::hardware::graphics::composer::V2_1::IComposerCallback;
-using android::hardware::graphics::composer::V2_1::IComposerClient;
-using android::hardware::graphics::composer::V2_1::Error;
-using android::hardware::graphics::composer::V2_1::Display;
using android::hardware::graphics::composer::V2_1::Layer;
-using android::hardware::graphics::composer::V2_1::Config;
+using android::hardware::graphics::composer::V2_2::IComposerClient;
-using android::hardware::graphics::composer::V2_1::CommandWriterBase;
-using android::hardware::graphics::composer::V2_1::CommandReaderBase;
+using android::hardware::graphics::composer::V2_2::CommandReaderBase;
+using android::hardware::graphics::composer::V2_2::CommandWriterBase;
using android::hardware::kSynchronizedReadWrite;
using android::hardware::MessageQueue;
@@ -111,6 +113,9 @@
float* outMaxLuminance, float* outMaxAverageLuminance,
float* outMinLuminance) = 0;
+ virtual Error getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
+
virtual Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
std::vector<int>* outReleaseFences) = 0;
@@ -155,6 +160,8 @@
virtual Error setLayerCompositionType(Display display, Layer layer,
IComposerClient::Composition type) = 0;
virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0;
+ virtual Error setLayerHdrMetadata(Display display, Layer layer,
+ const HdrMetadata& metadata) = 0;
virtual Error setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame) = 0;
virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0;
@@ -298,6 +305,9 @@
Error getHdrCapabilities(Display display, std::vector<Hdr>* outTypes, float* outMaxLuminance,
float* outMaxAverageLuminance, float* outMinLuminance) override;
+ Error getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override;
+
Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
std::vector<int>* outReleaseFences) override;
@@ -339,6 +349,7 @@
Error setLayerCompositionType(Display display, Layer layer,
IComposerClient::Composition type) override;
Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override;
+ Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override;
Error setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame) override;
Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
@@ -375,7 +386,8 @@
Error execute();
sp<IComposer> mComposer;
- sp<IComposerClient> mClient;
+ sp<hardware::graphics::composer::V2_1::IComposerClient> mClient;
+ sp<IComposerClient> mClient_2_2;
// 64KiB minus a small space for metadata such as read/write pointers
static constexpr size_t kWriterInitialSize =
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 814b55e..f14c2fe 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -37,6 +37,7 @@
using android::FloatRect;
using android::GraphicBuffer;
using android::HdrCapabilities;
+using android::HdrMetadata;
using android::Rect;
using android::Region;
using android::sp;
@@ -687,8 +688,7 @@
// Layer methods
-Layer::Layer(android::Hwc2::Composer& composer,
- const std::unordered_set<Capability>& capabilities,
+Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
hwc2_display_t displayId, hwc2_layer_t layerId)
: mComposer(composer),
mCapabilities(capabilities),
@@ -788,6 +788,16 @@
return static_cast<Error>(intError);
}
+Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) {
+ if (metadata == mHdrMetadata) {
+ return Error::None;
+ }
+
+ mHdrMetadata = metadata;
+ auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata);
+ return static_cast<Error>(intError);
+}
+
Error Layer::setDisplayFrame(const Rect& frame)
{
Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index aade4e0..e74f00d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -23,8 +23,9 @@
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
-#include <ui/HdrCapabilities.h>
+#include <gui/HdrMetadata.h>
#include <math/mat4.h>
+#include <ui/HdrCapabilities.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
@@ -306,6 +307,7 @@
[[clang::warn_unused_result]] Error setCompositionType(Composition type);
[[clang::warn_unused_result]] Error setDataspace(
android_dataspace_t dataspace);
+ [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata);
[[clang::warn_unused_result]] Error setDisplayFrame(
const android::Rect& frame);
[[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
@@ -329,6 +331,7 @@
hwc2_display_t mDisplayId;
hwc2_layer_t mId;
android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
+ android::HdrMetadata mHdrMetadata;
std::function<void(Layer*)> mLayerDestroyedListener;
};
diff --git a/services/surfaceflinger/tests/unittests/MockComposer.h b/services/surfaceflinger/tests/unittests/MockComposer.h
index 248afcf..acd9b30 100644
--- a/services/surfaceflinger/tests/unittests/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/MockComposer.h
@@ -39,8 +39,8 @@
using android::hardware::graphics::composer::V2_1::Error;
using android::hardware::graphics::composer::V2_1::IComposer;
using android::hardware::graphics::composer::V2_1::IComposerCallback;
-using android::hardware::graphics::composer::V2_1::IComposerClient;
using android::hardware::graphics::composer::V2_1::Layer;
+using android::hardware::graphics::composer::V2_2::IComposerClient;
class Composer : public Hwc2::Composer {
public:
@@ -73,6 +73,8 @@
MOCK_METHOD2(getDisplayType, Error(Display, IComposerClient::DisplayType*));
MOCK_METHOD2(getDozeSupport, Error(Display, bool*));
MOCK_METHOD5(getHdrCapabilities, Error(Display, std::vector<Hdr>*, float*, float*, float*));
+ MOCK_METHOD2(getPerFrameMetadataKeys,
+ Error(Display, std::vector<IComposerClient::PerFrameMetadataKey>*));
MOCK_METHOD3(getReleaseFences, Error(Display, std::vector<Layer>*, std::vector<int>*));
MOCK_METHOD2(presentDisplay, Error(Display, int*));
MOCK_METHOD2(setActiveConfig, Error(Display, Config));
@@ -95,6 +97,7 @@
MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&));
MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition));
MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace));
+ MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&));
MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&));
MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float));
MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*));