Merge "Add tests for mutable swapchain code" into main
diff --git a/libs/attestation/OWNERS b/libs/attestation/OWNERS
index 4dbb0ea..76811f2 100644
--- a/libs/attestation/OWNERS
+++ b/libs/attestation/OWNERS
@@ -1,2 +1 @@
-chaviw@google.com
-svv@google.com
\ No newline at end of file
+svv@google.com
diff --git a/libs/ui/include_types/ui/HdrRenderTypeUtils.h b/libs/ui/include_types/ui/HdrRenderTypeUtils.h
index 70c50f0..98018d9 100644
--- a/libs/ui/include_types/ui/HdrRenderTypeUtils.h
+++ b/libs/ui/include_types/ui/HdrRenderTypeUtils.h
@@ -36,7 +36,7 @@
*/
inline HdrRenderType getHdrRenderType(ui::Dataspace dataspace,
std::optional<ui::PixelFormat> pixelFormat,
- float hdrSdrRatio = 1.f) {
+ float hdrSdrRatio = 1.f, bool hasHdrMetadata = false) {
const auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
const auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
@@ -49,7 +49,8 @@
HAL_DATASPACE_RANGE_EXTENDED);
if ((dataspace == BT2020_LINEAR_EXT || dataspace == ui::Dataspace::V0_SCRGB) &&
- pixelFormat.has_value() && pixelFormat.value() == ui::PixelFormat::RGBA_FP16) {
+ pixelFormat.has_value() && pixelFormat.value() == ui::PixelFormat::RGBA_FP16 &&
+ hasHdrMetadata) {
return HdrRenderType::GENERIC_HDR;
}
diff --git a/services/gpuservice/vts/OWNERS b/services/gpuservice/vts/OWNERS
index a63de1c..a980866 100644
--- a/services/gpuservice/vts/OWNERS
+++ b/services/gpuservice/vts/OWNERS
@@ -1,8 +1,6 @@
# Bug component: 653544
kocdemir@google.com
paulthomson@google.com
-pbaiget@google.com
lfy@google.com
chrisforbes@google.com
-lpy@google.com
alecmouri@google.com
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index cf2d8c2..b1bbcac 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -369,8 +369,11 @@
layerFEState->buffer->getPixelFormat()))
: std::nullopt;
- auto hdrRenderType =
- getHdrRenderType(outputState.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio);
+ // prefer querying this from gralloc instead to catch 2094-10 metadata
+ const bool hasHdrMetadata = layerFEState->hdrMetadata.validTypes != 0;
+
+ auto hdrRenderType = getHdrRenderType(outputState.dataspace, pixelFormat,
+ layerFEState->desiredHdrSdrRatio, hasHdrMetadata);
// Determine the output dependent dataspace for this layer. If it is
// colorspace agnostic, it just uses the dataspace chosen for the output to
@@ -393,8 +396,8 @@
}
// re-get HdrRenderType after the dataspace gets changed.
- hdrRenderType =
- getHdrRenderType(state.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio);
+ hdrRenderType = getHdrRenderType(state.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio,
+ hasHdrMetadata);
// For hdr content, treat the white point as the display brightness - HDR content should not be
// boosted or dimmed.
@@ -416,12 +419,20 @@
state.dimmingRatio = std::min(idealizedMaxHeadroom / deviceHeadroom, 1.0f);
state.whitePointNits = getOutput().getState().displayBrightnessNits * state.dimmingRatio;
} else {
+ const bool isLayerFp16 = pixelFormat && *pixelFormat == ui::PixelFormat::RGBA_FP16;
float layerBrightnessNits = getOutput().getState().sdrWhitePointNits;
// RANGE_EXTENDED can "self-promote" to HDR, but is still rendered for a particular
// range that we may need to re-adjust to the current display conditions
+ // Do NOT do this when we may render fp16 to an fp16 client target, to avoid applying
+ // and additional gain to the layer. This is because the fp16 client target should
+ // already be adapted to remap 1.0 to the SDR white point in the panel's luminance
+ // space.
if (hdrRenderType == HdrRenderType::DISPLAY_HDR) {
- layerBrightnessNits *= layerFEState->currentHdrSdrRatio;
+ if (!FlagManager::getInstance().fp16_client_target() || !isLayerFp16) {
+ layerBrightnessNits *= layerFEState->currentHdrSdrRatio;
+ }
}
+
state.dimmingRatio =
std::clamp(layerBrightnessNits / getOutput().getState().displayBrightnessNits, 0.f,
1.f);
diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h
index c95c875..c91f1ea 100644
--- a/services/surfaceflinger/tests/TransactionTestHarnesses.h
+++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h
@@ -48,7 +48,11 @@
ui::DisplayMode displayMode;
SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
- const ui::Size& resolution = displayMode.resolution;
+ ui::Size resolution = displayMode.resolution;
+ if (displayState.orientation == ui::Rotation::Rotation90 ||
+ displayState.orientation == ui::Rotation::Rotation270) {
+ std::swap(resolution.width, resolution.height);
+ }
sp<IBinder> vDisplay;
@@ -93,8 +97,8 @@
#else
t.setDisplaySurface(vDisplay, producer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
- t.setDisplayProjection(vDisplay, displayState.orientation,
- Rect(displayState.layerStackSpaceRect), Rect(resolution));
+ t.setDisplayProjection(vDisplay, ui::Rotation::Rotation0, Rect(resolution),
+ Rect(resolution));
t.setDisplayLayerStack(vDisplay, layerStack);
t.setLayerStack(mirrorSc, layerStack);
t.apply();
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index 7f9296f..4322af7 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -114,7 +114,11 @@
// Test instances
TestableSurfaceFlinger mFlinger;
+
sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
+ sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
+ sp<compositionengine::mock::DisplaySurface>::make();
+
sp<GraphicBuffer> mBuffer =
sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
@@ -294,6 +298,7 @@
injector.setSecure(static_cast<bool>(SECURE));
injector.setNativeWindow(test->mNativeWindow);
+ injector.setDisplaySurface(test->mDisplaySurface);
// Creating a DisplayDevice requires getting default dimensions from the
// native window along with some other initial setup.
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index a506873..62f1a52 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -171,16 +171,22 @@
static constexpr DisplayModeId kModeId90{1};
static constexpr DisplayModeId kModeId120{2};
static constexpr DisplayModeId kModeId90_4K{3};
+ static constexpr DisplayModeId kModeId60_8K{4};
static inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz, 0);
static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz, 1);
static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz, 2);
static constexpr ui::Size kResolution4K{3840, 2160};
+ static constexpr ui::Size kResolution8K{7680, 4320};
+
static inline const DisplayModePtr kMode90_4K =
createDisplayMode(kModeId90_4K, 90_Hz, 3, kResolution4K);
+ static inline const DisplayModePtr kMode60_8K =
+ createDisplayMode(kModeId60_8K, 60_Hz, 4, kResolution8K);
- static inline const DisplayModes kModes = makeModes(kMode60, kMode90, kMode120, kMode90_4K);
+ static inline const DisplayModes kModes =
+ makeModes(kMode60, kMode90, kMode120, kMode90_4K, kMode60_8K);
};
void DisplayModeSwitchingTest::setupScheduler(
@@ -326,6 +332,8 @@
}
TEST_F(DisplayModeSwitchingTest, changeResolutionWithoutRefreshRequired) {
+ SET_FLAG_FOR_TEST(flags::synced_resolution_switch, false);
+
EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
EXPECT_EQ(NO_ERROR,
@@ -360,6 +368,44 @@
EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90_4K));
}
+TEST_F(DisplayModeSwitchingTest, changeResolutionSynced) {
+ SET_FLAG_FOR_TEST(flags::synced_resolution_switch, true);
+
+ EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
+
+ // PrimaryDisplayVariant has a 4K size, so switch to 8K.
+ EXPECT_EQ(NO_ERROR,
+ mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
+ mock::createDisplayModeSpecs(kModeId60_8K,
+ 60_Hz)));
+
+ EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K));
+
+ // The mode should not be set until the commit that resizes the display.
+ mFlinger.commit();
+ EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K));
+ mFlinger.commit();
+ EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K));
+
+ // Set the display size to match the resolution.
+ DisplayState state;
+ state.what = DisplayState::eDisplaySizeChanged;
+ state.token = mDisplay->getDisplayToken().promote();
+ state.width = static_cast<uint32_t>(kResolution8K.width);
+ state.height = static_cast<uint32_t>(kResolution8K.height);
+
+ // The next commit should set the mode and resize the framebuffer.
+ const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
+ EXPECT_CALL(*mDisplaySurface, resizeBuffers(kResolution8K));
+ EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId60_8K);
+
+ constexpr bool kModeset = true;
+ mFlinger.setDisplayStateLocked(state);
+ mFlinger.configureAndCommit(kModeset);
+
+ EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60_8K));
+}
+
TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) {
SET_FLAG_FOR_TEST(flags::connected_display, true);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 41f2b6e..8084450 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -337,9 +337,9 @@
mFlinger->configure();
}
- void configureAndCommit() {
+ void configureAndCommit(bool modeset = false) {
configure();
- commitTransactionsLocked(eDisplayTransactionNeeded);
+ commitTransactionsLocked(eDisplayTransactionNeeded, modeset);
}
void commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime,
@@ -429,11 +429,14 @@
dispSurface, producer);
}
- void commitTransactionsLocked(uint32_t transactionFlags) {
+ void commitTransactionsLocked(uint32_t transactionFlags, bool modeset = false) {
Mutex::Autolock lock(mFlinger->mStateLock);
ftl::FakeGuard guard(kMainThreadContext);
mFlinger->processDisplayChangesLocked();
mFlinger->commitTransactionsLocked(transactionFlags);
+ if (modeset) {
+ mFlinger->initiateDisplayModeChanges();
+ }
}
void onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId, DisplayHotplugEvent event) {