Merge "graphics: add RenderIntent and better HDR support" into pi-dev

This commit is contained in:
Chia-I Wu
2018-04-02 22:22:28 +00:00
committed by Android (Google) Code Review
16 changed files with 594 additions and 60 deletions

View File

@@ -323,9 +323,9 @@ be794f5df97f134d6dcabb866b250d1305100e7ae07fb253b7841df890b931bb android.hardwar
3c5183d7506010be57e0f748e3640fc2ded1ba955784b6256ba427f4c399591c android.hardware.gnss@1.1::IGnssConfiguration
b054af24fbb70d54cde1fb5cba126809e7c4e863e8f9115dc492321dfbcbc993 android.hardware.gnss@1.1::IGnssMeasurement
83e7a10ff3702147bd7ffa04567b20d407a3b16bbb7705644af44d919afe9103 android.hardware.gnss@1.1::IGnssMeasurementCallback
82da7e7624f72ff1927f48738913e20bee3a513adfe5dc7c4f888176e20376e6 android.hardware.graphics.common@1.1::types
0b96e0254e2168cfecb30c1ed5fb42681652cc00faa68c6e07568fafe64d1d50 android.hardware.graphics.common@1.1::types
d9b40a5b09962a5a0780b10fe33a4e607e69e2e088fc83de88a584115b7cb1c0 android.hardware.graphics.composer@2.2::IComposer
d6ce042995239712bc1d0970fa9d512c15c0b1ac9bcb048bd8b69f617b45c25e android.hardware.graphics.composer@2.2::IComposerClient
da3979dd97093cdc4ffc2e2427e848f4ba07ddcd181f31f2cb494ad0d2fa58ad android.hardware.graphics.composer@2.2::IComposerClient
dd83be076b6b3f10ed62ab34d8c8b95f2415961fb785200eb842e7bfb2b0ee92 android.hardware.graphics.mapper@2.1::IMapper
675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback

View File

@@ -15,8 +15,10 @@ hidl_interface {
],
types: [
"BufferUsage",
"ColorMode",
"Dataspace",
"PixelFormat",
"RenderIntent",
],
gen_java: true,
gen_java_constants: true,

View File

