summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Courtney Goeltzenleuchter <courtneygo@google.com> 2017-12-19 12:34:34 -0700
committer Chia-I Wu <olv@google.com> 2018-01-04 13:01:35 -0800
commit9bad0d7e726e6b264c528a3dd13d0c58fd92c0e1 (patch)
tree54e7e08b63095230ab9b146c1b1882b3ad7fa15f
parente85d368c4e61b2b8a860d833d28d85e2922396f8 (diff)
Add plumbing for HDR metadata
Allow a ANativeWindow client to send HDR metadata to SurfaceFlinger. The metadata can be queried with BufferLayerConsumer::getCurrentHdrMetadata. Written by Courtney. Updated by olv@. Bug: 63710530 Test: builds Change-Id: I23192d4750950664b57863a533bffd72397255b4
-rw-r--r--libs/gui/Android.bp1
-rw-r--r--libs/gui/BufferItem.cpp9
-rw-r--r--libs/gui/BufferQueueProducer.cpp8
-rw-r--r--libs/gui/HdrMetadata.cpp69
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp17
-rw-r--r--libs/gui/Surface.cpp45
-rw-r--r--libs/gui/include/gui/BufferItem.h5
-rw-r--r--libs/gui/include/gui/HdrMetadata.h43
-rw-r--r--libs/gui/include/gui/IGraphicBufferProducer.h5
-rw-r--r--libs/gui/include/gui/Surface.h11
-rw-r--r--libs/gui/tests/Surface_test.cpp65
-rw-r--r--libs/nativewindow/include/system/window.h38
-rw-r--r--services/surfaceflinger/BufferLayerConsumer.cpp7
-rw-r--r--services/surfaceflinger/BufferLayerConsumer.h9
14 files changed, 325 insertions, 7 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index c713e9e554..7ee4d49f64 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -92,6 +92,7 @@ cc_library_shared {
"FrameTimestamps.cpp",
"GLConsumer.cpp",
"GuiConfig.cpp",
+ "HdrMetadata.cpp",
"IDisplayEventConnection.cpp",
"IConsumerListener.cpp",
"IGraphicBufferConsumer.cpp",
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index 69b5962441..f7409dc344 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -98,6 +98,7 @@ size_t BufferItem::getFlattenedSize() const {
size = FlattenableUtils::align<4>(size);
}
size += mSurfaceDamage.getFlattenedSize();
+ size += mHdrMetadata.getFlattenedSize();
size = FlattenableUtils::align<8>(size);
return size + getPodSize();
}
@@ -151,6 +152,10 @@ status_t BufferItem::flatten(
if (err) return err;
FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+ err = mHdrMetadata.flatten(buffer, size);
+ if (err) return err;
+ FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
+
// Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
@@ -212,6 +217,10 @@ status_t BufferItem::unflatten(
if (err) return err;
FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+ err = mHdrMetadata.unflatten(buffer, size);
+ if (err) return err;
+ FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
+
// Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index c5cab2d730..add857c350 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -765,6 +765,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
&crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
&getFrameTimestamps);
const Region& surfaceDamage = input.getSurfaceDamage();
+ const HdrMetadata& hdrMetadata = input.getHdrMetadata();
if (acquireFence == NULL) {
BQ_LOGE("queueBuffer: fence is NULL");
@@ -825,9 +826,9 @@ status_t BufferQueueProducer::queueBuffer(int slot,
}
BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
- " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
- slot, mCore->mFrameCounter + 1, requestedPresentTimestamp,
- dataSpace, crop.left, crop.top, crop.right, crop.bottom,
+ " validHdrMetadataTypes=0x%x crop=[%d,%d,%d,%d] transform=%#x scale=%s",
+ slot, mCore->mFrameCounter + 1, requestedPresentTimestamp, dataSpace,
+ hdrMetadata.validTypes, crop.left, crop.top, crop.right, crop.bottom,
transform,
BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
@@ -866,6 +867,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
item.mTimestamp = requestedPresentTimestamp;
item.mIsAutoTimestamp = isAutoTimestamp;
item.mDataSpace = dataSpace;
+ item.mHdrMetadata = hdrMetadata;
item.mFrameNumber = currentFrameNumber;
item.mSlot = slot;
item.mFence = acquireFence;
diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp
new file mode 100644
index 0000000000..299bdfa381
--- /dev/null
+++ b/libs/gui/HdrMetadata.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gui/HdrMetadata.h>
+
+namespace android {
+
+size_t HdrMetadata::getFlattenedSize() const {
+ size_t size = sizeof(validTypes);
+ if (validTypes & SMPTE2086) {
+ size += sizeof(smpte2086);
+ }
+ if (validTypes & CTA861_3) {
+ size += sizeof(cta8613);
+ }
+ return size;
+}
+
+status_t HdrMetadata::flatten(void* buffer, size_t size) const {
+ if (size < getFlattenedSize()) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, validTypes);
+ if (validTypes & SMPTE2086) {
+ FlattenableUtils::write(buffer, size, smpte2086);
+ }
+ if (validTypes & CTA861_3) {
+ FlattenableUtils::write(buffer, size, cta8613);
+ }
+
+ return NO_ERROR;
+}
+
+status_t HdrMetadata::unflatten(void const* buffer, size_t size) {
+ if (size < sizeof(validTypes)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, validTypes);
+ if (validTypes & SMPTE2086) {
+ if (size < sizeof(smpte2086)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, smpte2086);
+ }
+ if (validTypes & CTA861_3) {
+ if (size < sizeof(cta8613)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, cta8613);
+ }
+
+ return NO_ERROR;
+}
+
+} // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 71e22cedf0..7e4902405e 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -951,7 +951,8 @@ constexpr size_t IGraphicBufferProducer::QueueBufferInput::minFlattenedSize() {
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
return minFlattenedSize() +
fence->getFlattenedSize() +
- surfaceDamage.getFlattenedSize();
+ surfaceDamage.getFlattenedSize() +
+ hdrMetadata.getFlattenedSize();
}
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
@@ -978,7 +979,12 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
if (result != NO_ERROR) {
return result;
}
- return surfaceDamage.flatten(buffer, size);
+ result = surfaceDamage.flatten(buffer, size);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize());
+ return hdrMetadata.flatten(buffer, size);
}
status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
@@ -1002,7 +1008,12 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
if (result != NO_ERROR) {
return result;
}
- return surfaceDamage.unflatten(buffer, size);
+ result = surfaceDamage.unflatten(buffer, size);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize());
+ return hdrMetadata.unflatten(buffer, size);
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 80216bc63e..a4aec6e6aa 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -667,6 +667,9 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
fence, mStickyTransform, mEnableFrameTimestamps);
+ // we should send HDR metadata as needed if this becomes a bottleneck
+ input.setHdrMetadata(mHdrMetadata);
+
if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
input.setSurfaceDamage(Region::INVALID_REGION);
} else {
@@ -944,6 +947,12 @@ int Surface::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
res = dispatchSetBuffersDataSpace(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA:
+ res = dispatchSetBuffersSmpte2086Metadata(args);
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
+ res = dispatchSetBuffersCta8613Metadata(args);
+ break;
case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
res = dispatchSetSurfaceDamage(args);
break;
@@ -1088,6 +1097,18 @@ int Surface::dispatchSetBuffersDataSpace(va_list args) {
return setBuffersDataSpace(dataspace);
}
+int Surface::dispatchSetBuffersSmpte2086Metadata(va_list args) {
+ const android_smpte2086_metadata* metadata =
+ va_arg(args, const android_smpte2086_metadata*);
+ return setBuffersSmpte2086Metadata(metadata);
+}
+
+int Surface::dispatchSetBuffersCta8613Metadata(va_list args) {
+ const android_cta861_3_metadata* metadata =
+ va_arg(args, const android_cta861_3_metadata*);
+ return setBuffersCta8613Metadata(metadata);
+}
+
int Surface::dispatchSetSurfaceDamage(va_list args) {
android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
size_t numRects = va_arg(args, size_t);
@@ -1512,6 +1533,30 @@ int Surface::setBuffersDataSpace(android_dataspace dataSpace)
return NO_ERROR;
}
+int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) {
+ ALOGV("Surface::setBuffersSmpte2086Metadata");
+ Mutex::Autolock lock(mMutex);
+ if (metadata) {
+ mHdrMetadata.smpte2086 = *metadata;
+ mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
+ } else {
+ mHdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086;
+ }
+ return NO_ERROR;
+}
+
+int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) {
+ ALOGV("Surface::setBuffersCta8613Metadata");
+ Mutex::Autolock lock(mMutex);
+ if (metadata) {
+ mHdrMetadata.cta8613 = *metadata;
+ mHdrMetadata.validTypes |= HdrMetadata::CTA861_3;
+ } else {
+ mHdrMetadata.validTypes &= ~HdrMetadata::CTA861_3;
+ }
+ return NO_ERROR;
+}
+
android_dataspace_t Surface::getBuffersDataSpace() {
ALOGV("Surface::getBuffersDataSpace");
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/include/gui/BufferItem.h b/libs/gui/include/gui/BufferItem.h
index 55637a9be4..7740b9f095 100644
--- a/libs/gui/include/gui/BufferItem.h
+++ b/libs/gui/include/gui/BufferItem.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_GUI_BUFFERITEM_H
#define ANDROID_GUI_BUFFERITEM_H
+#include <gui/HdrMetadata.h>
+
#include <ui/FenceTime.h>
#include <ui/Rect.h>
#include <ui/Region.h>
@@ -86,6 +88,9 @@ class BufferItem : public Flattenable<BufferItem> {
// dataSpace is format-dependent.
android_dataspace mDataSpace;
+ // mHdrMetadata is the HDR metadata associated with this buffer slot.
+ HdrMetadata mHdrMetadata;
+
// mFrameNumber is the number of the queued frame for this slot.
uint64_t mFrameNumber;
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
new file mode 100644
index 0000000000..cd01952005
--- /dev/null
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <system/graphics.h>
+#include <utils/Flattenable.h>
+
+namespace android {
+
+struct HdrMetadata : public LightFlattenable<HdrMetadata> {
+ enum Type : uint32_t {
+ SMPTE2086 = 1 << 0,
+ CTA861_3 = 1 << 1,
+ };
+ uint32_t validTypes{0};
+
+ android_smpte2086_metadata smpte2086{};
+ android_cta861_3_metadata cta8613{};
+
+ // LightFlattenable
+ bool isFixedSize() const { return false; }
+ size_t getFlattenedSize() const;
+ status_t flatten(void* buffer, size_t size) const;
+ status_t unflatten(void const* buffer, size_t size);
+};
+
+} // namespace android
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 039dc0d657..722833eed6 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -31,6 +31,7 @@
#include <ui/Region.h>
#include <gui/FrameTimestamps.h>
+#include <gui/HdrMetadata.h>
#include <hidl/HybridInterface.h>
#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
@@ -354,6 +355,9 @@ public:
const Region& getSurfaceDamage() const { return surfaceDamage; }
void setSurfaceDamage(const Region& damage) { surfaceDamage = damage; }
+ const HdrMetadata& getHdrMetadata() const { return hdrMetadata; }
+ void setHdrMetadata(const HdrMetadata& metadata) { hdrMetadata = metadata; }
+
private:
int64_t timestamp{0};
int isAutoTimestamp{0};
@@ -365,6 +369,7 @@ public:
sp<Fence> fence;
Region surfaceDamage;
bool getFrameTimestamps{false};
+ HdrMetadata hdrMetadata;
};
struct QueueBufferOutput : public Flattenable<QueueBufferOutput> {
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 354f23ab06..641d62cd4d 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -17,8 +17,9 @@
#ifndef ANDROID_GUI_SURFACE_H
#define ANDROID_GUI_SURFACE_H
-#include <gui/IGraphicBufferProducer.h>
#include <gui/BufferQueueDefs.h>
+#include <gui/HdrMetadata.h>
+#include <gui/IGraphicBufferProducer.h>
#include <ui/ANativeObjectBase.h>
#include <ui/Region.h>
@@ -214,6 +215,8 @@ private:
int dispatchUnlockAndPost(va_list args);
int dispatchSetSidebandStream(va_list args);
int dispatchSetBuffersDataSpace(va_list args);
+ int dispatchSetBuffersSmpte2086Metadata(va_list args);
+ int dispatchSetBuffersCta8613Metadata(va_list args);
int dispatchSetSurfaceDamage(va_list args);
int dispatchSetSharedBufferMode(va_list args);
int dispatchSetAutoRefresh(va_list args);
@@ -243,6 +246,8 @@ protected:
virtual int setBuffersStickyTransform(uint32_t transform);
virtual int setBuffersTimestamp(int64_t timestamp);
virtual int setBuffersDataSpace(android_dataspace dataSpace);
+ virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata);
+ virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata);
virtual int setCrop(Rect const* rect);
virtual int setUsage(uint64_t reqUsage);
virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
@@ -339,6 +344,10 @@ protected:
// means that the buffer contains some type of color data.
android_dataspace mDataSpace;
+ // mHdrMetadata is the HDR metadata that will be used for the next buffer
+ // queue operation. There is no HDR metadata by default.
+ HdrMetadata mHdrMetadata;
+
// mCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mCrop;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 470a338639..cd29d4a667 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -47,6 +47,9 @@ using Transaction = SurfaceComposerClient::Transaction;
static bool hasWideColorDisplay =
getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+static bool hasHdrDisplay =
+ getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
+
class FakeSurfaceComposer;
class FakeProducerFrameEventHistory;
@@ -294,6 +297,68 @@ TEST_F(SurfaceTest, GetWideColorSupport) {
ASSERT_EQ(hasWideColorDisplay, supported);
}
+TEST_F(SurfaceTest, GetHdrSupport) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<DummyConsumer> dummyConsumer(new DummyConsumer);
+ consumer->consumerConnect(dummyConsumer, false);
+ consumer->setConsumerName(String8("TestConsumer"));
+
+ sp<Surface> surface = new Surface(producer);
+ sp<ANativeWindow> window(surface);
+ native_window_api_connect(window.get(), NATIVE_WINDOW_API_CPU);
+
+ bool supported;
+ status_t result = surface->getHdrSupport(&supported);
+ ASSERT_EQ(NO_ERROR, result);
+
+ // NOTE: This is not a CTS test.
+ // This test verifies that when the BoardConfig TARGET_HAS_HDR_DISPLAY
+ // is TRUE, getHdrSupport is also true.
+ // TODO: Add check for an HDR color mode on the primary display.
+ ASSERT_EQ(hasHdrDisplay, supported);
+}
+
+TEST_F(SurfaceTest, SetHdrMetadata) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<DummyConsumer> dummyConsumer(new DummyConsumer);
+ consumer->consumerConnect(dummyConsumer, false);
+ consumer->setConsumerName(String8("TestConsumer"));
+
+ sp<Surface> surface = new Surface(producer);
+ sp<ANativeWindow> window(surface);
+ native_window_api_connect(window.get(), NATIVE_WINDOW_API_CPU);
+
+ bool supported;
+ status_t result = surface->getHdrSupport(&supported);
+ ASSERT_EQ(NO_ERROR, result);
+
+ if (!hasHdrDisplay || !supported) {
+ return;
+ }
+ const android_smpte2086_metadata smpte2086 = {
+ {0.680, 0.320},
+ {0.265, 0.690},
+ {0.150, 0.060},
+ {0.3127, 0.3290},
+ 100.0,
+ 0.1,
+ };
+ const android_cta861_3_metadata cta861_3 = {
+ 78.0,
+ 62.0,
+ };
+ int error = native_window_set_buffers_smpte2086_metadata(window.get(), &smpte2086);
+ ASSERT_EQ(error, NO_ERROR);
+ error = native_window_set_buffers_cta861_3_metadata(window.get(), &cta861_3);
+ ASSERT_EQ(error, NO_ERROR);
+}
+
TEST_F(SurfaceTest, DynamicSetBufferCount) {
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 64908049d6..69e0951f89 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -225,6 +225,8 @@ enum {
NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
NATIVE_WINDOW_SET_USAGE64 = 30,
NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
+ NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
+ NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
// clang-format on
};
@@ -700,6 +702,42 @@ static inline int native_window_set_buffers_data_space(
}
/*
+ * native_window_set_buffers_smpte2086_metadata(..., metadata)
+ * All buffers queued after this call will be associated with the SMPTE
+ * ST.2086 metadata specified.
+ *
+ * metadata specifies additional information about the contents of the buffer
+ * that may affect how it's displayed. When it is nullptr, it means no such
+ * information is available. No SMPTE ST.2086 metadata is associated with the
+ * buffers by default.
+ */
+static inline int native_window_set_buffers_smpte2086_metadata(
+ struct ANativeWindow* window,
+ const struct android_smpte2086_metadata* metadata)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA,
+ metadata);
+}
+
+/*
+ * native_window_set_buffers_cta861_3_metadata(..., metadata)
+ * All buffers queued after this call will be associated with the CTA-861.3
+ * metadata specified.
+ *
+ * metadata specifies additional information about the contents of the buffer
+ * that may affect how it's displayed. When it is nullptr, it means no such
+ * information is available. No CTA-861.3 metadata is associated with the
+ * buffers by default.
+ */
+static inline int native_window_set_buffers_cta861_3_metadata(
+ struct ANativeWindow* window,
+ const struct android_cta861_3_metadata* metadata)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA,
+ metadata);
+}
+
+/*
* native_window_set_buffers_transform(..., int transform)
* All buffers queued after this call will be displayed transformed according
* to the transform parameter specified.
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 976dde24ce..bf61236663 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -340,6 +340,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
mCurrentScalingMode = item.mScalingMode;
mCurrentTimestamp = item.mTimestamp;
mCurrentDataSpace = item.mDataSpace;
+ mCurrentHdrMetadata = item.mHdrMetadata;
mCurrentFence = item.mFence;
mCurrentFenceTime = item.mFenceTime;
mCurrentFrameNumber = item.mFrameNumber;
@@ -447,6 +448,12 @@ android_dataspace BufferLayerConsumer::getCurrentDataSpace() {
return mCurrentDataSpace;
}
+const HdrMetadata& BufferLayerConsumer::getCurrentHdrMetadata() const {
+ BLC_LOGV("getCurrentHdrMetadata");
+ Mutex::Autolock lock(mMutex);
+ return mCurrentHdrMetadata;
+}
+
uint64_t BufferLayerConsumer::getFrameNumber() {
BLC_LOGV("getFrameNumber");
Mutex::Autolock lock(mMutex);
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 9b1860833e..51c2b414d7 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -21,6 +21,7 @@
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
+#include <gui/HdrMetadata.h>
#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>
@@ -121,6 +122,10 @@ public:
// set by the most recent call to updateTexImage.
android_dataspace getCurrentDataSpace();
+ // getCurrentHdrMetadata retrieves the HDR metadata associated with the
+ // texture image set by the most recent call to updateTexImage.
+ const HdrMetadata& getCurrentHdrMetadata() const;
+
// getFrameNumber retrieves the frame number associated with the texture
// image set by the most recent call to updateTexImage.
//
@@ -316,6 +321,10 @@ private:
// gets set each time updateTexImage is called.
android_dataspace mCurrentDataSpace;
+ // mCurrentHdrMetadata is the HDR metadata for the current texture. It
+ // gets set each time updateTexImage is called.
+ HdrMetadata mCurrentHdrMetadata;
+
// mCurrentFrameNumber is the frame counter for the current texture.
// It gets set each time updateTexImage is called.
uint64_t mCurrentFrameNumber;