Merge "Adding HDR10+ Dynamic Metadata Support"
This commit is contained in:
commit
e089050c92
11 changed files with 501 additions and 7 deletions
|
@ -16,11 +16,20 @@
|
|||
|
||||
package android.hardware.graphics.common@1.2;
|
||||
|
||||
import @1.0::Hdr;
|
||||
import @1.1::BufferUsage;
|
||||
import @1.1::ColorMode;
|
||||
import @1.1::Dataspace;
|
||||
import @1.1::PixelFormat;
|
||||
|
||||
/**
|
||||
* Hdr
|
||||
*/
|
||||
@export(name="android_hdr_v1_2_t", value_prefix="HAL_HDR_")
|
||||
enum Hdr : @1.0::Hdr {
|
||||
HDR10_PLUS = 4,
|
||||
};
|
||||
|
||||
@export(name="android_dataspace_v1_2_t", value_prefix="HAL_DATASPACE_",
|
||||
export_parent="false")
|
||||
enum Dataspace : @1.1::Dataspace {
|
||||
|
|
|
@ -534,6 +534,9 @@ class CommandWriterBase {
|
|||
|
||||
static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
std::unique_ptr<uint32_t[]> mData;
|
||||
uint32_t mDataWritten;
|
||||
|
||||
private:
|
||||
void growData(uint32_t grow) {
|
||||
uint32_t newWritten = mDataWritten + grow;
|
||||
|
@ -558,9 +561,6 @@ class CommandWriterBase {
|
|||
}
|
||||
|
||||
uint32_t mDataMaxSize;
|
||||
std::unique_ptr<uint32_t[]> mData;
|
||||
|
||||
uint32_t mDataWritten;
|
||||
// end offset of the current command
|
||||
uint32_t mCommandEnd;
|
||||
|
||||
|
@ -746,13 +746,14 @@ class CommandReaderBase {
|
|||
return fd;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint32_t[]> mData;
|
||||
uint32_t mDataRead;
|
||||
|
||||
private:
|
||||
std::unique_ptr<CommandQueueType> mQueue;
|
||||
uint32_t mDataMaxSize;
|
||||
std::unique_ptr<uint32_t[]> mData;
|
||||
|
||||
uint32_t mDataSize;
|
||||
uint32_t mDataRead;
|
||||
|
||||
// begin/end offsets of the current command
|
||||
uint32_t mCommandBegin;
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.hardware.graphics.common@1.1::RenderIntent;
|
|||
import android.hardware.graphics.common@1.1::PixelFormat;
|
||||
import android.hardware.graphics.common@1.2::ColorMode;
|
||||
import android.hardware.graphics.common@1.2::Dataspace;
|
||||
import android.hardware.graphics.common@1.2::Hdr;
|
||||
import android.hardware.graphics.composer@2.1::IComposerClient.Command;
|
||||
import @2.2::IComposerClient;
|
||||
import @2.1::Display;
|
||||
|
@ -27,7 +28,7 @@ import @2.1::Error;
|
|||
|
||||
interface IComposerClient extends @2.2::IComposerClient {
|
||||
|
||||
// TODO: Move this enum to LLNDK after we decide where to put graphic types.
|
||||
// Bug: Move this enum to LLNDK after we decide where to put graphic types.
|
||||
/**
|
||||
* Required capabilities which are supported by the display. The
|
||||
* particular set of supported capabilities for a given display may be
|
||||
|
@ -63,6 +64,48 @@ interface IComposerClient extends @2.2::IComposerClient {
|
|||
DOZE = 2,
|
||||
};
|
||||
|
||||
//Bug: Move this enum to LLNDK after we decide where to put graphic types.
|
||||
/**
|
||||
* PerFrameMetadataKey
|
||||
*
|
||||
* A set of PerFrameMetadataKey pertains specifically to blob-formatted
|
||||
* metadata (as opposed to float-valued metadata).
|
||||
* The list of keys that represent blobs are:
|
||||
* 1. HDR10_PLUS_SEI
|
||||
*/
|
||||
enum PerFrameMetadataKey : @2.2::IComposerClient.PerFrameMetadataKey {
|
||||
/**HDR10+ metadata
|
||||
* Specifies a metadata blob adhering to
|
||||
* the ST2094-40 SEI message spec, Version 1.0
|
||||
*/
|
||||
HDR10_PLUS_SEI,
|
||||
};
|
||||
|
||||
/**
|
||||
* PerFrameMetadata
|
||||
* This struct encapsulates float-valued
|
||||
* metadata - key must not be in the list
|
||||
* of keys representing blob-formatted metadata
|
||||
* (see PerFrameMetadataKey)
|
||||
*/
|
||||
struct PerFrameMetadata {
|
||||
PerFrameMetadataKey key;
|
||||
float value;
|
||||
};
|
||||
|
||||
/**
|
||||
* PerFrameMetadataBlob
|
||||
* This struct encapsulates blob
|
||||
* metadata - key must be one of the list of keys
|
||||
* associated with blob-type metadata key
|
||||
* and the blob must adhere to the format specified by
|
||||
* that key (See PerFrameMetadataKey).
|
||||
*/
|
||||
struct PerFrameMetadataBlob {
|
||||
PerFrameMetadataKey key;
|
||||
vec<uint8_t> blob;
|
||||
};
|
||||
|
||||
enum Command : @2.2::IComposerClient.Command {
|
||||
/**
|
||||
* SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
|
||||
|
@ -106,6 +149,22 @@ interface IComposerClient extends @2.2::IComposerClient {
|
|||
* @param matrix is a 4x4 transform matrix (16 floats) as described above.
|
||||
*/
|
||||
SET_LAYER_COLOR_TRANSFORM = 0x40d << @2.1::IComposerClient.Command:OPCODE_SHIFT,
|
||||
|
||||
/* SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
|
||||
*
|
||||
* setLayerPerFrameMetadataBlobs(Display display, Layer layer,
|
||||
* vec<PerFrameMetadataBlob> metadata);
|
||||
*
|
||||
* This command sends metadata that may be used for tone-mapping the
|
||||
* associated layer. The metadata structure follows a {key, blob}
|
||||
* format (see the PerFrameMetadataBlob struct). All keys must be
|
||||
* returned by a prior call to getPerFrameMetadataKeys and must
|
||||
* be part of the list of keys associated with blob-type metadata
|
||||
* (see PerFrameMetadataKey).
|
||||
*
|
||||
* This method may be called every frame.
|
||||
*/
|
||||
SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -399,4 +458,43 @@ interface IComposerClient extends @2.2::IComposerClient {
|
|||
getDisplayCapabilities(Display display)
|
||||
generates (Error error,
|
||||
vec<DisplayCapability> capabilities);
|
||||
|
||||
/**
|
||||
* Returns the PerFrameMetadataKeys that are supported by this device.
|
||||
*
|
||||
* @param display is the display on which to create the layer.
|
||||
* @return keys is the vector of PerFrameMetadataKey keys that are
|
||||
* supported by this device.
|
||||
* @return error is NONE upon success. Otherwise,
|
||||
* UNSUPPORTED if not supported on underlying HAL
|
||||
*/
|
||||
getPerFrameMetadataKeys_2_3(Display display)
|
||||
generates (Error error,
|
||||
vec<PerFrameMetadataKey> keys);
|
||||
|
||||
/**
|
||||
* Returns the high dynamic range (HDR) capabilities of the given display,
|
||||
* which are invariant with regard to the active configuration.
|
||||
*
|
||||
* Displays which are not HDR-capable must return no types.
|
||||
*
|
||||
* @param display is the display to query.
|
||||
* @return error is NONE upon success. Otherwise,
|
||||
* BAD_DISPLAY when an invalid display handle was passed in.
|
||||
* @return types is an array of HDR types, may have 0 elements if the
|
||||
* display is not HDR-capable.
|
||||
* @return maxLuminance is the desired content maximum luminance for this
|
||||
* display in cd/m^2.
|
||||
* @return maxAverageLuminance - the desired content maximum frame-average
|
||||
* luminance for this display in cd/m^2.
|
||||
* @return minLuminance is the desired content minimum luminance for this
|
||||
* display in cd/m^2.
|
||||
*/
|
||||
@callflow(next="*")
|
||||
getHdrCapabilities_2_3(Display display)
|
||||
generates (Error error,
|
||||
vec<Hdr> types,
|
||||
float maxLuminance,
|
||||
float maxAverageLuminance,
|
||||
float minLuminance);
|
||||
};
|
||||
|
|
|
@ -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 @@ using android::hardware::graphics::composer::V2_3::IComposerClient;
|
|||
// 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 @@ class CommandWriterBase : public V2_2::CommandWriterBase {
|
|||
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
|
||||
|
|
|
@ -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 @@ namespace detail {
|
|||
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 @@ class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interfac
|
|||
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 @@ class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interfac
|
|||
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
|
||||
|
|
|
@ -43,6 +43,8 @@ class ComposerCommandEngine : public V2_2::hal::ComposerCommandEngine {
|
|||
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 @@ class ComposerCommandEngine : public V2_2::hal::ComposerCommandEngine {
|
|||
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;
|
||||
|
|
|
@ -29,12 +29,19 @@ using common::V1_1::PixelFormat;
|
|||
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 @@ class ComposerHal : public V2_2::hal::ComposerHal {
|
|||
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 @@ class ComposerHal : public V2_2::hal::ComposerHal {
|
|||
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 @@ class ComposerHal : public V2_2::hal::ComposerHal {
|
|||
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
|
||||
|
|
|
@ -38,6 +38,7 @@ using common::V1_1::PixelFormat;
|
|||
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 @@ using V2_1::Error;
|
|||
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 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
|
|||
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 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
|
|||
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 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
|
|||
&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 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
|
|||
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
|
||||
|
|
|
@ -108,6 +108,33 @@ bool ComposerClient::getClientTargetSupport_2_3(Display display, uint32_t width,
|
|||
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) {
|
||||
|
|
|
@ -36,6 +36,7 @@ using common::V1_1::PixelFormat;
|
|||
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 @@ class ComposerClient : public V2_2::vts::ComposerClient {
|
|||
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;
|
||||
};
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
|
||||
#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
|
||||
#include <composer-vts/2.1/GraphicsComposerCallback.h>
|
||||
#include <composer-vts/2.1/TestCommandReader.h>
|
||||
#include <composer-vts/2.3/ComposerVts.h>
|
||||
#include <mapper-vts/2.0/MapperVts.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
|
@ -33,10 +35,13 @@ namespace V2_3 {
|
|||
namespace vts {
|
||||
namespace {
|
||||
|
||||
using common::V1_0::BufferUsage;
|
||||
using common::V1_1::PixelFormat;
|
||||
using common::V1_1::RenderIntent;
|
||||
using common::V1_2::ColorMode;
|
||||
using common::V1_2::Dataspace;
|
||||
using mapper::V2_0::IMapper;
|
||||
using mapper::V2_0::vts::Gralloc;
|
||||
|
||||
// Test environment for graphics.composer
|
||||
class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
|
||||
|
@ -80,6 +85,8 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
|||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
ASSERT_EQ(0, mReader->mCompositionChanges.size());
|
||||
if (mComposerCallback != nullptr) {
|
||||
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
|
||||
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
|
||||
|
@ -131,6 +138,44 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
|||
}
|
||||
};
|
||||
|
||||
// Tests for IComposerClient::Command.
|
||||
class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
|
||||
|
||||
mWriter = std::make_unique<CommandWriterBase>(1024);
|
||||
mReader = std::make_unique<V2_1::vts::TestCommandReader>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
|
||||
}
|
||||
|
||||
const native_handle_t* allocate() {
|
||||
IMapper::BufferDescriptorInfo info{};
|
||||
info.width = 64;
|
||||
info.height = 64;
|
||||
info.layerCount = 1;
|
||||
info.format = static_cast<common::V1_0::PixelFormat>(PixelFormat::RGBA_8888);
|
||||
info.usage =
|
||||
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
|
||||
|
||||
return mGralloc->allocate(info);
|
||||
}
|
||||
|
||||
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
|
||||
|
||||
std::unique_ptr<CommandWriterBase> mWriter;
|
||||
std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Gralloc> mGralloc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test IComposerClient::getDisplayIdentificationData.
|
||||
*
|
||||
|
@ -151,6 +196,57 @@ TEST_F(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
|
||||
*/
|
||||
TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
|
||||
Layer layer;
|
||||
ASSERT_NO_FATAL_FAILURE(layer =
|
||||
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
|
||||
|
||||
mWriter->selectDisplay(mPrimaryDisplay);
|
||||
mWriter->selectLayer(layer);
|
||||
|
||||
/**
|
||||
* DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
|
||||
* the D65 white point and the SRGB transfer functions.
|
||||
* Rendering Intent: Colorimetric
|
||||
* Primaries:
|
||||
* x y
|
||||
* green 0.265 0.690
|
||||
* blue 0.150 0.060
|
||||
* red 0.680 0.320
|
||||
* white (D65) 0.3127 0.3290
|
||||
*/
|
||||
|
||||
std::vector<IComposerClient::PerFrameMetadata> hidlMetadata;
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_X, 0.3127});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_Y, 0.3290});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_LUMINANCE, 100.0});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MIN_LUMINANCE, 0.1});
|
||||
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
|
||||
hidlMetadata.push_back(
|
||||
{IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
|
||||
mWriter->setLayerPerFrameMetadata(hidlMetadata);
|
||||
execute();
|
||||
|
||||
if (mReader->mErrors.size() == 1 &&
|
||||
static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
|
||||
mReader->mErrors.clear();
|
||||
GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
|
||||
ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
|
||||
}
|
||||
|
||||
/**
|
||||
* TestIComposerClient::getReadbackBufferAttributes_2_3
|
||||
*/
|
||||
|
@ -353,6 +449,13 @@ TEST_F(GraphicsComposerHidlTest, SetLayerColorTransform) {
|
|||
|
||||
mWriter->setLayerColorTransform(matrix.data());
|
||||
execute();
|
||||
|
||||
if (mReader->mErrors.size() == 1 &&
|
||||
static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
|
||||
mReader->mErrors.clear();
|
||||
GTEST_SUCCEED() << "setLayerColorTransform is not supported";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
|
||||
|
@ -444,6 +547,29 @@ TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
|
|||
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
|
||||
}
|
||||
|
||||
TEST_F(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
|
||||
Layer layer;
|
||||
ASSERT_NO_FATAL_FAILURE(layer =
|
||||
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
|
||||
|
||||
mWriter->selectDisplay(mPrimaryDisplay);
|
||||
mWriter->selectLayer(layer);
|
||||
|
||||
std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
|
||||
metadata.push_back(
|
||||
{IComposerClient::PerFrameMetadataKey::HDR10_PLUS_SEI, std::vector<uint8_t>(1, 0xff)});
|
||||
|
||||
mWriter->setLayerPerFrameMetadataBlobs(metadata);
|
||||
execute();
|
||||
|
||||
if (mReader->mErrors.size() == 1 &&
|
||||
static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
|
||||
mReader->mErrors.clear();
|
||||
GTEST_SUCCEED() << "setLayerDynamicPerFrameMetadata is not supported";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace vts
|
||||
} // namespace V2_3
|
||||
|
|
Loading…
Reference in a new issue