@@ -16,9 +16,10 @@
package android.hardware.graphics.common@1.1;
import @1.0::PixelFormat;
import @1.0::BufferUsage;
import @1.0::ColorMode;
import @1.0::Dataspace;
import @1.0::PixelFormat;
/**
* Pixel formats for graphics buffers.
@@ -129,15 +130,165 @@ enum BufferUsage : @1.0::BufferUsage {
@export(name="android_dataspace_v1_1_t", value_prefix="HAL_DATASPACE_",
export_parent="false")
enum Dataspace : @1.0::Dataspace {
/*
* @1.0::Dataspace defines six legacy dataspaces
*
* SRGB_LINEAR = 0x200, // deprecated, use V0_SRGB_LINEAR
* SRGB = 0x201, // deprecated, use V0_SRGB
* JFIF = 0x101, // deprecated, use V0_JFIF
* BT601_625 = 0x102, // deprecated, use V0_BT601_625
* BT601_525 = 0x103, // deprecated, use V0_BT601_525
* BT709 = 0x104, // deprecated, use V0_BT709
*
* The difference between the legacy dataspaces and their modern
* counterparts is that, with legacy dataspaces, the pixel values may have
* been desaturated by the content creator in an unspecified way.
*
* When colorimetric mapping is required, the legacy dataspaces must be
* treated as their modern counterparts (e.g., SRGB must be treated as
* V0_SRGB) and no re-saturation is allowed. When non-colorimetric mapping
* is allowed, the pixel values can be interpreted freely by
* implementations for the purpose of re-saturation, and the re-saturated
* pixel values are in the respective modern dataspaces.
*
* This is also true when UNKNOWN is treated as a legacy dataspace.
*/
/**
* ITU-R Recommendation 2020 (BT.2020)
*
* Ultra High-definition television
*
* Use limited range, SMPTE 2084 (PQ) transfer and BT2020 standard
* limited range is the preferred / normative definition for BT.2020
* Use limited range, BT.709 transfer and BT2020 standard
*/
BT2020_ITU = STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED,
/**
* ITU-R Recommendation 2100 (BT.2100)
*
* High dynamic range television
*
* Use limited/full range, PQ/HLG transfer, and BT2020 standard
* limited range is the preferred / normative definition for BT.2100
*/
BT2020_ITU_PQ = STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED,
BT2020_ITU_HLG = STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED,
BT2020_HLG = STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL,
};
@export(name="android_color_mode_v1_1_t", value_prefix="HAL_COLOR_MODE_",
export_parent="false")
enum ColorMode : @1.0::ColorMode {
/**
* BT2020 corresponds with display settings that implement the ITU-R
* Recommendation BT.2020 / Rec. 2020 for UHDTV.
*
* Primaries:
* x y
* green 0.170 0.797
* blue 0.131 0.046
* red 0.708 0.292
* white (D65) 0.3127 0.3290
*
* Inverse Gamma Correction (IGC): V represents normalized (with [0 to 1]
* range) value of R, G, or B.
*
* if Vnonlinear < b * 4.5
* Vlinear = Vnonlinear / 4.5
* else
* Vlinear = ((Vnonlinear + (a - 1)) / a) ^ (1/0.45)
*
* Gamma Correction (GC):
*
* if Vlinear < b
* Vnonlinear = 4.5 * Vlinear
* else
* Vnonlinear = a * Vlinear ^ 0.45 - (a - 1)
*
* where
*
* a = 1.09929682680944, b = 0.018053968510807
*
* For practical purposes, these a/b values can be used instead
*
* a = 1.099, b = 0.018 for 10-bit display systems
* a = 1.0993, b = 0.0181 for 12-bit display systems
*/
BT2020 = 10,
/**
* BT2100_PQ and BT2100_HLG correspond with display settings that
* implement the ITU-R Recommendation BT.2100 / Rec. 2100 for HDR TV.
*
* Primaries:
* x y
* green 0.170 0.797
* blue 0.131 0.046
* red 0.708 0.292
* white (D65) 0.3127 0.3290
*
* For BT2100_PQ, the transfer function is Perceptual Quantizer (PQ). For
* BT2100_HLG, the transfer function is Hybrid Log-Gamma (HLG).
*/
BT2100_PQ = 11,
BT2100_HLG = 12,
};
/**
* RenderIntent defines the mapping from color mode colors to display colors.
*
* A render intent must not change how it maps colors when the color mode
* changes. That is to say that when a render intent maps color C to color C',
* the fact that color C can have different pixel values in different color
* modes should not affect the mapping.
*
* RenderIntent overrides the render intents defined for individual color
* modes. It is ignored when the color mode is ColorMode::NATIVE, because
* ColorMode::NATIVE colors are already display colors.
*/
@export(name="android_render_intent_v1_1_t", value_prefix="HAL_RENDER_INTENT_",
export_parent="false")
enum RenderIntent : int32_t {
/**
* Colors in the display gamut are unchanged. Colors out of the display
* gamut are hard-clipped.
*
* This implies that the display must have been calibrated unless
* ColorMode::NATIVE is the only supported color mode.
*/
COLORIMETRIC = 0,
/**
* Enhance colors that are in the display gamut. Colors out of the display
* gamut are hard-clipped.
*
* The enhancement typically picks the biggest standard color space (e.g.
* DCI-P3) that is narrower than the display gamut and stretches it to the
* display gamut. The stretching is recommended to preserve skin tones.
*/
ENHANCE = 1,
/**
* Tone map high-dynamic-range colors to the display's dynamic range. The
* dynamic range of the colors are communicated separately. After tone
* mapping, the mapping to the display gamut is as defined in
* COLORIMETRIC.
*/
TONE_MAP_COLORIMETRIC = 2,
/**
* Tone map high-dynamic-range colors to the display's dynamic range. The
* dynamic range of the colors are communicated separately. After tone
* mapping, the mapping to the display gamut is as defined in ENHANCE.
*
* The tone mapping step and the enhancing step must match
* TONE_MAP_COLORIMETRIC and ENHANCE respectively when they are also
* supported.
*/
TONE_MAP_ENHANCE = 3,
/*
* Vendors are recommended to use 0x100 - 0x1FF for their own values, and
* that must be done with subtypes defined by vendor extensions.
*/
};

