Adding HDR10+ Dynamic Metadata Support
Bug: 118343714
Test: build, flash, boot
Test: VtsGraphicsComposerV2_3TargetTest should pass
Change-Id: Iee78818bc2704f4045b62251ea2cc75af72a0609
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 6c95a1f..11863fa 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -26,6 +26,7 @@
#include <android/hardware/graphics/composer/2.3/IComposer.h>
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <limits>
namespace android {
namespace hardware {
@@ -44,6 +45,16 @@
// units of uint32_t's.
class CommandWriterBase : public V2_2::CommandWriterBase {
public:
+ void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
+ beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
+ metadataVec.size() * 2);
+ for (const auto& metadata : metadataVec) {
+ writeSigned(static_cast<int32_t>(metadata.key));
+ writeFloat(metadata.value);
+ }
+ endCommand();
+ }
+
void setLayerDataspace(Dataspace dataspace) {
setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
}
@@ -66,11 +77,59 @@
endCommand();
}
+ void setLayerPerFrameMetadataBlobs(
+ const hidl_vec<IComposerClient::PerFrameMetadataBlob>& metadata) {
+ size_t commandLength = 0;
+
+ if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
+ LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
+ return;
+ }
+
+ // number of blobs
+ commandLength += metadata.size();
+
+ for (auto metadataBlob : metadata) {
+ commandLength += sizeof(int32_t); // key of metadata blob
+ commandLength += 1; // size information of metadata blob
+
+ // metadata content size
+ size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
+ commandLength += metadataSize;
+ commandLength +=
+ (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
+ }
+
+ if (commandLength > std::numeric_limits<uint16_t>::max()) {
+ LOG_FATAL("dynamic metadata size is too large");
+ return;
+ }
+
+ // Blobs are written as:
+ // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
+ uint16_t length = static_cast<uint16_t>(commandLength);
+ beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
+ write(static_cast<uint32_t>(metadata.size()));
+ for (auto metadataBlob : metadata) {
+ writeSigned(static_cast<int32_t>(metadataBlob.key));
+ write(static_cast<uint32_t>(metadataBlob.blob.size()));
+ writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
+ }
+ endCommand();
+ }
+
protected:
void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
V2_2::CommandWriterBase::beginCommand_2_2(
static_cast<V2_2::IComposerClient::Command>(static_cast<int32_t>(command)), length);
}
+
+ void writeBlob(uint32_t length, const unsigned char* blob) {
+ memcpy(&mData[mDataWritten], blob, length);
+ uint32_t numElements = length / 4;
+ mDataWritten += numElements;
+ mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index 69872d2..edc203e 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -21,6 +21,7 @@
#endif
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
+#include <composer-hal/2.2/ComposerResources.h>
#include <composer-hal/2.3/ComposerClient.h>
#include <composer-hal/2.3/ComposerCommandEngine.h>
#include <composer-hal/2.3/ComposerHal.h>
@@ -38,6 +39,14 @@
template <typename Interface, typename Hal>
class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interface, Hal> {
public:
+ Return<void> getPerFrameMetadataKeys_2_3(
+ Display display, IComposerClient::getPerFrameMetadataKeys_2_3_cb hidl_cb) override {
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ Error error = mHal->getPerFrameMetadataKeys_2_3(display, &keys);
+ hidl_cb(error, keys);
+ return Void();
+ }
+
Return<Error> setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
return mHal->setColorMode_2_3(display, mode, intent);
}
@@ -67,6 +76,18 @@
return Void();
}
+ Return<void> getHdrCapabilities_2_3(
+ Display display, IComposerClient::getHdrCapabilities_2_3_cb hidl_cb) override {
+ hidl_vec<Hdr> types;
+ float max_lumi = 0.0f;
+ float max_avg_lumi = 0.0f;
+ float min_lumi = 0.0f;
+ Error err =
+ mHal->getHdrCapabilities_2_3(display, &types, &max_lumi, &max_avg_lumi, &min_lumi);
+ hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+ }
+
Return<Error> getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override {
Error err = mHal->getClientTargetSupport_2_3(display, width, height, format, dataspace);
@@ -151,12 +172,19 @@
return Void();
}
+ protected:
+ std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
+ return std::make_unique<ComposerCommandEngine>(
+ mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
+ }
+
private:
using BaseType2_2 = V2_2::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1::mCommandEngine;
using BaseType2_1::mCommandEngineMutex;
using BaseType2_1::mHal;
+ using BaseType2_1::mResources;
};
} // namespace detail
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
index c3dcbcd..1a40d96 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
@@ -43,6 +43,8 @@
switch (static_cast<IComposerClient::Command>(command)) {
case IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM:
return executeSetLayerColorTransform(length);
+ case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
+ return executeSetLayerPerFrameMetadataBlobs(length);
default:
return BaseType2_2::executeCommand(command, length);
}
@@ -65,6 +67,48 @@
return true;
}
+ bool executeSetLayerPerFrameMetadataBlobs(uint16_t length) {
+ // must have at least one metadata blob
+ // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
+ if (length < 4) {
+ return false;
+ }
+
+ uint32_t numBlobs = read();
+ length--;
+
+ std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
+
+ for (size_t i = 0; i < numBlobs; i++) {
+ IComposerClient::PerFrameMetadataKey key =
+ static_cast<IComposerClient::PerFrameMetadataKey>(readSigned());
+ uint32_t blobSize = read();
+
+ length -= 2;
+
+ if (length * sizeof(uint32_t) < blobSize) {
+ return false;
+ }
+
+ metadata.push_back({key, std::vector<uint8_t>()});
+ IComposerClient::PerFrameMetadataBlob& metadataBlob = metadata.back();
+ metadataBlob.blob.resize(blobSize);
+ readBlob(blobSize, metadataBlob.blob.data());
+ }
+ auto err = mHal->setLayerPerFrameMetadataBlobs(mCurrentDisplay, mCurrentLayer, metadata);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+ return true;
+ }
+
+ void readBlob(uint32_t size, void* blob) {
+ memcpy(blob, &mData[mDataRead], size);
+ uint32_t numElements = size / sizeof(uint32_t);
+ mDataRead += numElements;
+ mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0;
+ }
+
private:
using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
using BaseType2_1::mWriter;
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index c7de848..882621f 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -29,12 +29,19 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
class ComposerHal : public V2_2::hal::ComposerHal {
public:
+ Error getPerFrameMetadataKeys(
+ Display display, std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* outKeys) {
+ return getPerFrameMetadataKeys_2_3(
+ display, reinterpret_cast<std::vector<IComposerClient::PerFrameMetadataKey>*>(outKeys));
+ }
+
Error setColorMode_2_2(Display display, common::V1_1::ColorMode mode,
RenderIntent intent) override {
return setColorMode_2_3(display, static_cast<ColorMode>(mode), intent);
@@ -57,6 +64,24 @@
reinterpret_cast<Dataspace*>(outDataspace));
}
+ Error getHdrCapabilities(Display display, hidl_vec<common::V1_0::Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) override {
+ return getHdrCapabilities_2_3(display, reinterpret_cast<hidl_vec<Hdr>*>(outTypes),
+ outMaxLuminance, outMaxAverageLuminance, outMinLuminance);
+ }
+
+ Error setLayerPerFrameMetadata(
+ Display display, Layer layer,
+ const std::vector<V2_2::IComposerClient::PerFrameMetadata>& metadata) override {
+ return setLayerPerFrameMetadata_2_3(
+ display, layer,
+ reinterpret_cast<const std::vector<IComposerClient::PerFrameMetadata>&>(metadata));
+ }
+
+ virtual Error getPerFrameMetadataKeys_2_3(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
+
virtual Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) = 0;
virtual Error getRenderIntents_2_3(Display display, ColorMode mode,
@@ -68,7 +93,12 @@
PixelFormat format, Dataspace dataspace) = 0;
virtual Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) = 0;
-
+ virtual Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) = 0;
+ virtual Error setLayerPerFrameMetadata_2_3(
+ Display display, Layer layer,
+ const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
virtual Error getDisplayIdentificationData(Display display, uint8_t* outPort,
std::vector<uint8_t>* outData) = 0;
virtual Error setLayerColorTransform(Display display, Layer layer, const float* matrix) = 0;
@@ -86,6 +116,9 @@
hidl_vec<uint64_t>& sampleComponent3) = 0;
virtual Error getDisplayCapabilities(
Display display, hidl_vec<IComposerClient::DisplayCapability>* outCapabilities) = 0;
+ virtual Error setLayerPerFrameMetadataBlobs(
+ Display display, Layer layer,
+ std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) = 0;
};
} // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index f7ce7e8..9fb6d4b 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -38,6 +38,7 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
@@ -45,6 +46,29 @@
template <typename Hal>
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
public:
+ Error getPerFrameMetadataKeys_2_3(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
+ std::vector<V2_2::IComposerClient::PerFrameMetadataKey> castKeys;
+ Error error = getPerFrameMetadataKeys(display, &castKeys);
+ if (error != Error::NONE) {
+ return error;
+ }
+ outKeys->clear();
+ for (auto key : castKeys) {
+ outKeys->push_back(static_cast<IComposerClient::PerFrameMetadataKey>(key));
+ }
+ return Error::NONE;
+ }
+
+ Error setLayerPerFrameMetadata_2_3(
+ Display display, Layer layer,
+ const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
+ return setLayerPerFrameMetadata(
+ display, layer,
+ reinterpret_cast<const std::vector<V2_2::IComposerClient::PerFrameMetadata>&>(
+ metadata));
+ }
+
Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
return setColorMode_2_2(display, static_cast<common::V1_1::ColorMode>(mode), intent);
}
@@ -59,6 +83,12 @@
reinterpret_cast<hidl_vec<common::V1_1::ColorMode>*>(outModes));
}
+ Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes, float* outMaxLuminance,
+ float* outMaxAverageLuminance, float* outMinLuminance) override {
+ return getHdrCapabilities(display, reinterpret_cast<hidl_vec<common::V1_0::Hdr>*>(outTypes),
+ outMaxLuminance, outMaxAverageLuminance, outMinLuminance);
+ }
+
Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override {
return getClientTargetSupport_2_2(display, width, height, format,
@@ -186,6 +216,33 @@
return Error::NONE;
}
+ Error setLayerPerFrameMetadataBlobs(
+ Display display, Layer layer,
+ std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override {
+ if (!mDispatch.setLayerPerFrameMetadataBlobs) {
+ return Error::UNSUPPORTED;
+ }
+
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ std::vector<uint32_t> sizes;
+ std::vector<uint8_t> blobs;
+
+ for (auto metadataBlob : metadata) {
+ keys.push_back(metadataBlob.key);
+ sizes.push_back(metadataBlob.blob.size());
+
+ int writeIndex = blobs.size();
+ blobs.resize(blobs.size() + metadataBlob.blob.size());
+ memcpy(blobs.data() + writeIndex, metadataBlob.blob.data(), metadataBlob.blob.size());
+ }
+
+ int32_t err = mDispatch.setLayerPerFrameMetadataBlobs(
+ mDevice, display, layer, static_cast<uint32_t>(metadata.size()),
+ reinterpret_cast<int32_t*>(keys.data()), reinterpret_cast<uint32_t*>(sizes.data()),
+ blobs.data());
+ return static_cast<Error>(err);
+ }
+
protected:
bool initDispatch() override {
if (!BaseType2_2::initDispatch()) {
@@ -204,6 +261,8 @@
&mDispatch.getDisplayedContentSample);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES,
&mDispatch.getDisplayCapabilities);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
+ &mDispatch.setLayerPerFrameMetadataBlobs);
return true;
}
@@ -215,16 +274,20 @@
HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED setDisplayedContentSamplingEnabled;
HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
+ HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS setLayerPerFrameMetadataBlobs;
} mDispatch = {};
using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
+ using BaseType2_1::getHdrCapabilities;
using BaseType2_1::mDevice;
using BaseType2_2::getClientTargetSupport_2_2;
using BaseType2_2::getColorModes_2_2;
+ using BaseType2_2::getPerFrameMetadataKeys;
using BaseType2_2::getReadbackBufferAttributes;
using BaseType2_2::getRenderIntents;
using BaseType2_2::setColorMode_2_2;
+ using BaseType2_2::setLayerPerFrameMetadata;
};
} // namespace detail
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index c631c50..0e541ed 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -108,6 +108,33 @@
return error == Error::NONE;
}
+std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient::getPerFrameMetadataKeys_2_3(
+ Display display) {
+ std::vector<IComposerClient::PerFrameMetadataKey> keys;
+ mClient->getPerFrameMetadataKeys_2_3(display, [&](const auto& tmpError, const auto& tmpKeys) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get perFrameMetadataKeys";
+ keys = tmpKeys;
+ });
+ return keys;
+}
+
+std::vector<Hdr> ComposerClient::getHdrCapabilities_2_3(Display display, float* outMaxLuminance,
+ float* outMaxAverageLuminance,
+ float* outMinLuminance) {
+ std::vector<Hdr> types;
+ mClient->getHdrCapabilities_2_3(
+ display, [&](const auto& tmpError, const auto& tmpTypes, const auto& tmpMaxLuminance,
+ const auto& tmpMaxAverageLuminance, const auto& tmpMinLuminance) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
+ types = tmpTypes;
+ *outMaxLuminance = tmpMaxLuminance;
+ *outMaxAverageLuminance = tmpMaxAverageLuminance;
+ *outMinLuminance = tmpMinLuminance;
+ });
+
+ return types;
+}
+
Error ComposerClient::getDisplayedContentSamplingAttributes(
uint64_t display, PixelFormat& format, Dataspace& dataspace,
hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) {
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index d3aa779..7add322 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -36,6 +36,7 @@
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
+using common::V1_2::Hdr;
using V2_1::Display;
using V2_1::Error;
using V2_3::IComposer;
@@ -89,10 +90,15 @@
void getReadbackBufferAttributes_2_3(Display display, PixelFormat* outPixelFormat,
Dataspace* outDataspace);
+ std::vector<Hdr> getHdrCapabilities_2_3(Display display, float* outMaxLuminance,
+ float* outMaxAverageLuminance, float* outMinLuminance);
+
bool getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace);
std::vector<IComposerClient::DisplayCapability> getDisplayCapabilities(Display display);
+ std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys_2_3(Display display);
+
private:
const sp<IComposerClient> mClient;
};