Support extended range fp16 ClientTargets in HWC

Introduce the concept of hdrSdrRatio for ClientTargets, so that:

* 1.0 is treated as SDR luminance
* hdrSdrRatio is provided to scale the content into display luminance
  range during composition. That is, 1.0 maps to SDR max, and
  hdrSdrRatio maps to display max luminance

Bug: 236745178
Test: builds
Change-Id: Id82a102eaca82f85bf3982538786dd2ae6cb8e61
This commit is contained in:
Alec Mouri 2023-09-06 02:14:47 +00:00
parent 5e25fb2ac4
commit 8062f1feda
7 changed files with 24 additions and 11 deletions

View file

@ -37,4 +37,5 @@ parcelable ClientTarget {
android.hardware.graphics.composer3.Buffer buffer;
android.hardware.graphics.common.Dataspace dataspace;
android.hardware.graphics.common.Rect[] damage;
float hdrSdrRatio = 1.0f;
}

View file

@ -37,12 +37,12 @@ parcelable DisplayRequest {
long display;
int mask;
android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
const int FLIP_CLIENT_TARGET = (1 << 0);
const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1);
const int FLIP_CLIENT_TARGET = (1 << 0) /* 1 */;
const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1) /* 2 */;
@VintfStability
parcelable LayerRequest {
long layer;
int mask;
const int CLEAR_CLIENT_TARGET = (1 << 0);
const int CLEAR_CLIENT_TARGET = (1 << 0) /* 1 */;
}
}

View file

@ -34,8 +34,8 @@
package android.hardware.graphics.composer3;
@Backing(type="byte") @VintfStability
enum FormatColorComponent {
FORMAT_COMPONENT_0 = (1 << 0),
FORMAT_COMPONENT_1 = (1 << 1),
FORMAT_COMPONENT_2 = (1 << 2),
FORMAT_COMPONENT_3 = (1 << 3),
FORMAT_COMPONENT_0 = (1 << 0) /* 1 */,
FORMAT_COMPONENT_1 = (1 << 1) /* 2 */,
FORMAT_COMPONENT_2 = (1 << 2) /* 4 */,
FORMAT_COMPONENT_3 = (1 << 3) /* 8 */,
}

View file

@ -36,4 +36,14 @@ parcelable ClientTarget {
* The surface damage regions.
*/
Rect[] damage;
/**
* The HDR/SDR ratio.
* Only meaningful for extended_range client targets to communicate the amount of HDR heaedroom
* inside the client target. For floating point client targets, this means that for each color
* channel the maximum SDR luminance is 1.0, and the maximum display relative luminance is
* the hdrSdrRatio.
* Note that this ratio is meant to be >= 1.0.
*/
float hdrSdrRatio = 1.0f;
}

View file

@ -83,11 +83,13 @@ class ComposerClientWriter final {
}
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
float hdrSdrRatio) {
ClientTarget clientTargetCommand;
clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
clientTargetCommand.hdrSdrRatio = hdrSdrRatio;
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
}

View file

@ -500,7 +500,7 @@ TEST_P(GraphicsCompositionTest, ClientComposition) {
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
clientDataspace, std::vector<common::Rect>(1, damage));
clientDataspace, std::vector<common::Rect>(1, damage), 1.f);
layer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);
@ -608,7 +608,7 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
clientDataspace, std::vector<common::Rect>(1, clientFrame));
clientDataspace, std::vector<common::Rect>(1, clientFrame), 1.f);
clientLayer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);

View file

@ -1828,7 +1828,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SetClientTarget) {
auto& writer = getWriter(getPrimaryDisplayId());
writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
Dataspace::UNKNOWN, std::vector<Rect>());
Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
execute();
}