View File

@@ -12,6 +12,7 @@ hidl_interface {
],
interfaces: [
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.composer@2.1",
"android.hidl.base@1.0",
],

View File

@@ -16,8 +16,10 @@
package android.hardware.graphics.composer@2.2;
import android.hardware.graphics.common@1.0::PixelFormat;
import android.hardware.graphics.common@1.0::Dataspace;
import android.hardware.graphics.common@1.0::PixelFormat;
import android.hardware.graphics.common@1.1::ColorMode;
import android.hardware.graphics.common@1.1::RenderIntent;
import @2.1::IComposerClient;
import @2.1::Display;
import @2.1::Error;
@@ -90,16 +92,20 @@ interface IComposerClient extends @2.1::IComposerClient {
enum Command : @2.1::IComposerClient.Command {
/**
* setPerFrameMetadata(Display display, vec<PerFrameMetadata> data)
* SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
*
* setLayerPerFrameMetadata(Display display, Layer layer,
* vec<PerFrameMetadata> data);
*
* Sets the PerFrameMetadata for the display. This metadata must be used
* by the implementation to better tone map content to that display.
*
* This is a method that may be called every frame. Thus it's
* implemented using buffered transport.
* SET_PER_FRAME_METADATA is the command used by the buffered transport
* SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
* mechanism.
*/
SET_PER_FRAME_METADATA = 0x207 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
SET_LAYER_PER_FRAME_METADATA = 0x303 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
/**
* SET_LAYER_COLOR has this pseudo prototype
@@ -260,4 +266,118 @@ interface IComposerClient extends @2.1::IComposerClient {
*/
setPowerMode_2_2(Display display, PowerMode mode) generates (Error error);
/**
* Returns the color modes supported on this display.
*
* All devices must support at least ColorMode::NATIVE.
*
* @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 modes is an array of color modes.
*/
getColorModes_2_2(Display display)
generates (Error error,
vec<ColorMode> modes);
/**
* Returns the render intents supported by the specified display and color
* mode.
*
* RenderIntent::COLORIMETRIC is always supported.
*
* @param display is the display to query.
* @param mode is the color mode to query.
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_PARAMETER when an invalid color mode was passed in.
* @return intents is an array of render intents.
*/
getRenderIntents(Display display, ColorMode mode)
generates (Error error,
vec<RenderIntent> intents);
/**
* Sets the color mode and render intent of the given display.
*
* The color mode and render intent change must take effect on next
* presentDisplay.
*
* All devices must support at least ColorMode::NATIVE and
* RenderIntent::COLORIMETRIC, and displays are assumed to be in this mode
* upon hotplug.
*
* @param display is the display to which the color mode is set.
* @param mode is the color mode to set to.
* @param intent is the render intent to set to.
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_PARAMETER when mode or intent is invalid
* UNSUPPORTED when mode or intent is not supported on this
* display.
*/
setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent)
generates (Error error);
/*
* By default, layer dataspaces are mapped to the current color mode
* colorimetrically with a few exceptions.
*
* When the layer dataspace is a legacy sRGB dataspace
* (Dataspace::SRGB_LINEAR, Dataspace::SRGB, or Dataspace::UNKNOWN when
* treated as such) and the display render intent is
* RenderIntent::ENHANCE, the pixel values can go through an
* implementation-defined saturation transform before being mapped to the
* current color mode colorimetrically.
*
* Colors that are out of the gamut of the current color mode are
* hard-clipped.
*/
/**
* Returns the saturation matrix of the specified legacy dataspace.
*
* The saturation matrix can be used to approximate the legacy dataspace
* saturation transform. It is to be applied on linear pixel values like
* this:
*
* (in GLSL)
* linearSrgb = clamp(saturationMatrix * linearSrgb, 0.0, 1.0);
*
* @param dataspace must be Dataspace::SRGB_LINEAR.
* @return error is NONE upon success. Otherwise,
* BAD_PARAMETER when an invalid dataspace was passed in.
* @return matrix is the 4x4 column-major matrix used to approximate the
* legacy dataspace saturation operation. The last row must be
* [0.0, 0.0, 0.0, 1.0].
*/
getDataspaceSaturationMatrix(Dataspace dataspace)
generates (Error error,
float[4][4] matrix);
/**
* Executes commands from the input command message queue. Return values
* generated by the input commands are written to the output command
* message queue in the form of value commands.
*
* @param inLength is the length of input commands.
* @param inHandles is an array of handles referenced by the input
* commands.
* @return error is NONE upon success. Otherwise,
* BAD_PARAMETER when inLength is not equal to the length of
* commands in the input command message queue.
* NO_RESOURCES when the output command message queue was not
* properly drained.
* @param outQueueChanged indicates whether the output command message
* queue has changed.
* @param outLength is the length of output commands.
* @param outHandles is an array of handles referenced by the output
* commands.
*/
executeCommands_2_2(uint32_t inLength,
vec<handle> inHandles)
generates (Error error,
bool outQueueChanged,
uint32_t outLength,
vec<handle> outHandles);
};

View File

@@ -1,31 +0,0 @@
cc_binary {
name: "android.hardware.graphics.composer@2.2-service",
defaults: ["hidl_defaults"],
vendor: true,
relative_install_path: "hw",
srcs: ["service.cpp"],
init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
header_libs: [
"android.hardware.graphics.composer@2.2-passthrough",
],
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libbinder",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"libhwc2on1adapter",
"libhwc2onfbadapter",
"liblog",
"libsync",
"libutils",
],
cflags: [
"-DLOG_TAG=\"ComposerHal\""
],
}

View File

@@ -0,0 +1,32 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.graphics.composer@2.2-service
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_CFLAGS := -Wall -Werror -DLOG_TAG=\"ComposerHal\"
LOCAL_SRC_FILES := service.cpp
LOCAL_INIT_RC := android.hardware.graphics.composer@2.2-service.rc
LOCAL_HEADER_LIBRARIES := android.hardware.graphics.composer@2.2-passthrough
LOCAL_SHARED_LIBRARIES := \
android.hardware.graphics.composer@2.1 \
android.hardware.graphics.composer@2.2 \
android.hardware.graphics.mapper@2.0 \
libbase \
libbinder \
libcutils \
libfmq \
libhardware \
libhidlbase \
libhidltransport \
libhwc2on1adapter \
libhwc2onfbadapter \
liblog \
libsync \
libutils
ifdef TARGET_USES_DISPLAY_RENDER_INTENTS
LOCAL_CFLAGS += -DUSES_DISPLAY_RENDER_INTENTS
endif
include $(BUILD_EXECUTABLE)

View File

@@ -72,8 +72,9 @@ class CommandWriterBase : public V2_1::CommandWriterBase {
endCommand();
}
void setPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
beginCommand_2_2(IComposerClient::Command::SET_PER_FRAME_METADATA, metadataVec.size() * 2);
void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
beginCommand_2_2(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);

View File

@@ -103,6 +103,64 @@ class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl<Interfac
return mHal->setPowerMode_2_2(display, mode);
}
Return<void> getColorModes_2_2(Display display,
IComposerClient::getColorModes_2_2_cb hidl_cb) override {
hidl_vec<ColorMode> modes;
Error err = mHal->getColorModes_2_2(display, &modes);
hidl_cb(err, modes);
return Void();
}
Return<void> getRenderIntents(Display display, ColorMode mode,
IComposerClient::getRenderIntents_cb hidl_cb) override {
#ifdef USES_DISPLAY_RENDER_INTENTS
std::vector<RenderIntent> intents;
Error err = mHal->getRenderIntents(display, mode, &intents);
hidl_cb(err, intents);
#else
(void)display;
(void)mode;
hidl_cb(Error::NONE, hidl_vec<RenderIntent>({RenderIntent::COLORIMETRIC}));
#endif
return Void();
}
Return<Error> setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
#ifndef USES_DISPLAY_RENDER_INTENTS
if (intent != RenderIntent::COLORIMETRIC) {
return Error::BAD_PARAMETER;
}
#endif
return mHal->setColorMode_2_2(display, mode, intent);
}
Return<void> getDataspaceSaturationMatrix(
Dataspace dataspace, IComposerClient::getDataspaceSaturationMatrix_cb hidl_cb) override {
if (dataspace != Dataspace::SRGB_LINEAR) {
hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
return Void();
}
hidl_cb(Error::NONE, mHal->getDataspaceSaturationMatrix(dataspace).data());
return Void();
}
Return<void> executeCommands_2_2(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
IComposerClient::executeCommands_2_2_cb hidl_cb) override {
std::lock_guard<std::mutex> lock(mCommandEngineMutex);
bool outChanged = false;
uint32_t outLength = 0;
hidl_vec<hidl_handle> outHandles;
Error error =
mCommandEngine->execute(inLength, inHandles, &outChanged, &outLength, &outHandles);
hidl_cb(error, outChanged, outLength, outHandles);
mCommandEngine->reset();
return Void();
}
protected:
std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
return ComposerResources::create();
@@ -146,6 +204,8 @@ class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl<Interfac
private:
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;
};

View File

@@ -40,8 +40,8 @@ class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
protected:
bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
switch (static_cast<IComposerClient::Command>(command)) {
case IComposerClient::Command::SET_PER_FRAME_METADATA:
return executeSetPerFrameMetadata(length);
case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
return executeSetLayerPerFrameMetadata(length);
case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
return executeSetLayerFloatColor(length);
default:
@@ -49,7 +49,7 @@ class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
}
}
bool executeSetPerFrameMetadata(uint16_t length) {
bool executeSetLayerPerFrameMetadata(uint16_t length) {
// (key, value) pairs
if (length % 2 != 0) {
return false;
@@ -63,7 +63,7 @@ class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
length -= 2;
}
auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
auto err = mHal->setLayerPerFrameMetadata(mCurrentDisplay, mCurrentLayer, metadata);
if (err != Error::NONE) {
mWriter.setError(getCommandLoc(), err);
}

View File

@@ -30,6 +30,8 @@ namespace hal {
using common::V1_0::Dataspace;
using common::V1_0::PixelFormat;
using common::V1_1::ColorMode;
using common::V1_1::RenderIntent;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
@@ -41,10 +43,21 @@ class ComposerHal : public V2_1::hal::ComposerHal {
return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
}
// superceded by getColorModes_2_2
Error getColorModes(Display display, hidl_vec<common::V1_0::ColorMode>* outModes) override {
return getColorModes_2_2(display, reinterpret_cast<hidl_vec<ColorMode>*>(outModes));
}
// superceded by setColorMode_2_2
Error setColorMode(Display display, common::V1_0::ColorMode mode) override {
return setColorMode_2_2(display, static_cast<ColorMode>(mode), RenderIntent::COLORIMETRIC);
}
virtual Error getPerFrameMetadataKeys(
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
virtual Error setPerFrameMetadata(
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
virtual Error setLayerPerFrameMetadata(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) = 0;
@@ -56,6 +69,13 @@ class ComposerHal : public V2_1::hal::ComposerHal {
virtual Error setLayerFloatColor(Display display, Layer layer,
IComposerClient::FloatColor color) = 0;
virtual Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) = 0;
virtual Error getRenderIntents(Display display, ColorMode mode,
std::vector<RenderIntent>* outIntents) = 0;
virtual Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) = 0;
virtual std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) = 0;
};
} // namespace hal

View File

@@ -36,6 +36,8 @@ namespace detail {
using common::V1_0::Dataspace;
using common::V1_0::PixelFormat;
using common::V1_1::ColorMode;
using common::V1_1::RenderIntent;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
@@ -72,9 +74,10 @@ class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
return Error::NONE;
}
Error setPerFrameMetadata(
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
if (!mDispatch.setPerFrameMetadata) {
Error setLayerPerFrameMetadata(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
if (!mDispatch.setLayerPerFrameMetadata) {
return Error::UNSUPPORTED;
}
@@ -87,8 +90,8 @@ class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
values.push_back(m.value);
}
int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
keys.data(), values.data());
int32_t error = mDispatch.setLayerPerFrameMetadata(mDevice, display, layer, metadata.size(),
keys.data(), values.data());
return static_cast<Error>(error);
}
@@ -149,6 +152,69 @@ class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
return static_cast<Error>(error);
}
Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) override {
return getColorModes(display,
reinterpret_cast<hidl_vec<common::V1_0::ColorMode>*>(outModes));
}
Error getRenderIntents(Display display, ColorMode mode,
std::vector<RenderIntent>* outIntents) override {
if (!mDispatch.getRenderIntents) {
*outIntents = std::vector<RenderIntent>({RenderIntent::COLORIMETRIC});
return Error::NONE;
}
uint32_t count = 0;
int32_t error =
mDispatch.getRenderIntents(mDevice, display, int32_t(mode), &count, nullptr);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
std::vector<RenderIntent> intents(count);
error = mDispatch.getRenderIntents(
mDevice, display, int32_t(mode), &count,
reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
intents.resize(count);
*outIntents = std::move(intents);
return Error::NONE;
}
Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
if (!mDispatch.setColorModeWithRenderIntent) {
if (intent != RenderIntent::COLORIMETRIC) {
return Error::UNSUPPORTED;
}
return setColorMode(display, static_cast<common::V1_0::ColorMode>(mode));
}
int32_t err = mDispatch.setColorModeWithRenderIntent(
mDevice, display, static_cast<int32_t>(mode), static_cast<int32_t>(intent));
return static_cast<Error>(err);
}
std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) override {
std::array<float, 16> matrix;
int32_t error = HWC2_ERROR_UNSUPPORTED;
if (mDispatch.getDataspaceSaturationMatrix) {
error = mDispatch.getDataspaceSaturationMatrix(mDevice, static_cast<int32_t>(dataspace),
matrix.data());
}
if (error != HWC2_ERROR_NONE) {
return std::array<float, 16>{
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
};
}
return matrix;
}
protected:
template <typename T>
bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
@@ -168,7 +234,8 @@ class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA,
&mDispatch.setLayerPerFrameMetadata);
initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
&mDispatch.getPerFrameMetadataKeys);
@@ -178,21 +245,32 @@ class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
&mDispatch.getReadbackBufferFence);
initOptionalDispatch(HWC2_FUNCTION_GET_RENDER_INTENTS, &mDispatch.getRenderIntents);
initOptionalDispatch(HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT,
&mDispatch.setColorModeWithRenderIntent);
initOptionalDispatch(HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX,
&mDispatch.getDataspaceSaturationMatrix);
return true;
}
struct {
HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
HWC2_PFN_SET_LAYER_PER_FRAME_METADATA setLayerPerFrameMetadata;
HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
HWC2_PFN_GET_RENDER_INTENTS getRenderIntents;
HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT setColorModeWithRenderIntent;
HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX getDataspaceSaturationMatrix;
} mDispatch = {};
private:
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1::getColorModes;
using BaseType2_1::mDevice;
using BaseType2_1::setColorMode;
using BaseType2_1::setPowerMode;
};

View File

@@ -26,10 +26,17 @@ cc_library_static {
"android.hardware.graphics.composer@2.1-vts",
"android.hardware.graphics.composer@2.2",
],
export_static_lib_headers: [
"android.hardware.graphics.composer@2.1-vts",
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
export_header_lib_headers: [
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
cflags: [
"-O0",
"-g",

View File

@@ -119,6 +119,41 @@ void ComposerClient_v2_2::getReadbackBufferFence(Display display, int32_t* outFe
*outFence = 0;
}
std::vector<ColorMode> ComposerClient_v2_2::getColorModes(Display display) {
std::vector<ColorMode> modes;
mClient_v2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
modes = tmpModes;
});
return modes;
}
std::vector<RenderIntent> ComposerClient_v2_2::getRenderIntents(Display display, ColorMode mode) {
std::vector<RenderIntent> intents;
mClient_v2_2->getRenderIntents(
display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
intents = tmpIntents;
});
return intents;
}
void ComposerClient_v2_2::setColorMode(Display display, ColorMode mode, RenderIntent intent) {
Error error = mClient_v2_2->setColorMode_2_2(display, mode, intent);
ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
}
std::array<float, 16> ComposerClient_v2_2::getDataspaceSaturationMatrix(Dataspace dataspace) {
std::array<float, 16> matrix;
mClient_v2_2->getDataspaceSaturationMatrix(
dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to get datasapce saturation matrix";
std::copy_n(tmpMatrix.data(), matrix.size(), matrix.begin());
});
return matrix;
}
} // namespace vts
} // namespace V2_2
} // namespace composer

View File

@@ -36,10 +36,11 @@ namespace composer {
namespace V2_2 {
namespace vts {
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::Hdr;
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_1::ColorMode;
using android::hardware::graphics::common::V1_1::RenderIntent;
using android::hardware::graphics::composer::V2_2::IComposer;
using android::hardware::graphics::composer::V2_2::IComposerClient;
@@ -72,6 +73,12 @@ class ComposerClient_v2_2
Dataspace* outDataspace);
void getReadbackBufferFence(Display display, int32_t* outFence);
std::vector<ColorMode> getColorModes(Display display);
std::vector<RenderIntent> getRenderIntents(Display display, ColorMode mode);
void setColorMode(Display display, ColorMode mode, RenderIntent intent);
std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace);
private:
sp<V2_2::IComposerClient> mClient_v2_2;
};

View File

@@ -33,11 +33,12 @@ namespace vts {
namespace {
using android::hardware::graphics::common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
using android::hardware::graphics::common::V1_1::ColorMode;
using android::hardware::graphics::common::V1_1::RenderIntent;
using android::hardware::graphics::composer::V2_2::IComposerClient;
using android::hardware::graphics::mapper::V2_0::IMapper;
using android::hardware::graphics::mapper::V2_0::vts::Gralloc;
@@ -146,9 +147,9 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
};
/**
* Test IComposerClient::Command::SET_PER_FRAME_METADATA.
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
*/
TEST_F(GraphicsComposerHidlCommandTest, SET_PER_FRAME_METADATA) {
TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -182,7 +183,7 @@ TEST_F(GraphicsComposerHidlCommandTest, SET_PER_FRAME_METADATA) {
hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
hidlMetadata.push_back(
{IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
mWriter->setPerFrameMetadata(hidlMetadata);
mWriter->setLayerPerFrameMetadata(hidlMetadata);
execute();
}
@@ -235,6 +236,56 @@ TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
mWriter->setLayerFloatColor(IComposerClient::FloatColor{0.0, 0.0, 0.0, 0.0});
}
/**
* Test IComposerClient::getDataspaceSaturationMatrix.
*/
TEST_F(GraphicsComposerHidlTest, getDataspaceSaturationMatrix) {
auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
// the last row is known
ASSERT_EQ(0.0f, matrix[12]);
ASSERT_EQ(0.0f, matrix[13]);
ASSERT_EQ(0.0f, matrix[14]);
ASSERT_EQ(1.0f, matrix[15]);
}
/**
* Test IComposerClient::getColorMode_2_2.
*/
TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
EXPECT_NE(modes.cend(), nativeMode);
}
/**
* Test IComposerClient::getRenderIntent.
*/
TEST_F(GraphicsComposerHidlTest, GetRenderIntent) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
auto colorimetricIntent =
std::find(intents.cbegin(), intents.cend(), RenderIntent::COLORIMETRIC);
EXPECT_NE(intents.cend(), colorimetricIntent);
}
}
/**
* Test IComposerClient::setColorMode_2_2.
*/
TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
for (auto intent : intents) {
mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
}
}
}
} // namespace
} // namespace vts
} // namespace V2_2