blob: 442b603ca0909b536d7d919b33079924345df2c3 [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Brian Lindahl1a4ffd82024-10-30 11:00:37 -060018#include <com_android_graphics_libgui_flags.h>
Alec Mourif97df4d2023-09-06 02:10:05 +000019#include <com_android_graphics_surfaceflinger_flags.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070020#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080022#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070023#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070024#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070025#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080026#include <compositionengine/mock/LayerFE.h>
27#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070028#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000029#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070030#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080031#include <renderengine/ExternalTexture.h>
32#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080033#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070034#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070035#include <ui/Rect.h>
36#include <ui/Region.h>
37
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040038#include <cstdint>
Leon Scroggins III2f60d732022-09-12 14:42:38 -040039#include <variant>
Alec Mouria90a5702021-04-16 16:36:21 +000040
Brian Lindahl1a4ffd82024-10-30 11:00:37 -060041#include <com_android_graphics_surfaceflinger_flags.h>
42
Alec Mourif97df4d2023-09-06 02:10:05 +000043#include <common/FlagManager.h>
44#include <common/test/FlagUtils.h>
Lloyd Pique17ca7422019-11-14 14:24:10 -080045#include "CallOrderStateMachineHelper.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070046#include "RegionMatcher.h"
Lloyd Piquee98286f2024-09-16 16:23:24 -070047#include "mock/DisplayHardware/MockHWC2.h"
Brian Lindahl1a4ffd82024-10-30 11:00:37 -060048#include "mock/DisplayHardware/MockHWComposer.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070049
50namespace android::compositionengine {
51namespace {
52
Alec Mourif97df4d2023-09-06 02:10:05 +000053using namespace com::android::graphics::surfaceflinger;
54
Lloyd Pique56eba802019-08-28 15:45:25 -070055using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080056using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080057using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080058using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080059using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080060using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080061using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080062using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080063using testing::Invoke;
64using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080065using testing::Mock;
Leon Scroggins III2f60d732022-09-12 14:42:38 -040066using testing::NiceMock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080068using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080069using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070070using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070071using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080072using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070073using testing::StrictMock;
74
Lloyd Pique56eba802019-08-28 15:45:25 -070075constexpr auto TR_IDENT = 0u;
76constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080077constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070078
Lloyd Pique3eb1b212019-03-07 21:15:40 -080079const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080080const mat4 kNonIdentityHalf = mat4() * 0.5f;
81const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080082
Lloyd Pique17ca7422019-11-14 14:24:10 -080083constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
84 static_cast<OutputColorSetting>(0x100);
85
Vishnu Nair9cf89262022-02-26 09:17:49 -080086using CompositionStrategyPredictionState = android::compositionengine::impl::
87 OutputCompositionState::CompositionStrategyPredictionState;
88
Lloyd Piquefaa3f192019-11-14 14:05:09 -080089struct OutputPartialMockBase : public impl::Output {
90 // compositionengine::Output overrides
91 const OutputCompositionState& getState() const override { return mState; }
92 OutputCompositionState& editState() override { return mState; }
93
94 // Use mocks for all the remaining virtual functions
95 // not implemented by the base implementation class.
96 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
97 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080098 MOCK_METHOD2(ensureOutputLayer,
99 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800100 MOCK_METHOD0(finalizePendingOutputLayers, void());
101 MOCK_METHOD0(clearOutputLayers, void());
102 MOCK_CONST_METHOD1(dumpState, void(std::string&));
103 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -0800104 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800105 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
106
107 impl::OutputCompositionState mState;
108};
109
Lloyd Piquede196652020-01-22 17:29:58 -0800110struct InjectedLayer {
111 InjectedLayer() {
112 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
113 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
114 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
115
116 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800117 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
118 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800119 }
120
121 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800122 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800123 LayerFECompositionState layerFEState;
124 impl::OutputLayerCompositionState outputLayerState;
125};
126
127struct NonInjectedLayer {
128 NonInjectedLayer() {
129 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
130 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
131 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
132
133 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800134 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
135 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800136 }
137
138 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800139 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800140 LayerFECompositionState layerFEState;
141 impl::OutputLayerCompositionState outputLayerState;
142};
143
Lloyd Pique66d68602019-02-13 14:23:31 -0800144struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700145 class Output : public impl::Output {
146 public:
147 using impl::Output::injectOutputLayerForTest;
148 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
Brian Lindahl1a4ffd82024-10-30 11:00:37 -0600149
150 virtual ftl::Optional<DisplayId> getDisplayId() const override { return mId; }
151
152 virtual bool hasPictureProcessing() const override { return mHasPictureProcessing; }
153 virtual int32_t getMaxLayerPictureProfiles() const override {
154 return mMaxLayerPictureProfiles;
155 }
156
157 void setDisplayIdForTest(DisplayId value) { mId = value; }
158
159 void setHasPictureProcessingForTest(bool value) { mHasPictureProcessing = value; }
160
161 void setMaxLayerPictureProfilesForTest(int32_t value) { mMaxLayerPictureProfiles = value; }
162
163 private:
164 ftl::Optional<DisplayId> mId;
165 bool mHasPictureProcessing;
166 int32_t mMaxLayerPictureProfiles;
Lloyd Pique01c77c12019-04-17 12:48:32 -0700167 };
168
169 static std::shared_ptr<Output> createOutput(
170 const compositionengine::CompositionEngine& compositionEngine) {
171 return impl::createOutputTemplated<Output>(compositionEngine);
172 }
173
Lloyd Pique31cb2942018-10-19 17:23:03 -0700174 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700175 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700176 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700177 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800178
Angel Aguayob084e0c2021-08-04 23:27:28 +0000179 mOutput->editState().displaySpace.setBounds(
180 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700181 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Brian Lindahl1a4ffd82024-10-30 11:00:37 -0600182 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700183 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700184
Lloyd Piquede196652020-01-22 17:29:58 -0800185 void injectOutputLayer(InjectedLayer& layer) {
186 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
187 }
188
189 void injectNullOutputLayer() {
190 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
191 }
192
Lloyd Piqueef958122019-02-05 18:00:12 -0800193 static const Rect kDefaultDisplaySize;
194
Brian Lindahl1a4ffd82024-10-30 11:00:37 -0600195 StrictMock<::android::mock::HWComposer> mHwComposer;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700196 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700197 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700198 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700199 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700200 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201};
202
Lloyd Piqueef958122019-02-05 18:00:12 -0800203const Rect OutputTest::kDefaultDisplaySize{100, 200};
204
Lloyd Pique17ca7422019-11-14 14:24:10 -0800205using ColorProfile = compositionengine::Output::ColorProfile;
206
207void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
Alec Mouri88790f32023-07-21 01:25:14 +0000208 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d]) ", name,
Lloyd Pique17ca7422019-11-14 14:24:10 -0800209 toString(profile.mode).c_str(), profile.mode,
210 toString(profile.dataspace).c_str(), profile.dataspace,
Alec Mouri88790f32023-07-21 01:25:14 +0000211 toString(profile.renderIntent).c_str(), profile.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800212}
213
214// Checks for a ColorProfile match
215MATCHER_P(ColorProfileEq, expected, "") {
216 std::string buf;
217 buf.append("ColorProfiles are not equal\n");
218 dumpColorProfile(expected, buf, "expected value");
219 dumpColorProfile(arg, buf, "actual value");
220 *result_listener << buf;
221
222 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
Alec Mouri88790f32023-07-21 01:25:14 +0000223 (expected.renderIntent == arg.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800224}
225
Lloyd Pique66d68602019-02-13 14:23:31 -0800226/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227 * Basic construction
228 */
229
Lloyd Pique31cb2942018-10-19 17:23:03 -0700230TEST_F(OutputTest, canInstantiateOutput) {
231 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700232 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700233 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700236
237 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700239
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700240 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
241
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700243}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Lloyd Pique66d68602019-02-13 14:23:31 -0800245/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246 * Output::setCompositionEnabled()
247 */
248
249TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700250 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700251
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700252 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700253
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700254 EXPECT_TRUE(mOutput->getState().isEnabled);
255 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700256}
257
258TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700259 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700260
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700261 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700262
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700263 EXPECT_TRUE(mOutput->getState().isEnabled);
264 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700265}
266
267TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700268 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700269
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700270 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700271
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700272 EXPECT_FALSE(mOutput->getState().isEnabled);
273 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700274}
275
Lloyd Pique66d68602019-02-13 14:23:31 -0800276/*
Alec Mouridda07d92022-04-25 22:39:25 +0000277 * Output::setTreat170mAsSrgb()
278 */
279
280TEST_F(OutputTest, setTreat170mAsSrgb) {
281 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
282
283 mOutput->setTreat170mAsSrgb(true);
284 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
285
286 mOutput->setTreat170mAsSrgb(false);
287 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
288}
289
290/*
Alec Mouri023c1882021-05-08 16:36:33 -0700291 * Output::setLayerCachingEnabled()
292 */
293
294TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
295 const auto kSize = ui::Size(1, 1);
296 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
297 mOutput->setLayerCachingEnabled(false);
298 mOutput->setLayerCachingEnabled(true);
299
300 EXPECT_TRUE(mOutput->plannerEnabled());
301}
302
303TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
304 const auto kSize = ui::Size(1, 1);
305 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
306 mOutput->setLayerCachingEnabled(true);
307 mOutput->setLayerCachingEnabled(false);
308
309 EXPECT_FALSE(mOutput->plannerEnabled());
310}
311
Alec Mouric773472b2021-05-19 14:29:05 -0700312TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
313 renderengine::mock::RenderEngine renderEngine;
314 const auto kSize = ui::Size(1, 1);
315 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
316 mOutput->setLayerCachingEnabled(true);
317
318 // Inject some layers
319 InjectedLayer layer;
320 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800321 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700322 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800323 renderengine::impl::ExternalTexture::Usage::READABLE |
324 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700325 injectOutputLayer(layer);
326 // inject a null layer to check for null exceptions
327 injectNullOutputLayer();
328
329 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
330 mOutput->setLayerCachingEnabled(false);
331 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
332}
333
Alec Mouri023c1882021-05-08 16:36:33 -0700334/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700335 * Output::setProjection()
336 */
337
Marin Shalamanov209ae612020-10-01 00:17:39 +0200338TEST_F(OutputTest, setProjectionWorks) {
339 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000340 mOutput->editState().displaySpace.setBounds(
341 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
342 mOutput->editState().framebufferSpace.setBounds(
343 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200344
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200345 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200346 const Rect frame{50, 60, 100, 100};
347 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700348
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200349 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700350
Angel Aguayob084e0c2021-08-04 23:27:28 +0000351 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
352 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
353 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200354
355 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000356 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
357 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
358 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200359
Angel Aguayob084e0c2021-08-04 23:27:28 +0000360 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
361 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
362 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200363
Angel Aguayob084e0c2021-08-04 23:27:28 +0000364 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
365 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
366 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200367
Angel Aguayob084e0c2021-08-04 23:27:28 +0000368 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
369 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
370 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200371
Angel Aguayob084e0c2021-08-04 23:27:28 +0000372 EXPECT_EQ(state.displaySpace.getContent(),
373 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700374
375 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200376}
377
378TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
379 const Rect displayRect{0, 0, 1000, 2000};
380 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000381 mOutput->editState().displaySpace.setBounds(
382 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
383 mOutput->editState().framebufferSpace.setBounds(
384 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200385
386 const ui::Rotation orientation = ui::ROTATION_90;
387 const Rect frame{50, 60, 100, 100};
388 const Rect viewport{10, 20, 30, 40};
389
390 mOutput->setProjection(orientation, viewport, frame);
391
Angel Aguayob084e0c2021-08-04 23:27:28 +0000392 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
393 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
394 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200395
396 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000397 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
398 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
399 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200400
Angel Aguayob084e0c2021-08-04 23:27:28 +0000401 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
402 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
403 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200404
Angel Aguayob084e0c2021-08-04 23:27:28 +0000405 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
406 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
407 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
410 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
411 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200412
Angel Aguayob084e0c2021-08-04 23:27:28 +0000413 EXPECT_EQ(state.displaySpace.getContent(),
414 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415}
416
Lloyd Pique66d68602019-02-13 14:23:31 -0800417/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200418 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419 */
420
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200421TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000422 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
423 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
424 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
425 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
426 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
427 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
428 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
429 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
430 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
431 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700432
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200433 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700434
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200435 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200437 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700438
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200439 const auto state = mOutput->getState();
440
441 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000442 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
443 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
444 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200445
Angel Aguayob084e0c2021-08-04 23:27:28 +0000446 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
447 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200448
Angel Aguayob084e0c2021-08-04 23:27:28 +0000449 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
450 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200451
Angel Aguayob084e0c2021-08-04 23:27:28 +0000452 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
453 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200454
Angel Aguayob084e0c2021-08-04 23:27:28 +0000455 EXPECT_EQ(state.displaySpace.getContent(),
456 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200457
458 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459}
460
Lloyd Pique66d68602019-02-13 14:23:31 -0800461/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700462 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700463 */
464
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700465TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
466 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
467 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700468
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700469 const auto& state = mOutput->getState();
470 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
471 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700472
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700473 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700474}
475
Lloyd Pique66d68602019-02-13 14:23:31 -0800476/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700477 * Output::setColorTransform
478 */
479
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700482
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483 // If no colorTransformMatrix is set the update should be skipped.
484 CompositionRefreshArgs refreshArgs;
485 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700486
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700488
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800491
492 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494}
Lloyd Piqueef958122019-02-05 18:00:12 -0800495
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700498
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499 // Attempting to set the same colorTransformMatrix that is already set should
500 // also skip the update.
501 CompositionRefreshArgs refreshArgs;
502 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700503
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700504 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700505
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800506 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700507 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800508
509 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700510 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800511}
512
513TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800515
516 // Setting a different colorTransformMatrix should perform the update.
517 CompositionRefreshArgs refreshArgs;
518 refreshArgs.colorTransformMatrix = kIdentity;
519
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700520 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800521
522 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700523 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800524
525 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800527}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700528
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800529TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700530 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700531
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800532 // Setting a different colorTransformMatrix should perform the update.
533 CompositionRefreshArgs refreshArgs;
534 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700535
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700536 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800537
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800538 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700539 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800540
541 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800543}
544
545TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700546 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800547
548 // Setting a different colorTransformMatrix should perform the update.
549 CompositionRefreshArgs refreshArgs;
550 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
551
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700552 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800553
554 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700555 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800556
557 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700559}
560
Lloyd Pique66d68602019-02-13 14:23:31 -0800561/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800562 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700563 */
564
Lloyd Pique17ca7422019-11-14 14:24:10 -0800565using OutputSetColorProfileTest = OutputTest;
566
567TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800568 using ColorProfile = Output::ColorProfile;
569
Lloyd Piqueef958122019-02-05 18:00:12 -0800570 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700571
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700572 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000573 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
576 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
577 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800578
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700579 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800580}
581
Lloyd Pique17ca7422019-11-14 14:24:10 -0800582TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800583 using ColorProfile = Output::ColorProfile;
584
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700585 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
586 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
587 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piqueef958122019-02-05 18:00:12 -0800588
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700589 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000590 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Piqueef958122019-02-05 18:00:12 -0800591
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700592 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700593}
594
Lloyd Pique66d68602019-02-13 14:23:31 -0800595/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700596 * Output::setRenderSurface()
597 */
598
599TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
600 const ui::Size newDisplaySize{640, 480};
601
602 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
603 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
604
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700605 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700606
Angel Aguayob084e0c2021-08-04 23:27:28 +0000607 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700608}
609
Alec Mouricdf16792021-12-10 13:16:06 -0800610/**
611 * Output::setDisplayBrightness()
612 */
613
614TEST_F(OutputTest, setNextBrightness) {
615 constexpr float kDisplayBrightness = 0.5f;
616 mOutput->setNextBrightness(kDisplayBrightness);
617 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
618 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
619}
620
Lloyd Pique66d68602019-02-13 14:23:31 -0800621/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000622 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700623 */
624
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700625TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000626 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000627 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700628 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700629
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700630 // The dirty region should be clipped to the display bounds.
631 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700632}
633
Lloyd Pique66d68602019-02-13 14:23:31 -0800634/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800636 */
637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638TEST_F(OutputTest, layerFiltering) {
639 const ui::LayerStack layerStack1{123u};
640 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // If the output is associated to layerStack1 and to an internal display...
643 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 // It excludes layers with no layer stack, internal-only or not.
646 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
647 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800648
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700649 // It includes layers on layerStack1, internal-only or not.
650 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
651 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
652 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
653 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800654
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700655 // If the output is associated to layerStack1 but not to an internal display...
656 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 // It includes layers on layerStack1, unless they are internal-only.
659 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
660 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
661 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
662 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800663}
664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800666 NonInjectedLayer layer;
667 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800668
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700669 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800670 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800672}
673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800675 NonInjectedLayer layer;
676 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700678 const ui::LayerStack layerStack1{123u};
679 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 // If the output is associated to layerStack1 and to an internal display...
682 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 // It excludes layers with no layer stack, internal-only or not.
685 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
686 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800687
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700688 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
689 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800690
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700691 // It includes layers on layerStack1, internal-only or not.
692 layer.layerFEState.outputFilter = {layerStack1, false};
693 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800694
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700695 layer.layerFEState.outputFilter = {layerStack1, true};
696 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800697
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700698 layer.layerFEState.outputFilter = {layerStack2, true};
699 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800700
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700701 layer.layerFEState.outputFilter = {layerStack2, false};
702 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800703
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700704 // If the output is associated to layerStack1 but not to an internal display...
705 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800706
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700707 // It includes layers on layerStack1, unless they are internal-only.
708 layer.layerFEState.outputFilter = {layerStack1, false};
709 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800710
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700711 layer.layerFEState.outputFilter = {layerStack1, true};
712 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800713
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700714 layer.layerFEState.outputFilter = {layerStack2, true};
715 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800716
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700717 layer.layerFEState.outputFilter = {layerStack2, false};
718 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800719}
720
Lloyd Pique66d68602019-02-13 14:23:31 -0800721/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800722 * Output::getOutputLayerForLayer()
723 */
724
725TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800726 InjectedLayer layer1;
727 InjectedLayer layer2;
728 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800729
Lloyd Piquede196652020-01-22 17:29:58 -0800730 injectOutputLayer(layer1);
731 injectNullOutputLayer();
732 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800733
734 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800735 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
736 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800737
738 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800739 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
740 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
741 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800742
743 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800744 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
745 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
746 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800747}
748
Lloyd Pique66d68602019-02-13 14:23:31 -0800749/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800750 * Output::setReleasedLayers()
751 */
752
753using OutputSetReleasedLayersTest = OutputTest;
754
755TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800756 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
757 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
758 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800759
760 Output::ReleasedLayers layers;
761 layers.push_back(layer1FE);
762 layers.push_back(layer2FE);
763 layers.push_back(layer3FE);
764
765 mOutput->setReleasedLayers(std::move(layers));
766
767 const auto& setLayers = mOutput->getReleasedLayersForTest();
768 ASSERT_EQ(3u, setLayers.size());
769 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
770 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
771 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
772}
773
774/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800775 * Output::updateAndWriteCompositionState()
776 */
777
Lloyd Piquede196652020-01-22 17:29:58 -0800778using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800779
780TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
781 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800782
783 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800784 mOutput->updateCompositionState(args);
785 mOutput->planComposition();
786 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800787}
788
Lloyd Piqueef63b612019-11-14 13:19:56 -0800789TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800790 InjectedLayer layer1;
791 InjectedLayer layer2;
792 InjectedLayer layer3;
793
Lloyd Piqueef63b612019-11-14 13:19:56 -0800794 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800795
Lloyd Piquede196652020-01-22 17:29:58 -0800796 injectOutputLayer(layer1);
797 injectOutputLayer(layer2);
798 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800799
800 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800801 mOutput->updateCompositionState(args);
802 mOutput->planComposition();
803 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800804}
805
806TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800807 InjectedLayer layer1;
808 InjectedLayer layer2;
809 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800810
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400811 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700812 EXPECT_CALL(*layer1.outputLayer,
813 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800814 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400815 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
816 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000817 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700818 EXPECT_CALL(*layer2.outputLayer,
819 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800820 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400821 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
822 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000823 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700824 EXPECT_CALL(*layer3.outputLayer,
825 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800826 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400827 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
828 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000829 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800830
831 injectOutputLayer(layer1);
832 injectOutputLayer(layer2);
833 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800834
835 mOutput->editState().isEnabled = true;
836
837 CompositionRefreshArgs args;
838 args.updatingGeometryThisFrame = false;
839 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800841 mOutput->updateCompositionState(args);
842 mOutput->planComposition();
843 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800844}
845
846TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800847 InjectedLayer layer1;
848 InjectedLayer layer2;
849 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800850
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400851 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700852 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800853 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400854 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
855 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000856 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700857 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800858 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400859 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
860 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000861 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700862 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800863 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400864 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000866 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800867
868 injectOutputLayer(layer1);
869 injectOutputLayer(layer2);
870 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800871
872 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800873
874 CompositionRefreshArgs args;
875 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800876 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800877 mOutput->updateCompositionState(args);
878 mOutput->planComposition();
879 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800880}
881
882TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800883 InjectedLayer layer1;
884 InjectedLayer layer2;
885 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800886
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400887 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700888 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800889 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400890 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
891 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000892 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700893 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800894 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400895 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
896 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000897 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700898 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800899 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400900 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
901 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000902 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800903
904 injectOutputLayer(layer1);
905 injectOutputLayer(layer2);
906 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800907
908 mOutput->editState().isEnabled = true;
909
910 CompositionRefreshArgs args;
911 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800912 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800913 mOutput->updateCompositionState(args);
914 mOutput->planComposition();
915 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800916}
917
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400918TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
919 renderengine::mock::RenderEngine renderEngine;
920 InjectedLayer layer0;
921 InjectedLayer layer1;
922 InjectedLayer layer2;
923 InjectedLayer layer3;
924
925 InSequence seq;
Sally Qi0abc4a52024-09-26 16:13:06 -0700926 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
927 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000928 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700929 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
930 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400931
932 uint32_t z = 0;
933 EXPECT_CALL(*layer0.outputLayer,
934 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
935 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000936 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400937
938 // After calling planComposition (which clears overrideInfo), this test sets
939 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
940 // comes first, setting isPeekingThrough to true and zIsOverridden to true
941 // for it and the following layers.
942 EXPECT_CALL(*layer3.outputLayer,
943 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
944 /*zIsOverridden*/ true, /*isPeekingThrough*/
945 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000946 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400947 EXPECT_CALL(*layer1.outputLayer,
948 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
949 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000950 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400951 EXPECT_CALL(*layer2.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000954 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400955
956 injectOutputLayer(layer0);
957 injectOutputLayer(layer1);
958 injectOutputLayer(layer2);
959 injectOutputLayer(layer3);
960
961 mOutput->editState().isEnabled = true;
962
963 CompositionRefreshArgs args;
964 args.updatingGeometryThisFrame = true;
965 args.devOptForceClientComposition = false;
966 mOutput->updateCompositionState(args);
967 mOutput->planComposition();
968
969 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800970 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700971 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800972 renderengine::impl::ExternalTexture::Usage::READABLE |
973 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400974 layer1.outputLayerState.overrideInfo.buffer = buffer;
975 layer2.outputLayerState.overrideInfo.buffer = buffer;
976 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
977 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
978
979 mOutput->writeCompositionState(args);
980}
981
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800982/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800983 * Output::prepareFrame()
984 */
985
986struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800987 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800988 // Sets up the helper functions called by the function under test to use
989 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800990 MOCK_METHOD1(chooseCompositionStrategy,
991 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
992 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800993 };
994
995 OutputPrepareFrameTest() {
996 mOutput.setDisplayColorProfileForTest(
997 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
998 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
999 }
1000
1001 StrictMock<mock::CompositionEngine> mCompositionEngine;
1002 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1003 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001004 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001005};
1006
1007TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1008 mOutput.editState().isEnabled = false;
1009
1010 mOutput.prepareFrame();
1011}
1012
1013TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1014 mOutput.editState().isEnabled = true;
1015 mOutput.editState().usesClientComposition = false;
1016 mOutput.editState().usesDeviceComposition = true;
1017
Vishnu Naira3140382022-02-24 14:07:11 -08001018 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1019 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001020 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001021 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1022
1023 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001024 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001025}
1026
1027// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1028// base chooseCompositionStrategy() is invoked.
1029TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001030 mOutput->editState().isEnabled = true;
1031 mOutput->editState().usesClientComposition = false;
1032 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001033
1034 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1035
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001037
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001038 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1039 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001040 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001041}
1042
Vishnu Naira3140382022-02-24 14:07:11 -08001043struct OutputPrepareFrameAsyncTest : public testing::Test {
1044 struct OutputPartialMock : public OutputPartialMockBase {
1045 // Sets up the helper functions called by the function under test to use
1046 // mock implementations.
1047 MOCK_METHOD1(chooseCompositionStrategy,
1048 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1049 MOCK_METHOD0(updateProtectedContentState, void());
1050 MOCK_METHOD2(dequeueRenderBuffer,
1051 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1052 MOCK_METHOD1(
1053 chooseCompositionStrategyAsync,
1054 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001055 MOCK_METHOD3(composeSurfaces,
1056 std::optional<base::unique_fd>(const Region&,
1057 std::shared_ptr<renderengine::ExternalTexture>,
1058 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001059 MOCK_METHOD0(resetCompositionStrategy, void());
1060 };
1061
1062 OutputPrepareFrameAsyncTest() {
1063 mOutput.setDisplayColorProfileForTest(
1064 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1065 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1066 }
1067
1068 StrictMock<mock::CompositionEngine> mCompositionEngine;
1069 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1070 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1071 StrictMock<OutputPartialMock> mOutput;
1072 CompositionRefreshArgs mRefreshArgs;
1073};
1074
1075TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1076 mOutput.editState().isEnabled = true;
1077 mOutput.editState().usesClientComposition = false;
1078 mOutput.editState().usesDeviceComposition = true;
1079 mOutput.editState().previousDeviceRequestedChanges =
1080 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1081 std::promise<bool> p;
1082 p.set_value(true);
1083
1084 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1085 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1086 EXPECT_CALL(mOutput, updateProtectedContentState());
1087 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1088 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1089 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1090 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1091 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001092 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001093
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001094 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001095 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001096 EXPECT_FALSE(result.bufferAvailable());
1097}
1098
1099TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1100 mOutput.editState().isEnabled = true;
1101 mOutput.editState().usesClientComposition = false;
1102 mOutput.editState().usesDeviceComposition = true;
1103 mOutput.editState().previousDeviceRequestedChanges =
1104 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1105 std::promise<bool> p;
1106 p.set_value(true);
1107
1108 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1109 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1110 EXPECT_CALL(mOutput, updateProtectedContentState());
1111 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1112 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1113 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1114 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1115 Return(ByMove(p.get_future()))));
1116
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001117 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001118 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001119 EXPECT_FALSE(result.bufferAvailable());
1120}
1121
1122// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1123// client composition
1124TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1125 mOutput.editState().isEnabled = true;
1126 mOutput.editState().usesClientComposition = false;
1127 mOutput.editState().usesDeviceComposition = true;
1128 mOutput.editState().previousDeviceRequestedChanges =
1129 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1130 std::promise<bool> p;
1131 p.set_value(false);
1132 std::shared_ptr<renderengine::ExternalTexture> tex =
1133 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1134 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1135 2);
1136 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1137 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1138 EXPECT_CALL(mOutput, updateProtectedContentState());
1139 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1140 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1141 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1142 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1143 return p.get_future();
1144 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001145 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001146
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001147 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001148 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001149 EXPECT_TRUE(result.bufferAvailable());
1150}
1151
1152TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1153 mOutput.editState().isEnabled = true;
1154 mOutput.editState().usesClientComposition = false;
1155 mOutput.editState().usesDeviceComposition = true;
1156 mOutput.editState().previousDeviceRequestedChanges =
1157 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1158 auto newDeviceRequestedChanges =
1159 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1160 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1161 std::promise<bool> p;
1162 p.set_value(false);
1163 std::shared_ptr<renderengine::ExternalTexture> tex =
1164 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1165 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1166 2);
1167
1168 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1169 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1170 EXPECT_CALL(mOutput, updateProtectedContentState());
1171 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1172 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1173 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1174 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1175 return p.get_future();
1176 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001177 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001178
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001179 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001180 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001181 EXPECT_TRUE(result.bufferAvailable());
1182}
1183
Lloyd Pique56eba802019-08-28 15:45:25 -07001184/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001185 * Output::prepare()
1186 */
1187
1188struct OutputPrepareTest : public testing::Test {
1189 struct OutputPartialMock : public OutputPartialMockBase {
1190 // Sets up the helper functions called by the function under test to use
1191 // mock implementations.
1192 MOCK_METHOD2(rebuildLayerStacks,
1193 void(const compositionengine::CompositionRefreshArgs&,
1194 compositionengine::LayerFESet&));
1195 };
1196
Brian Lindahl439afad2022-11-14 11:16:55 -07001197 OutputPrepareTest() {
1198 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1199 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1200 .WillRepeatedly(Return(&mLayer1.outputLayer));
1201 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1202 .WillRepeatedly(Return(&mLayer2.outputLayer));
1203
1204 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1205 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1206 }
1207
1208 struct Layer {
1209 StrictMock<mock::OutputLayer> outputLayer;
1210 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1211 };
1212
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001213 StrictMock<OutputPartialMock> mOutput;
1214 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001215 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001216 Layer mLayer1;
1217 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001218};
1219
Brian Lindahl439afad2022-11-14 11:16:55 -07001220TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001221 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001222
1223 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1224
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001225 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001226 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1227 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1228
1229 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1230}
1231
1232TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1233 InSequence seq;
1234
1235 mRefreshArgs.bufferIdsToUncache = {};
1236
1237 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1238 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1239 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001240
1241 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1242}
1243
1244/*
1245 * Output::rebuildLayerStacks()
1246 */
1247
1248struct OutputRebuildLayerStacksTest : public testing::Test {
1249 struct OutputPartialMock : public OutputPartialMockBase {
1250 // Sets up the helper functions called by the function under test to use
1251 // mock implementations.
1252 MOCK_METHOD2(collectVisibleLayers,
1253 void(const compositionengine::CompositionRefreshArgs&,
1254 compositionengine::Output::CoverageState&));
1255 };
1256
1257 OutputRebuildLayerStacksTest() {
1258 mOutput.mState.isEnabled = true;
1259 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001260 mOutput.mState.displaySpace.setBounds(
1261 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001262
1263 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1264
1265 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1266
1267 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1268 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1269 }
1270
1271 void setTestCoverageValues(const CompositionRefreshArgs&,
1272 compositionengine::Output::CoverageState& state) {
1273 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1274 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1275 state.dirtyRegion = mCoverageDirtyRegionToSet;
1276 }
1277
1278 static const ui::Transform kIdentityTransform;
1279 static const ui::Transform kRotate90Transform;
1280 static const Rect kOutputBounds;
1281
1282 StrictMock<OutputPartialMock> mOutput;
1283 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001285 Region mCoverageAboveCoveredLayersToSet;
1286 Region mCoverageAboveOpaqueLayersToSet;
1287 Region mCoverageDirtyRegionToSet;
1288};
1289
1290const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1291const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1292const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1293
1294TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1295 mOutput.mState.isEnabled = false;
1296
1297 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1298}
1299
1300TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1301 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1302
1303 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1304}
1305
1306TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1307 mOutput.mState.transform = kIdentityTransform;
1308
1309 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1310
1311 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1312
1313 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1314}
1315
1316TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1317 mOutput.mState.transform = kIdentityTransform;
1318
1319 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1320
1321 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1322
1323 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1324}
1325
1326TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1327 mOutput.mState.transform = kRotate90Transform;
1328
1329 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1330
1331 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1332
1333 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1334}
1335
1336TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1337 mOutput.mState.transform = kRotate90Transform;
1338
1339 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1340
1341 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1342
1343 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1344}
1345
1346TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1347 mOutput.mState.transform = kIdentityTransform;
1348 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1349
1350 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1351
1352 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1353
1354 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1355}
1356
1357TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1358 mOutput.mState.transform = kRotate90Transform;
1359 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1360
1361 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1362
1363 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1364
1365 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1366}
1367
1368/*
1369 * Output::collectVisibleLayers()
1370 */
1371
Lloyd Pique1ef93222019-11-21 16:41:53 -08001372struct OutputCollectVisibleLayersTest : public testing::Test {
1373 struct OutputPartialMock : public OutputPartialMockBase {
1374 // Sets up the helper functions called by the function under test to use
1375 // mock implementations.
1376 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001377 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001378 compositionengine::Output::CoverageState&));
1379 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1380 MOCK_METHOD0(finalizePendingOutputLayers, void());
1381 };
1382
1383 struct Layer {
1384 Layer() {
1385 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1386 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1387 }
1388
1389 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001390 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001391 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001392 };
1393
1394 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001395 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001396 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1397 .WillRepeatedly(Return(&mLayer1.outputLayer));
1398 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1399 .WillRepeatedly(Return(&mLayer2.outputLayer));
1400 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1401 .WillRepeatedly(Return(&mLayer3.outputLayer));
1402
Lloyd Piquede196652020-01-22 17:29:58 -08001403 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1404 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1405 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001406 }
1407
1408 StrictMock<OutputPartialMock> mOutput;
1409 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410 LayerFESet mGeomSnapshots;
1411 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001412 Layer mLayer1;
1413 Layer mLayer2;
1414 Layer mLayer3;
1415};
1416
1417TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1418 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001419 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001420
1421 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1422 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1423
1424 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1425}
1426
1427TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1428 // Enforce a call order sequence for this test.
1429 InSequence seq;
1430
1431 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1433 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1434 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001435
1436 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1437 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1438
1439 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001440}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001441
1442/*
1443 * Output::ensureOutputLayerIfVisible()
1444 */
1445
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1447 struct OutputPartialMock : public OutputPartialMockBase {
1448 // Sets up the helper functions called by the function under test to use
1449 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001450 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1451 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001453 MOCK_METHOD2(ensureOutputLayer,
1454 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455 };
1456
1457 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001458 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001459 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001460 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001462 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001463
Angel Aguayob084e0c2021-08-04 23:27:28 +00001464 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1465 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001466 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 mLayer.layerFEState.isVisible = true;
1469 mLayer.layerFEState.isOpaque = true;
1470 mLayer.layerFEState.contentDirty = true;
1471 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1472 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001473 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1476 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
Lloyd Piquede196652020-01-22 17:29:58 -08001478 mGeomSnapshots.insert(mLayer.layerFE);
1479 }
1480
1481 void ensureOutputLayerIfVisible() {
1482 sp<LayerFE> layerFE(mLayer.layerFE);
1483 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001484 }
1485
1486 static const Region kEmptyRegion;
1487 static const Region kFullBoundsNoRotation;
1488 static const Region kRightHalfBoundsNoRotation;
1489 static const Region kLowerHalfBoundsNoRotation;
1490 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001491 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001492 static const Region kTransparentRegionHintTwo;
1493 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001494 static const Region kTransparentRegionHintNegative;
1495 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496
1497 StrictMock<OutputPartialMock> mOutput;
1498 LayerFESet mGeomSnapshots;
1499 Output::CoverageState mCoverageState{mGeomSnapshots};
1500
Lloyd Piquede196652020-01-22 17:29:58 -08001501 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502};
1503
1504const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1505const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1506 Region(Rect(0, 0, 100, 200));
1507const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1508 Region(Rect(0, 100, 100, 200));
1509const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1510 Region(Rect(50, 0, 100, 200));
1511const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1512 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001513const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001514 Region(Rect(0, 0, 100, 100));
1515const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001516 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001517const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001518 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001519const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1520 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1521const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1522 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001524TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1525 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526 mGeomSnapshots.clear();
1527
Lloyd Piquede196652020-01-22 17:29:58 -08001528 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529}
1530
1531TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001532 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1533 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 ensureOutputLayerIfVisible();
1536}
1537
1538TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1539 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1540
1541 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542}
1543
1544TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001545 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001548}
1549
1550TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001551 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552
Lloyd Piquede196652020-01-22 17:29:58 -08001553 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554}
1555
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001556TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001557 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560}
1561
1562TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1563 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001564 mLayer.layerFEState.isOpaque = true;
1565 mLayer.layerFEState.contentDirty = true;
1566 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567
1568 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001569 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1570 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571
Lloyd Piquede196652020-01-22 17:29:58 -08001572 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573
1574 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1575 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1577
Lloyd Piquede196652020-01-22 17:29:58 -08001578 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1580 RegionEq(kFullBoundsNoRotation));
1581 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1582 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583}
1584
1585TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1586 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001587 mLayer.layerFEState.isOpaque = true;
1588 mLayer.layerFEState.contentDirty = true;
1589 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590
Lloyd Piquede196652020-01-22 17:29:58 -08001591 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1592 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
Lloyd Piquede196652020-01-22 17:29:58 -08001594 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595
1596 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1599
Lloyd Piquede196652020-01-22 17:29:58 -08001600 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1602 RegionEq(kFullBoundsNoRotation));
1603 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1604 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605}
1606
1607TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1608 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001609 mLayer.layerFEState.isOpaque = false;
1610 mLayer.layerFEState.contentDirty = true;
1611 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612
1613 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001614 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1615 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616
Lloyd Piquede196652020-01-22 17:29:58 -08001617 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618
1619 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1620 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1621 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1624 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001626 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1627 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628}
1629
1630TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1631 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001632 mLayer.layerFEState.isOpaque = false;
1633 mLayer.layerFEState.contentDirty = true;
1634 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635
Lloyd Piquede196652020-01-22 17:29:58 -08001636 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1637 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640
1641 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1642 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1643 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1644
Lloyd Piquede196652020-01-22 17:29:58 -08001645 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1646 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001647 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001648 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1649 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650}
1651
1652TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1653 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001654 mLayer.layerFEState.isOpaque = true;
1655 mLayer.layerFEState.contentDirty = false;
1656 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
1658 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001659 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1660 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661
Lloyd Piquede196652020-01-22 17:29:58 -08001662 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001663
1664 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1665 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1666 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1667
Lloyd Piquede196652020-01-22 17:29:58 -08001668 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1669 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1670 RegionEq(kFullBoundsNoRotation));
1671 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1672 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001673}
1674
1675TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1676 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001677 mLayer.layerFEState.isOpaque = true;
1678 mLayer.layerFEState.contentDirty = false;
1679 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001680
Lloyd Piquede196652020-01-22 17:29:58 -08001681 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1682 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001683
Lloyd Piquede196652020-01-22 17:29:58 -08001684 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001685
1686 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1687 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1688 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1689
Lloyd Piquede196652020-01-22 17:29:58 -08001690 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1691 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1692 RegionEq(kFullBoundsNoRotation));
1693 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1694 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001695}
1696
1697TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1698 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001699 mLayer.layerFEState.isOpaque = true;
1700 mLayer.layerFEState.contentDirty = true;
1701 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1702 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1703 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1704 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001705
1706 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001707 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1708 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001709
Lloyd Piquede196652020-01-22 17:29:58 -08001710 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001711
1712 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1713 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1714 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1715
Lloyd Piquede196652020-01-22 17:29:58 -08001716 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1717 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1718 RegionEq(kFullBoundsNoRotation));
1719 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1720 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001721}
1722
1723TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1724 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001725 mLayer.layerFEState.isOpaque = true;
1726 mLayer.layerFEState.contentDirty = true;
1727 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1728 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1729 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1730 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001731
Lloyd Piquede196652020-01-22 17:29:58 -08001732 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1733 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001734
Lloyd Piquede196652020-01-22 17:29:58 -08001735 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001736
1737 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1739 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1740
Lloyd Piquede196652020-01-22 17:29:58 -08001741 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1742 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1743 RegionEq(kFullBoundsNoRotation));
1744 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1745 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001746}
1747
1748TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1749 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001750 mLayer.layerFEState.isOpaque = true;
1751 mLayer.layerFEState.contentDirty = true;
1752 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753
Angel Aguayob084e0c2021-08-04 23:27:28 +00001754 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1756
1757 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001758 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1759 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001760
Lloyd Piquede196652020-01-22 17:29:58 -08001761 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001762
1763 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1764 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1765 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1766
Lloyd Piquede196652020-01-22 17:29:58 -08001767 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1768 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1769 RegionEq(kFullBoundsNoRotation));
1770 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1771 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001772}
1773
1774TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1775 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001776 mLayer.layerFEState.isOpaque = true;
1777 mLayer.layerFEState.contentDirty = true;
1778 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001779
Angel Aguayob084e0c2021-08-04 23:27:28 +00001780 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001781 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1782
Lloyd Piquede196652020-01-22 17:29:58 -08001783 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1784 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001785
Lloyd Piquede196652020-01-22 17:29:58 -08001786 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001787
1788 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1789 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1790 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1791
Lloyd Piquede196652020-01-22 17:29:58 -08001792 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1793 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1794 RegionEq(kFullBoundsNoRotation));
1795 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1796 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001797}
1798
1799TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1800 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1801 ui::Transform arbitraryTransform;
1802 arbitraryTransform.set(1, 1, -1, 1);
1803 arbitraryTransform.set(0, 100);
1804
Lloyd Piquede196652020-01-22 17:29:58 -08001805 mLayer.layerFEState.isOpaque = true;
1806 mLayer.layerFEState.contentDirty = true;
1807 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1808 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001809
1810 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001811 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1812 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001813
Lloyd Piquede196652020-01-22 17:29:58 -08001814 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001815
1816 const Region kRegion = Region(Rect(0, 0, 300, 300));
1817 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1818
1819 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1820 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1821 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1822
Lloyd Piquede196652020-01-22 17:29:58 -08001823 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1824 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1825 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1826 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001827}
1828
1829TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001830 mLayer.layerFEState.isOpaque = false;
1831 mLayer.layerFEState.contentDirty = true;
1832 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001833
1834 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1835 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1836 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1837
Lloyd Piquede196652020-01-22 17:29:58 -08001838 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1839 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001840
Lloyd Piquede196652020-01-22 17:29:58 -08001841 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001842
1843 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1844 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1845 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1846 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1847 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1848 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1849
1850 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1851 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1852 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1853
Lloyd Piquede196652020-01-22 17:29:58 -08001854 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1855 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001856 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001857 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1858 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1859 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001860}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001861
Vishnu Naira483b4a2019-12-12 15:07:52 -08001862TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1863 ui::Transform translate;
1864 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001865 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001866 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001867
1868 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1869 // half of the layer including the casting shadow is covered and opaque
1870 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1871 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1872
Lloyd Piquede196652020-01-22 17:29:58 -08001873 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1874 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001875
Lloyd Piquede196652020-01-22 17:29:58 -08001876 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001877
1878 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1879 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1880 // add starting opaque region to the opaque half of the casting layer bounds
1881 const Region kExpectedAboveOpaqueRegion =
1882 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1883 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1884 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1885 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1886 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1887 const Region kExpectedLayerShadowRegion =
1888 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1889
1890 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1891 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1892 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1893
Lloyd Piquede196652020-01-22 17:29:58 -08001894 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1895 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001896 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001897 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1898 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001899 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001900 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001901 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1902}
1903
1904TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1905 ui::Transform translate;
1906 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001907 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001908 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001909
1910 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1911 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1912 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1913 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1914
Lloyd Piquede196652020-01-22 17:29:58 -08001915 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1916 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001917
Lloyd Piquede196652020-01-22 17:29:58 -08001918 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001919
1920 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1921 const Region kExpectedLayerShadowRegion =
1922 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1923
Lloyd Piquede196652020-01-22 17:29:58 -08001924 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1925 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001926 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1927}
1928
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001929TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001930 ui::Transform translate;
1931 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001932 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001933 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001934
1935 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1936 // Casting layer and its shadows are covered by an opaque region
1937 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1938 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1939
Lloyd Piquede196652020-01-22 17:29:58 -08001940 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001941}
1942
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001943TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1944 mLayer.layerFEState.isOpaque = false;
1945 mLayer.layerFEState.contentDirty = true;
1946 mLayer.layerFEState.compositionType =
1947 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1948
1949 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1950 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1951 .WillOnce(Return(&mLayer.outputLayer));
1952 ensureOutputLayerIfVisible();
1953
1954 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1955 RegionEq(kTransparentRegionHint));
1956}
1957
1958TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1959 mLayer.layerFEState.isOpaque = false;
1960 mLayer.layerFEState.contentDirty = true;
1961
1962 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1963 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1964 .WillOnce(Return(&mLayer.outputLayer));
1965 ensureOutputLayerIfVisible();
1966
1967 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1968}
1969
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001970TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1971 mLayer.layerFEState.isOpaque = false;
1972 mLayer.layerFEState.contentDirty = true;
1973 mLayer.layerFEState.compositionType =
1974 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001975 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001976
1977 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1978 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1979
1980 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1981 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1982 .WillOnce(Return(&mLayer.outputLayer));
1983 ensureOutputLayerIfVisible();
1984
1985 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001986 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001987}
1988
Alec Mourie60f0b92022-06-10 19:15:20 +00001989TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1990 mLayer.layerFEState.isOpaque = false;
1991 mLayer.layerFEState.contentDirty = true;
1992 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1993 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1994
1995 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1996}
1997
1998TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1999 mLayer.layerFEState.isOpaque = false;
2000 mLayer.layerFEState.contentDirty = true;
2001 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2002 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
2003
2004 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2005}
2006
2007TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
2008 mLayer.layerFEState.isOpaque = false;
2009 mLayer.layerFEState.contentDirty = true;
2010 mLayer.layerFEState.compositionType =
2011 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
2012 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
2013
2014 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2015 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
2016 .WillOnce(Return(&mLayer.outputLayer));
2017 ensureOutputLayerIfVisible();
2018
2019 // Check that the blocking region clips an out-of-bounds transparent region.
2020 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2021 RegionEq(kTransparentRegionHint));
2022}
2023
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002024/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002025 * Output::present()
2026 */
2027
2028struct OutputPresentTest : public testing::Test {
2029 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002030 // Sets up the helper functions called by the function under test to use
2031 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002032 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002033 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002034 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002035 MOCK_METHOD0(planComposition, void());
2036 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002037 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2038 MOCK_METHOD0(beginFrame, void());
2039 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002040 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002041 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002042 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002043 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Alec Mouriaa831582021-06-07 16:23:01 -07002044 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002045 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Xiang Wangaab31162024-03-12 19:48:08 -07002046 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
2047 (override));
2048 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002049 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002050 };
2051
Xiang Wangaab31162024-03-12 19:48:08 -07002052 OutputPresentTest() {
2053 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002054 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Xiang Wangaab31162024-03-12 19:48:08 -07002055 }
2056
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002057 StrictMock<OutputPartialMock> mOutput;
2058};
2059
2060TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2061 CompositionRefreshArgs args;
2062
2063 InSequence seq;
2064 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002065 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2066 EXPECT_CALL(mOutput, planComposition());
2067 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002068 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2069 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002070 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002071 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002072 EXPECT_CALL(mOutput, prepareFrame());
2073 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002074 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002075 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002076 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2077
2078 mOutput.present(args);
2079}
2080
2081TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2082 CompositionRefreshArgs args;
2083
2084 InSequence seq;
2085 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2086 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2087 EXPECT_CALL(mOutput, planComposition());
2088 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2089 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2090 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002091 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002092 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002093 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002094 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002095 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002096 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Alec Mouriaa831582021-06-07 16:23:01 -07002097 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002098
2099 mOutput.present(args);
2100}
2101
2102/*
2103 * Output::updateColorProfile()
2104 */
2105
Lloyd Pique17ca7422019-11-14 14:24:10 -08002106struct OutputUpdateColorProfileTest : public testing::Test {
2107 using TestType = OutputUpdateColorProfileTest;
2108
2109 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002110 // Sets up the helper functions called by the function under test to use
2111 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002112 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2113 };
2114
2115 struct Layer {
2116 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002117 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2118 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002119 }
2120
2121 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002122 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002123 LayerFECompositionState mLayerFEState;
2124 };
2125
2126 OutputUpdateColorProfileTest() {
2127 mOutput.setDisplayColorProfileForTest(
2128 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2129 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002130 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002131
2132 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2133 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2134 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2135 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2136 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2137 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2138 }
2139
2140 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2141 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2142 };
2143
2144 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2145 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2146 StrictMock<OutputPartialMock> mOutput;
2147
2148 Layer mLayer1;
2149 Layer mLayer2;
2150 Layer mLayer3;
2151
2152 CompositionRefreshArgs mRefreshArgs;
2153};
2154
2155// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2156// to make it easier to write unit tests.
2157
2158TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2159 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2160 // a simple default color profile without looking at anything else.
2161
Lloyd Pique0a456232020-01-16 17:51:13 -08002162 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002163 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002164 setColorProfile(
2165 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2166 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002167
2168 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002169
2170 mOutput.updateColorProfile(mRefreshArgs);
2171}
2172
2173struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2174 : public OutputUpdateColorProfileTest {
2175 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002176 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002177 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002178 }
2179
2180 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2181 : public CallOrderStateMachineHelper<
2182 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2183 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2184 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2185 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2186 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2187 _))
2188 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2189 SetArgPointee<4>(renderIntent)));
2190 EXPECT_CALL(getInstance()->mOutput,
2191 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002192 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002193 return nextState<ExecuteState>();
2194 }
2195 };
2196
2197 // Call this member function to start using the mini-DSL defined above.
2198 [[nodiscard]] auto verify() {
2199 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2200 }
2201};
2202
2203TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2204 Native_Unknown_Colorimetric_Set) {
2205 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2206 ui::Dataspace::UNKNOWN,
2207 ui::RenderIntent::COLORIMETRIC)
2208 .execute();
2209}
2210
2211TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2212 DisplayP3_DisplayP3_Enhance_Set) {
2213 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2214 ui::Dataspace::DISPLAY_P3,
2215 ui::RenderIntent::ENHANCE)
2216 .execute();
2217}
2218
Lloyd Pique17ca7422019-11-14 14:24:10 -08002219struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2220 : public OutputUpdateColorProfileTest {
2221 // Internally the implementation looks through the dataspaces of all the
2222 // visible layers. The topmost one that also has an actual dataspace
2223 // preference set is used to drive subsequent choices.
2224
2225 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2226 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002227
Lloyd Pique0a456232020-01-16 17:51:13 -08002228 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002229 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2230 }
2231
2232 struct IfTopLayerDataspaceState
2233 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2234 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2235 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2236 return nextState<AndIfMiddleLayerDataspaceState>();
2237 }
2238 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2239 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2240 }
2241 };
2242
2243 struct AndIfMiddleLayerDataspaceState
2244 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2245 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2246 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2247 return nextState<AndIfBottomLayerDataspaceState>();
2248 }
2249 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2250 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2251 }
2252 };
2253
2254 struct AndIfBottomLayerDataspaceState
2255 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2256 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2257 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2258 return nextState<ThenExpectBestColorModeCallUsesState>();
2259 }
2260 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2261 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2262 }
2263 };
2264
2265 struct ThenExpectBestColorModeCallUsesState
2266 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2267 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2268 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2269 getBestColorMode(dataspace, _, _, _, _));
2270 return nextState<ExecuteState>();
2271 }
2272 };
2273
2274 // Call this member function to start using the mini-DSL defined above.
2275 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2276};
2277
2278TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2279 noStrongLayerPrefenceUses_V0_SRGB) {
2280 // If none of the layers indicate a preference, then V0_SRGB is the
2281 // preferred choice (subject to additional checks).
2282 verify().ifTopLayerHasNoPreference()
2283 .andIfMiddleLayerHasNoPreference()
2284 .andIfBottomLayerHasNoPreference()
2285 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2286 .execute();
2287}
2288
2289TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2290 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2291 // If only the topmost layer has a preference, then that is what is chosen.
2292 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2293 .andIfMiddleLayerHasNoPreference()
2294 .andIfBottomLayerHasNoPreference()
2295 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2296 .execute();
2297}
2298
2299TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2300 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2301 // If only the middle layer has a preference, that that is what is chosen.
2302 verify().ifTopLayerHasNoPreference()
2303 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2304 .andIfBottomLayerHasNoPreference()
2305 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2306 .execute();
2307}
2308
2309TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2310 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2311 // If only the middle layer has a preference, that that is what is chosen.
2312 verify().ifTopLayerHasNoPreference()
2313 .andIfMiddleLayerHasNoPreference()
2314 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2315 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2316 .execute();
2317}
2318
2319TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2320 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2321 // If multiple layers have a preference, the topmost value is what is used.
2322 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2323 .andIfMiddleLayerHasNoPreference()
2324 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2325 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2326 .execute();
2327}
2328
2329TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2330 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2331 // If multiple layers have a preference, the topmost value is what is used.
2332 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2333 .andIfMiddleLayerHasNoPreference()
2334 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2335 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2336 .execute();
2337}
2338
2339struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2340 : public OutputUpdateColorProfileTest {
2341 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2342 // values, it overrides the layer dataspace choice.
2343
2344 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2345 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002346
2347 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2348
Lloyd Pique0a456232020-01-16 17:51:13 -08002349 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002350 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2351 }
2352
2353 struct IfForceOutputColorModeState
2354 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2355 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2356 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2357 return nextState<ThenExpectBestColorModeCallUsesState>();
2358 }
2359 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2360 };
2361
2362 struct ThenExpectBestColorModeCallUsesState
2363 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2364 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2365 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2366 getBestColorMode(dataspace, _, _, _, _));
2367 return nextState<ExecuteState>();
2368 }
2369 };
2370
2371 // Call this member function to start using the mini-DSL defined above.
2372 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2373};
2374
2375TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2376 // By default the layer state is used to set the preferred dataspace
2377 verify().ifNoOverride()
2378 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2383 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2384 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2385 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2386 .execute();
2387}
2388
2389TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2390 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2391 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2392 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2393 .execute();
2394}
2395
2396// HDR output requires all layers to be compatible with the chosen HDR
2397// dataspace, along with there being proper support.
2398struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2399 OutputUpdateColorProfileTest_Hdr() {
2400 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002401 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002402 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2403 }
2404
2405 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2406 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2407 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2408 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2409
2410 struct IfTopLayerDataspaceState
2411 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2412 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2413 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2414 return nextState<AndTopLayerCompositionTypeState>();
2415 }
2416 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2417 };
2418
2419 struct AndTopLayerCompositionTypeState
2420 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2421 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2422 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2423 return nextState<AndIfBottomLayerDataspaceState>();
2424 }
2425 };
2426
2427 struct AndIfBottomLayerDataspaceState
2428 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2429 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2430 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2431 return nextState<AndBottomLayerCompositionTypeState>();
2432 }
2433 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2434 return andIfBottomLayerIs(kNonHdrDataspace);
2435 }
2436 };
2437
2438 struct AndBottomLayerCompositionTypeState
2439 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2440 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2441 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2442 return nextState<AndIfHasLegacySupportState>();
2443 }
2444 };
2445
2446 struct AndIfHasLegacySupportState
2447 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2448 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2449 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2450 .WillOnce(Return(legacySupport));
2451 return nextState<ThenExpectBestColorModeCallUsesState>();
2452 }
2453 };
2454
2455 struct ThenExpectBestColorModeCallUsesState
2456 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2457 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2458 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2459 getBestColorMode(dataspace, _, _, _, _));
2460 return nextState<ExecuteState>();
2461 }
2462 };
2463
2464 // Call this member function to start using the mini-DSL defined above.
2465 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2466};
2467
2468TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2469 // If all layers use BT2020_PQ, and there are no other special conditions,
2470 // BT2020_PQ is used.
2471 verify().ifTopLayerIs(BT2020_PQ)
2472 .andTopLayerIsREComposed(false)
2473 .andIfBottomLayerIs(BT2020_PQ)
2474 .andBottomLayerIsREComposed(false)
2475 .andIfLegacySupportFor(BT2020_PQ, false)
2476 .thenExpectBestColorModeCallUses(BT2020_PQ)
2477 .execute();
2478}
2479
2480TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2481 // BT2020_PQ is not used if there is only legacy support for it.
2482 verify().ifTopLayerIs(BT2020_PQ)
2483 .andTopLayerIsREComposed(false)
2484 .andIfBottomLayerIs(BT2020_PQ)
2485 .andBottomLayerIsREComposed(false)
2486 .andIfLegacySupportFor(BT2020_PQ, true)
2487 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2488 .execute();
2489}
2490
2491TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2492 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2493 verify().ifTopLayerIs(BT2020_PQ)
2494 .andTopLayerIsREComposed(false)
2495 .andIfBottomLayerIs(BT2020_PQ)
2496 .andBottomLayerIsREComposed(true)
2497 .andIfLegacySupportFor(BT2020_PQ, false)
2498 .thenExpectBestColorModeCallUses(BT2020_PQ)
2499 .execute();
2500}
2501
2502TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2503 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2504 verify().ifTopLayerIs(BT2020_PQ)
2505 .andTopLayerIsREComposed(true)
2506 .andIfBottomLayerIs(BT2020_PQ)
2507 .andBottomLayerIsREComposed(false)
2508 .andIfLegacySupportFor(BT2020_PQ, false)
2509 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2510 .execute();
2511}
2512
2513TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2514 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2515 // are no other special conditions.
2516 verify().ifTopLayerIs(BT2020_PQ)
2517 .andTopLayerIsREComposed(false)
2518 .andIfBottomLayerIs(BT2020_HLG)
2519 .andBottomLayerIsREComposed(false)
2520 .andIfLegacySupportFor(BT2020_PQ, false)
2521 .thenExpectBestColorModeCallUses(BT2020_PQ)
2522 .execute();
2523}
2524
2525TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2526 // BT2020_PQ is not used if there is only legacy support for it.
2527 verify().ifTopLayerIs(BT2020_PQ)
2528 .andTopLayerIsREComposed(false)
2529 .andIfBottomLayerIs(BT2020_HLG)
2530 .andBottomLayerIsREComposed(false)
2531 .andIfLegacySupportFor(BT2020_PQ, true)
2532 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2533 .execute();
2534}
2535
2536TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2537 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2538 verify().ifTopLayerIs(BT2020_PQ)
2539 .andTopLayerIsREComposed(false)
2540 .andIfBottomLayerIs(BT2020_HLG)
2541 .andBottomLayerIsREComposed(true)
2542 .andIfLegacySupportFor(BT2020_PQ, false)
2543 .thenExpectBestColorModeCallUses(BT2020_PQ)
2544 .execute();
2545}
2546
2547TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2548 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2549 verify().ifTopLayerIs(BT2020_PQ)
2550 .andTopLayerIsREComposed(true)
2551 .andIfBottomLayerIs(BT2020_HLG)
2552 .andBottomLayerIsREComposed(false)
2553 .andIfLegacySupportFor(BT2020_PQ, false)
2554 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2555 .execute();
2556}
2557
2558TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2559 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2560 // used if there are no other special conditions.
2561 verify().ifTopLayerIs(BT2020_HLG)
2562 .andTopLayerIsREComposed(false)
2563 .andIfBottomLayerIs(BT2020_PQ)
2564 .andBottomLayerIsREComposed(false)
2565 .andIfLegacySupportFor(BT2020_PQ, false)
2566 .thenExpectBestColorModeCallUses(BT2020_PQ)
2567 .execute();
2568}
2569
2570TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2571 // BT2020_PQ is not used if there is only legacy support for it.
2572 verify().ifTopLayerIs(BT2020_HLG)
2573 .andTopLayerIsREComposed(false)
2574 .andIfBottomLayerIs(BT2020_PQ)
2575 .andBottomLayerIsREComposed(false)
2576 .andIfLegacySupportFor(BT2020_PQ, true)
2577 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2578 .execute();
2579}
2580
2581TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2582 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2583 verify().ifTopLayerIs(BT2020_HLG)
2584 .andTopLayerIsREComposed(false)
2585 .andIfBottomLayerIs(BT2020_PQ)
2586 .andBottomLayerIsREComposed(true)
2587 .andIfLegacySupportFor(BT2020_PQ, false)
2588 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2589 .execute();
2590}
2591
2592TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2593 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2594 verify().ifTopLayerIs(BT2020_HLG)
2595 .andTopLayerIsREComposed(true)
2596 .andIfBottomLayerIs(BT2020_PQ)
2597 .andBottomLayerIsREComposed(false)
2598 .andIfLegacySupportFor(BT2020_PQ, false)
2599 .thenExpectBestColorModeCallUses(BT2020_PQ)
2600 .execute();
2601}
2602
2603TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2604 // If all layers use HLG then HLG is used if there are no other special
2605 // conditions.
2606 verify().ifTopLayerIs(BT2020_HLG)
2607 .andTopLayerIsREComposed(false)
2608 .andIfBottomLayerIs(BT2020_HLG)
2609 .andBottomLayerIsREComposed(false)
2610 .andIfLegacySupportFor(BT2020_HLG, false)
2611 .thenExpectBestColorModeCallUses(BT2020_HLG)
2612 .execute();
2613}
2614
2615TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2616 // BT2020_HLG is not used if there is legacy support for it.
2617 verify().ifTopLayerIs(BT2020_HLG)
2618 .andTopLayerIsREComposed(false)
2619 .andIfBottomLayerIs(BT2020_HLG)
2620 .andBottomLayerIsREComposed(false)
2621 .andIfLegacySupportFor(BT2020_HLG, true)
2622 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2623 .execute();
2624}
2625
2626TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2627 // BT2020_HLG is used even if the bottom layer is client composed.
2628 verify().ifTopLayerIs(BT2020_HLG)
2629 .andTopLayerIsREComposed(false)
2630 .andIfBottomLayerIs(BT2020_HLG)
2631 .andBottomLayerIsREComposed(true)
2632 .andIfLegacySupportFor(BT2020_HLG, false)
2633 .thenExpectBestColorModeCallUses(BT2020_HLG)
2634 .execute();
2635}
2636
2637TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2638 // BT2020_HLG is used even if the top layer is client composed.
2639 verify().ifTopLayerIs(BT2020_HLG)
2640 .andTopLayerIsREComposed(true)
2641 .andIfBottomLayerIs(BT2020_HLG)
2642 .andBottomLayerIsREComposed(false)
2643 .andIfLegacySupportFor(BT2020_HLG, false)
2644 .thenExpectBestColorModeCallUses(BT2020_HLG)
2645 .execute();
2646}
2647
2648TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2649 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2650 verify().ifTopLayerIs(BT2020_PQ)
2651 .andTopLayerIsREComposed(false)
2652 .andIfBottomLayerIsNotHdr()
2653 .andBottomLayerIsREComposed(false)
2654 .andIfLegacySupportFor(BT2020_PQ, false)
2655 .thenExpectBestColorModeCallUses(BT2020_PQ)
2656 .execute();
2657}
2658
2659TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2660 // If all layers use HLG then HLG is used if there are no other special
2661 // conditions.
2662 verify().ifTopLayerIs(BT2020_HLG)
2663 .andTopLayerIsREComposed(false)
2664 .andIfBottomLayerIsNotHdr()
2665 .andBottomLayerIsREComposed(true)
2666 .andIfLegacySupportFor(BT2020_HLG, false)
2667 .thenExpectBestColorModeCallUses(BT2020_HLG)
2668 .execute();
2669}
2670
2671struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2672 : public OutputUpdateColorProfileTest {
2673 // The various values for CompositionRefreshArgs::outputColorSetting affect
2674 // the chosen renderIntent, along with whether the preferred dataspace is an
2675 // HDR dataspace or not.
2676
2677 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2678 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002679 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002680 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002681 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2682 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2683 .WillRepeatedly(Return(false));
2684 }
2685
2686 // The tests here involve enough state and GMock setup that using a mini-DSL
2687 // makes the tests much more readable, and allows the test to focus more on
2688 // the intent than on some of the details.
2689
2690 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2691 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2692
2693 struct IfDataspaceChosenState
2694 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2695 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2696 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2697 return nextState<AndOutputColorSettingState>();
2698 }
2699 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2700 return ifDataspaceChosenIs(kNonHdrDataspace);
2701 }
2702 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2703 };
2704
2705 struct AndOutputColorSettingState
2706 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2707 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2708 getInstance()->mRefreshArgs.outputColorSetting = setting;
2709 return nextState<ThenExpectBestColorModeCallUsesState>();
2710 }
2711 };
2712
2713 struct ThenExpectBestColorModeCallUsesState
2714 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2715 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2716 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2717 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2718 _, _));
2719 return nextState<ExecuteState>();
2720 }
2721 };
2722
2723 // Tests call one of these two helper member functions to start using the
2724 // mini-DSL defined above.
2725 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2726};
2727
2728TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2729 Managed_NonHdr_Prefers_Colorimetric) {
2730 verify().ifDataspaceChosenIsNonHdr()
2731 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2732 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2733 .execute();
2734}
2735
2736TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2737 Managed_Hdr_Prefers_ToneMapColorimetric) {
2738 verify().ifDataspaceChosenIsHdr()
2739 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2740 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2741 .execute();
2742}
2743
2744TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2745 verify().ifDataspaceChosenIsNonHdr()
2746 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2747 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2748 .execute();
2749}
2750
2751TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2752 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2753 verify().ifDataspaceChosenIsHdr()
2754 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2755 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2756 .execute();
2757}
2758
2759TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2760 verify().ifDataspaceChosenIsNonHdr()
2761 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2762 .thenExpectBestColorModeCallUses(
2763 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2764 .execute();
2765}
2766
2767TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2768 verify().ifDataspaceChosenIsHdr()
2769 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2770 .thenExpectBestColorModeCallUses(
2771 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2772 .execute();
2773}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002774
2775/*
2776 * Output::beginFrame()
2777 */
2778
Lloyd Piquee5965952019-11-18 16:16:32 -08002779struct OutputBeginFrameTest : public ::testing::Test {
2780 using TestType = OutputBeginFrameTest;
2781
2782 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002783 // Sets up the helper functions called by the function under test to use
2784 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002785 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002786 };
2787
2788 OutputBeginFrameTest() {
2789 mOutput.setDisplayColorProfileForTest(
2790 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2791 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2792 }
2793
2794 struct IfGetDirtyRegionExpectationState
2795 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2796 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002797 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002798 return nextState<AndIfGetOutputLayerCountExpectationState>();
2799 }
2800 };
2801
2802 struct AndIfGetOutputLayerCountExpectationState
2803 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2804 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2805 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2806 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2807 }
2808 };
2809
2810 struct AndIfLastCompositionHadVisibleLayersState
2811 : public CallOrderStateMachineHelper<TestType,
2812 AndIfLastCompositionHadVisibleLayersState> {
2813 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2814 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2815 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2816 }
2817 };
2818
2819 struct ThenExpectRenderSurfaceBeginFrameCallState
2820 : public CallOrderStateMachineHelper<TestType,
2821 ThenExpectRenderSurfaceBeginFrameCallState> {
2822 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2823 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2824 return nextState<ExecuteState>();
2825 }
2826 };
2827
2828 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2829 [[nodiscard]] auto execute() {
2830 getInstance()->mOutput.beginFrame();
2831 return nextState<CheckPostconditionHadVisibleLayersState>();
2832 }
2833 };
2834
2835 struct CheckPostconditionHadVisibleLayersState
2836 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2837 void checkPostconditionHadVisibleLayers(bool expected) {
2838 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2839 }
2840 };
2841
2842 // Tests call one of these two helper member functions to start using the
2843 // mini-DSL defined above.
2844 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2845
2846 static const Region kEmptyRegion;
2847 static const Region kNotEmptyRegion;
2848
2849 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2850 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2851 StrictMock<OutputPartialMock> mOutput;
2852};
2853
2854const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2855const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2856
2857TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2858 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2859 .andIfGetOutputLayerCountReturns(1u)
2860 .andIfLastCompositionHadVisibleLayersIs(true)
2861 .thenExpectRenderSurfaceBeginFrameCall(true)
2862 .execute()
2863 .checkPostconditionHadVisibleLayers(true);
2864}
2865
2866TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2867 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2868 .andIfGetOutputLayerCountReturns(0u)
2869 .andIfLastCompositionHadVisibleLayersIs(true)
2870 .thenExpectRenderSurfaceBeginFrameCall(true)
2871 .execute()
2872 .checkPostconditionHadVisibleLayers(false);
2873}
2874
2875TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2876 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2877 .andIfGetOutputLayerCountReturns(1u)
2878 .andIfLastCompositionHadVisibleLayersIs(false)
2879 .thenExpectRenderSurfaceBeginFrameCall(true)
2880 .execute()
2881 .checkPostconditionHadVisibleLayers(true);
2882}
2883
2884TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2885 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2886 .andIfGetOutputLayerCountReturns(0u)
2887 .andIfLastCompositionHadVisibleLayersIs(false)
2888 .thenExpectRenderSurfaceBeginFrameCall(false)
2889 .execute()
2890 .checkPostconditionHadVisibleLayers(false);
2891}
2892
2893TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2894 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2895 .andIfGetOutputLayerCountReturns(1u)
2896 .andIfLastCompositionHadVisibleLayersIs(true)
2897 .thenExpectRenderSurfaceBeginFrameCall(false)
2898 .execute()
2899 .checkPostconditionHadVisibleLayers(true);
2900}
2901
2902TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2903 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2904 .andIfGetOutputLayerCountReturns(0u)
2905 .andIfLastCompositionHadVisibleLayersIs(true)
2906 .thenExpectRenderSurfaceBeginFrameCall(false)
2907 .execute()
2908 .checkPostconditionHadVisibleLayers(true);
2909}
2910
2911TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2912 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2913 .andIfGetOutputLayerCountReturns(1u)
2914 .andIfLastCompositionHadVisibleLayersIs(false)
2915 .thenExpectRenderSurfaceBeginFrameCall(false)
2916 .execute()
2917 .checkPostconditionHadVisibleLayers(false);
2918}
2919
2920TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2921 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2922 .andIfGetOutputLayerCountReturns(0u)
2923 .andIfLastCompositionHadVisibleLayersIs(false)
2924 .thenExpectRenderSurfaceBeginFrameCall(false)
2925 .execute()
2926 .checkPostconditionHadVisibleLayers(false);
2927}
2928
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002929/*
2930 * Output::devOptRepaintFlash()
2931 */
2932
Lloyd Piquedb462d82019-11-19 17:58:46 -08002933struct OutputDevOptRepaintFlashTest : public testing::Test {
2934 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002935 // Sets up the helper functions called by the function under test to use
2936 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002937 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002938 MOCK_METHOD3(composeSurfaces,
2939 std::optional<base::unique_fd>(const Region&,
2940 std::shared_ptr<renderengine::ExternalTexture>,
2941 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002942 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002944 MOCK_METHOD0(updateProtectedContentState, void());
2945 MOCK_METHOD2(dequeueRenderBuffer,
2946 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002947 };
2948
2949 OutputDevOptRepaintFlashTest() {
2950 mOutput.setDisplayColorProfileForTest(
2951 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2952 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2953 }
2954
2955 static const Region kEmptyRegion;
2956 static const Region kNotEmptyRegion;
2957
2958 StrictMock<OutputPartialMock> mOutput;
2959 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2960 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2961 CompositionRefreshArgs mRefreshArgs;
2962};
2963
2964const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2965const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2966
2967TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2968 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002969 mOutput.mState.isEnabled = true;
2970
2971 mOutput.devOptRepaintFlash(mRefreshArgs);
2972}
2973
2974TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2975 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002976 mOutput.mState.isEnabled = false;
2977
2978 InSequence seq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002979 constexpr bool kFlushEvenWhenDisabled = false;
2980 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002981 EXPECT_CALL(mOutput, prepareFrame());
2982
2983 mOutput.devOptRepaintFlash(mRefreshArgs);
2984}
2985
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002986TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002987 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002988 mOutput.mState.isEnabled = true;
2989
2990 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002991 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002992 constexpr bool kFlushEvenWhenDisabled = false;
2993 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002994 EXPECT_CALL(mOutput, prepareFrame());
2995
2996 mOutput.devOptRepaintFlash(mRefreshArgs);
2997}
2998
2999TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3000 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003001 mOutput.mState.isEnabled = true;
3002
3003 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003004 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003005 EXPECT_CALL(mOutput, updateProtectedContentState());
3006 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003007 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Alec Mourif97df4d2023-09-06 02:10:05 +00003008 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003009 constexpr bool kFlushEvenWhenDisabled = false;
3010 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003011 EXPECT_CALL(mOutput, prepareFrame());
3012
3013 mOutput.devOptRepaintFlash(mRefreshArgs);
3014}
3015
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003016/*
3017 * Output::finishFrame()
3018 */
3019
Lloyd Pique03561a62019-11-19 18:34:52 -08003020struct OutputFinishFrameTest : public testing::Test {
3021 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003022 // Sets up the helper functions called by the function under test to use
3023 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003024 MOCK_METHOD3(composeSurfaces,
3025 std::optional<base::unique_fd>(const Region&,
3026 std::shared_ptr<renderengine::ExternalTexture>,
3027 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003028 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Vishnu Naira3140382022-02-24 14:07:11 -08003029 MOCK_METHOD0(updateProtectedContentState, void());
3030 MOCK_METHOD2(dequeueRenderBuffer,
3031 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Xiang Wangaab31162024-03-12 19:48:08 -07003032 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3033 (override));
3034 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003035 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique03561a62019-11-19 18:34:52 -08003036 };
3037
3038 OutputFinishFrameTest() {
3039 mOutput.setDisplayColorProfileForTest(
3040 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3041 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Alec Mourif97df4d2023-09-06 02:10:05 +00003042 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3043 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Xiang Wangaab31162024-03-12 19:48:08 -07003044 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003045 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique03561a62019-11-19 18:34:52 -08003046 }
3047
3048 StrictMock<OutputPartialMock> mOutput;
3049 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3050 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Alec Mourif97df4d2023-09-06 02:10:05 +00003051 StrictMock<mock::CompositionEngine> mCompositionEngine;
3052 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique03561a62019-11-19 18:34:52 -08003053};
3054
3055TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3056 mOutput.mState.isEnabled = false;
3057
Vishnu Naira3140382022-02-24 14:07:11 -08003058 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003059 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003060}
3061
3062TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3063 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003064 EXPECT_CALL(mOutput, updateProtectedContentState());
3065 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003066 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003067
Vishnu Naira3140382022-02-24 14:07:11 -08003068 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003069 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003070}
3071
Xiang Wangcf61e732024-03-22 11:05:28 -07003072TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFenceWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003073 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Lloyd Pique03561a62019-11-19 18:34:52 -08003074 mOutput.mState.isEnabled = true;
3075
3076 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003077 EXPECT_CALL(mOutput, updateProtectedContentState());
3078 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003079 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003080 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangaab31162024-03-12 19:48:08 -07003081 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
3082 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3083
3084 impl::GpuCompositionResult result;
3085 mOutput.finishFrame(std::move(result));
3086}
3087
Xiang Wangcf61e732024-03-22 11:05:28 -07003088TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
Xiang Wangaab31162024-03-12 19:48:08 -07003089 mOutput.mState.isEnabled = true;
3090
3091 InSequence seq;
3092 EXPECT_CALL(mOutput, updateProtectedContentState());
3093 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3094 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3095 .WillOnce(Return(ByMove(base::unique_fd())));
3096 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003097 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3098
3099 impl::GpuCompositionResult result;
3100 mOutput.finishFrame(std::move(result));
3101}
3102
3103TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) {
3104 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
3105 mOutput.mState.isEnabled = true;
3106
3107 InSequence seq;
3108 auto texture = std::make_shared<
3109 renderengine::impl::
3110 ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16,
3111 GRALLOC_USAGE_SW_WRITE_OFTEN |
3112 GRALLOC_USAGE_SW_READ_OFTEN),
3113 mRenderEngine,
3114 renderengine::impl::ExternalTexture::Usage::READABLE |
3115 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3116 mOutput.mState.displayBrightnessNits = 400.f;
3117 mOutput.mState.sdrWhitePointNits = 200.f;
3118 mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB;
3119 EXPECT_CALL(mOutput, updateProtectedContentState());
3120 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
3121 .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true)));
3122 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3123 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003124 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003125 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f));
Lloyd Pique03561a62019-11-19 18:34:52 -08003126
Vishnu Naira3140382022-02-24 14:07:11 -08003127 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003128 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003129}
3130
3131TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3132 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003133 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003134 InSequence seq;
Xiang Wangcf61e732024-03-22 11:05:28 -07003135 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003136 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Vishnu Naira3140382022-02-24 14:07:11 -08003137
3138 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003139 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003140}
3141
3142TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3143 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003144 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003145
3146 InSequence seq;
3147
3148 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003149 result.buffer =
3150 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3151 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3152 2);
3153
3154 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003155 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003156 Eq(ByRef(result.fence))))
3157 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003158 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003159 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003160 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003161}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003162
3163/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003164 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003165 */
3166
Lloyd Pique07178e32019-11-19 19:15:26 -08003167struct OutputPostFramebufferTest : public testing::Test {
3168 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003169 // Sets up the helper functions called by the function under test to use
3170 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003171 MOCK_METHOD(compositionengine::Output::FrameFences, presentFrame, ());
3172 MOCK_METHOD(void, executeCommands, ());
Lloyd Pique07178e32019-11-19 19:15:26 -08003173 };
3174
3175 struct Layer {
3176 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003177 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003178 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3179 }
3180
3181 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003182 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003183 StrictMock<HWC2::mock::Layer> hwc2Layer;
3184 };
3185
3186 OutputPostFramebufferTest() {
3187 mOutput.setDisplayColorProfileForTest(
3188 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3189 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3190
3191 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3192 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3193 .WillRepeatedly(Return(&mLayer1.outputLayer));
3194 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3195 .WillRepeatedly(Return(&mLayer2.outputLayer));
3196 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3197 .WillRepeatedly(Return(&mLayer3.outputLayer));
3198 }
3199
3200 StrictMock<OutputPartialMock> mOutput;
3201 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3202 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3203
3204 Layer mLayer1;
3205 Layer mLayer2;
3206 Layer mLayer3;
3207};
3208
3209TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003210 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3211 true);
Lloyd Pique07178e32019-11-19 19:15:26 -08003212 mOutput.mState.isEnabled = false;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003213 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3214 EXPECT_CALL(mOutput, presentFrame()).Times(0);
Lloyd Pique07178e32019-11-19 19:15:26 -08003215
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003216 constexpr bool kFlushEvenWhenDisabled = false;
3217 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3218}
3219
3220TEST_F(OutputPostFramebufferTest, ifNotEnabledExecutesCommandsIfFlush) {
3221 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3222 true);
3223 mOutput.mState.isEnabled = false;
3224 EXPECT_CALL(mOutput, executeCommands());
3225 EXPECT_CALL(mOutput, presentFrame()).Times(0);
3226
3227 constexpr bool kFlushEvenWhenDisabled = true;
3228 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3229}
3230
3231TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands) {
3232 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3233 true);
3234 mOutput.mState.isEnabled = true;
3235
3236 compositionengine::Output::FrameFences frameFences;
3237
3238 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3239
3240 // This should only be called for disabled outputs. This test's goal is to verify this line;
3241 // the other expectations help satisfy the StrictMocks.
3242 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3243
3244 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3245 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3246
3247 constexpr bool kFlushEvenWhenDisabled = true;
3248 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3249}
3250
3251TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands2) {
3252 // Same test as ifEnabledDoNotExecuteCommands, but with this variable set to false.
3253 constexpr bool kFlushEvenWhenDisabled = false;
3254
3255 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3256 true);
3257 mOutput.mState.isEnabled = true;
3258
3259 compositionengine::Output::FrameFences frameFences;
3260
3261 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3262
3263 // This should only be called for disabled outputs. This test's goal is to verify this line;
3264 // the other expectations help satisfy the StrictMocks.
3265 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3266
3267 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3268 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3269
3270 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003271}
3272
3273TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3274 mOutput.mState.isEnabled = true;
3275
3276 compositionengine::Output::FrameFences frameFences;
3277
3278 // This should happen even if there are no output layers.
3279 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3280
3281 // For this test in particular we want to make sure the call expectations
3282 // setup below are satisfied in the specific order.
3283 InSequence seq;
3284
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003285 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003286 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3287
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003288 constexpr bool kFlushEvenWhenDisabled = true;
3289 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003290}
3291
Melody Hsu793f8362024-01-08 20:00:35 +00003292TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
Melody Hsu793f8362024-01-08 20:00:35 +00003293 // Simulate getting release fences from each layer, and ensure they are passed to the
3294 // front-end layer interface for each layer correctly.
Melody Hsu793f8362024-01-08 20:00:35 +00003295 mOutput.mState.isEnabled = true;
3296
3297 // Create three unique fence instances
3298 sp<Fence> layer1Fence = sp<Fence>::make();
3299 sp<Fence> layer2Fence = sp<Fence>::make();
3300 sp<Fence> layer3Fence = sp<Fence>::make();
3301
3302 Output::FrameFences frameFences;
3303 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3304 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3305 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3306
3307 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3308 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3309
3310 // Compare the pointers values of each fence to make sure the correct ones
3311 // are passed. This happens to work with the current implementation, but
3312 // would not survive certain calls like Fence::merge() which would return a
3313 // new instance.
3314 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence(_))
3315 .WillOnce([&layer1Fence](FenceResult releaseFence) {
3316 EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
3317 });
3318 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
3319 .WillOnce([&layer2Fence](FenceResult releaseFence) {
3320 EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
3321 });
3322 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
3323 .WillOnce([&layer3Fence](FenceResult releaseFence) {
3324 EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
3325 });
3326
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003327 constexpr bool kFlushEvenWhenDisabled = false;
3328 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003329}
3330
Melody Hsu793f8362024-01-08 20:00:35 +00003331TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003332 mOutput.mState.isEnabled = true;
3333 mOutput.mState.usesClientComposition = true;
3334
3335 Output::FrameFences frameFences;
3336 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3337 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3338 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3339 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3340
3341 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3342 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3343
3344 // Fence::merge is called, and since none of the fences are actually valid,
3345 // Fence::NO_FENCE is returned and passed to each setReleaseFence() call.
3346 // This is the best we can do without creating a real kernel fence object.
3347 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
3348 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
3349 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003350 constexpr bool kFlushEvenWhenDisabled = false;
3351 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003352}
3353
Melody Hsu793f8362024-01-08 20:00:35 +00003354TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003355 mOutput.mState.isEnabled = true;
3356 mOutput.mState.usesClientComposition = true;
3357
3358 // This should happen even if there are no (current) output layers.
3359 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3360
3361 // Load up the released layers with some mock instances
3362 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3363 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3364 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3365 Output::ReleasedLayers layers;
3366 layers.push_back(releasedLayer1);
3367 layers.push_back(releasedLayer2);
3368 layers.push_back(releasedLayer3);
3369 mOutput.setReleasedLayers(std::move(layers));
3370
3371 // Set up a fake present fence
3372 sp<Fence> presentFence = sp<Fence>::make();
3373 Output::FrameFences frameFences;
3374 frameFences.presentFence = presentFence;
3375
3376 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3377 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3378
3379 // Each released layer should be given the presentFence.
3380 EXPECT_CALL(*releasedLayer1, setReleaseFence(_))
3381 .WillOnce([&presentFence](FenceResult fenceResult) {
3382 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3383 });
3384 EXPECT_CALL(*releasedLayer2, setReleaseFence(_))
3385 .WillOnce([&presentFence](FenceResult fenceResult) {
3386 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3387 });
3388 EXPECT_CALL(*releasedLayer3, setReleaseFence(_))
3389 .WillOnce([&presentFence](FenceResult fenceResult) {
3390 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3391 });
3392
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003393 constexpr bool kFlushEvenWhenDisabled = false;
3394 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003395
3396 // After the call the list of released layers should have been cleared.
3397 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3398}
3399
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003400/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003401 * Output::composeSurfaces()
3402 */
3403
3404struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003405 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003406
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003407 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003408 // Sets up the helper functions called by the function under test to use
3409 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003410 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003411 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003412 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3413 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003414 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003415 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003416 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Xiang Wangaab31162024-03-12 19:48:08 -07003417 MOCK_METHOD(void, setHintSessionGpuStart, (TimePoint startTime), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003418 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3419 (override));
Xiang Wangaab31162024-03-12 19:48:08 -07003420 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003421 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003422 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003423 };
3424
3425 OutputComposeSurfacesTest() {
3426 mOutput.setDisplayColorProfileForTest(
3427 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3428 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003429 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003430
Angel Aguayob084e0c2021-08-04 23:27:28 +00003431 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3432 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3433 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3434 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3435 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003436 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003437 mOutput.mState.dataspace = kDefaultOutputDataspace;
3438 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3439 mOutput.mState.isSecure = false;
3440 mOutput.mState.needsFiltering = false;
3441 mOutput.mState.usesClientComposition = true;
3442 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003443 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003444 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003445 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003446
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003447 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003448 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003449 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003450 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3451 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Xiang Wangaab31162024-03-12 19:48:08 -07003452 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003453 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique56eba802019-08-28 15:45:25 -07003454 }
3455
Lloyd Pique6818fa52019-12-03 12:32:13 -08003456 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3457 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003458 base::unique_fd fence;
3459 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3460 const bool success =
3461 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3462 if (success) {
3463 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003464 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3465 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003466 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003467 return nextState<FenceCheckState>();
3468 }
3469 };
3470
3471 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3472 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3473
3474 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3475 };
3476
3477 // Call this member function to start using the mini-DSL defined above.
3478 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3479
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003480 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3481 static constexpr uint32_t kDefaultOutputOrientationFlags =
3482 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003483 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3484 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3485 static constexpr float kDefaultMaxLuminance = 0.9f;
3486 static constexpr float kDefaultAvgLuminance = 0.7f;
3487 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003488 static constexpr float kDisplayLuminance = 400.f;
Alec Mourif97df4d2023-09-06 02:10:05 +00003489 static constexpr float kWhitePointLuminance = 300.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003490 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003491 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003492
3493 static const Rect kDefaultOutputFrame;
3494 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003495 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496 static const mat4 kDefaultColorTransformMat;
3497
3498 static const Region kDebugRegion;
3499 static const HdrCapabilities kHdrCapabilities;
3500
Lloyd Pique56eba802019-08-28 15:45:25 -07003501 StrictMock<mock::CompositionEngine> mCompositionEngine;
3502 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003503 // TODO: make this is a proper mock.
3504 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003505 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3506 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003507 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003508 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003509 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003510 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003511 renderengine::impl::ExternalTexture::Usage::READABLE |
3512 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513
3514 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003515};
3516
3517const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3518const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003519const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003520const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003521const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003522
Lloyd Pique6818fa52019-12-03 12:32:13 -08003523const HdrCapabilities OutputComposeSurfacesTest::
3524 kHdrCapabilities{{},
3525 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3526 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3527 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003528
Lloyd Piquea76ce462020-01-14 13:06:37 -08003529TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003530 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003531
Lloyd Piquee9eff972020-05-05 12:36:44 -07003532 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003533 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003534
Lloyd Piquea76ce462020-01-14 13:06:37 -08003535 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3536
Lloyd Pique6818fa52019-12-03 12:32:13 -08003537 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003538}
3539
Lloyd Piquee9eff972020-05-05 12:36:44 -07003540TEST_F(OutputComposeSurfacesTest,
3541 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3542 mOutput.mState.usesClientComposition = false;
3543 mOutput.mState.flipClientTarget = true;
3544
Lloyd Pique6818fa52019-12-03 12:32:13 -08003545 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003546 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003547
3548 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3549 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3550
3551 verify().execute().expectAFenceWasReturned();
3552}
3553
3554TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3555 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003556 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003557
3558 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3559
3560 verify().execute().expectNoFenceWasReturned();
3561}
3562
3563TEST_F(OutputComposeSurfacesTest,
3564 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3565 mOutput.mState.usesClientComposition = false;
3566 mOutput.mState.flipClientTarget = true;
3567
3568 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003569 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003570
Lloyd Pique6818fa52019-12-03 12:32:13 -08003571 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003572
Lloyd Pique6818fa52019-12-03 12:32:13 -08003573 verify().execute().expectNoFenceWasReturned();
3574}
Lloyd Pique56eba802019-08-28 15:45:25 -07003575
Lloyd Pique6818fa52019-12-03 12:32:13 -08003576TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3577 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3578 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3579 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003580 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003581 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003582 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003583 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3584 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003585
Lloyd Pique6818fa52019-12-03 12:32:13 -08003586 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003587 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003588 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003589 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003590 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003591 base::unique_fd&&) -> ftl::Future<FenceResult> {
3592 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003593 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003594 verify().execute().expectAFenceWasReturned();
3595}
Lloyd Pique56eba802019-08-28 15:45:25 -07003596
Lloyd Pique6818fa52019-12-03 12:32:13 -08003597TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003598 LayerFE::LayerSettings r1;
3599 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003600
3601 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3602 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3603
3604 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3605 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3606 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003607 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003608 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003609 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003610 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3611 .WillRepeatedly(
3612 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003613 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003614 clientCompositionLayers.emplace_back(r2);
3615 }));
3616
3617 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003618 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003619 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003620 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003621 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003622 base::unique_fd&&) -> ftl::Future<FenceResult> {
3623 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003624 });
Alec Mouri1684c702021-02-04 12:27:26 -08003625
3626 verify().execute().expectAFenceWasReturned();
3627}
3628
3629TEST_F(OutputComposeSurfacesTest,
3630 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3631 LayerFE::LayerSettings r1;
3632 LayerFE::LayerSettings r2;
3633
3634 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3635 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003636 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003637
3638 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3639 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3640 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3641 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003642 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003643 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3644 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3645 .WillRepeatedly(
3646 Invoke([&](const Region&,
3647 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3648 clientCompositionLayers.emplace_back(r2);
3649 }));
3650
3651 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003652 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003653 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003654 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003655 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003656 base::unique_fd&&) -> ftl::Future<FenceResult> {
3657 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003658 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003659
3660 verify().execute().expectAFenceWasReturned();
3661}
3662
Vishnu Nair9b079a22020-01-21 14:36:08 -08003663TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3664 mOutput.cacheClientCompositionRequests(0);
3665 LayerFE::LayerSettings r1;
3666 LayerFE::LayerSettings r2;
3667
3668 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3669 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3670
3671 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3672 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3673 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003674 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003675 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003676 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3677 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3678 .WillRepeatedly(Return());
3679
3680 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003681 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003682 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003683 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3684 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003685
3686 verify().execute().expectAFenceWasReturned();
3687 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3688
3689 verify().execute().expectAFenceWasReturned();
3690 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3691}
3692
3693TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3694 mOutput.cacheClientCompositionRequests(3);
3695 LayerFE::LayerSettings r1;
3696 LayerFE::LayerSettings r2;
3697
3698 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3699 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3700
3701 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3702 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3703 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003704 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003705 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3707 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3708 .WillRepeatedly(Return());
3709
3710 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003711 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003712 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003713 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3714
3715 verify().execute().expectAFenceWasReturned();
3716 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3717
3718 // We do not expect another call to draw layers.
Xiang Wangaab31162024-03-12 19:48:08 -07003719 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(_)).Times(0);
3720 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3721 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003722 verify().execute().expectAFenceWasReturned();
3723 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3724}
3725
Xiang Wangcf61e732024-03-22 11:05:28 -07003726TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChangesWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003727 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003728 LayerFE::LayerSettings r1;
3729 LayerFE::LayerSettings r2;
3730
3731 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3732 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3733
3734 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3735 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3736 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003737 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003738 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003739 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3740 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3741 .WillRepeatedly(Return());
3742
Alec Mouria90a5702021-04-16 16:36:21 +00003743 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003744 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003745 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003746 renderengine::impl::ExternalTexture::Usage::READABLE |
3747 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003748 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3749 .WillOnce(Return(mOutputBuffer))
3750 .WillOnce(Return(otherOutputBuffer));
Xiang Wangaab31162024-03-12 19:48:08 -07003751 base::unique_fd fd(open("/dev/null", O_RDONLY));
Alec Mourif29700f2023-08-17 21:53:31 +00003752 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003753 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003754 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003755 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003756 base::unique_fd&&) -> ftl::Future<FenceResult> {
Xiang Wangaab31162024-03-12 19:48:08 -07003757 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
Sally Qi4cabdd02021-08-05 16:45:57 -07003758 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003759
Xiang Wangaab31162024-03-12 19:48:08 -07003760 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3761 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3762 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
3763 verify().execute().expectAFenceWasReturned();
3764 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3765
3766 verify().execute().expectAFenceWasReturned();
3767 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3768}
3769
Xiang Wangcf61e732024-03-22 11:05:28 -07003770TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
Xiang Wangaab31162024-03-12 19:48:08 -07003771 LayerFE::LayerSettings r1;
3772 LayerFE::LayerSettings r2;
3773
3774 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3775 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3776
3777 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3778 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3779 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3780 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3781 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3782 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3783 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3784 .WillRepeatedly(Return());
3785
3786 const auto otherOutputBuffer = std::make_shared<
3787 renderengine::impl::
3788 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3789 renderengine::impl::ExternalTexture::Usage::READABLE |
3790 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3791 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3792 .WillOnce(Return(mOutputBuffer))
3793 .WillOnce(Return(otherOutputBuffer));
3794 base::unique_fd fd(open("/dev/null", O_RDONLY));
3795 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
3796 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3797 const std::vector<renderengine::LayerSettings>&,
3798 const std::shared_ptr<renderengine::ExternalTexture>&,
3799 base::unique_fd&&) -> ftl::Future<FenceResult> {
3800 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
3801 });
3802
3803 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3804 EXPECT_CALL(mOutput, setHintSessionGpuStart(_));
3805 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003806 verify().execute().expectAFenceWasReturned();
3807 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3808
3809 verify().execute().expectAFenceWasReturned();
3810 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3811}
3812
3813TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3814 LayerFE::LayerSettings r1;
3815 LayerFE::LayerSettings r2;
3816 LayerFE::LayerSettings r3;
3817
3818 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3819 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3820 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3821
3822 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3823 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3824 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003825 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003826 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003827 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3828 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3829 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3830 .WillRepeatedly(Return());
3831
3832 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003833 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003834 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003835 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003836 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003837
3838 verify().execute().expectAFenceWasReturned();
3839 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3840
3841 verify().execute().expectAFenceWasReturned();
3842 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3843}
3844
Lloyd Pique6818fa52019-12-03 12:32:13 -08003845struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3846 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3847 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003848 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Alec Mourif97df4d2023-09-06 02:10:05 +00003849 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003850 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003851 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3852 .WillRepeatedly(Return());
3853 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3854 }
3855
3856 struct MixedCompositionState
3857 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3858 auto ifMixedCompositionIs(bool used) {
3859 getInstance()->mOutput.mState.usesDeviceComposition = used;
3860 return nextState<OutputUsesHdrState>();
3861 }
3862 };
3863
3864 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3865 auto andIfUsesHdr(bool used) {
3866 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3867 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003868 return nextState<OutputWithDisplayBrightnessNits>();
3869 }
3870 };
3871
3872 struct OutputWithDisplayBrightnessNits
3873 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3874 auto withDisplayBrightnessNits(float nits) {
3875 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mourif97df4d2023-09-06 02:10:05 +00003876 return nextState<OutputWithSdrWhitePointNits>();
3877 }
3878 };
3879
3880 struct OutputWithSdrWhitePointNits
3881 : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> {
3882 auto withSdrWhitePointNits(float nits) {
3883 getInstance()->mOutput.mState.sdrWhitePointNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003884 return nextState<OutputWithDimmingStage>();
3885 }
3886 };
3887
3888 struct OutputWithDimmingStage
3889 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3890 auto withDimmingStage(
3891 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3892 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003893 return nextState<OutputWithRenderIntent>();
3894 }
3895 };
3896
3897 struct OutputWithRenderIntent
3898 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3899 auto withRenderIntent(
3900 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3901 getInstance()->mOutput.mState.renderIntent =
3902 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003903 return nextState<SkipColorTransformState>();
3904 }
3905 };
3906
3907 struct SkipColorTransformState
3908 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3909 auto andIfSkipColorTransform(bool skip) {
3910 // May be called zero or one times.
3911 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3912 .WillRepeatedly(Return(skip));
Alec Mourif97df4d2023-09-06 02:10:05 +00003913 return nextState<PixelFormatState>();
3914 }
3915 };
3916
3917 struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> {
3918 auto withPixelFormat(std::optional<PixelFormat> format) {
3919 // May be called zero or one times.
3920 if (format) {
3921 auto outputBuffer = std::make_shared<
3922 renderengine::impl::
3923 ExternalTexture>(sp<GraphicBuffer>::
3924 make(1u, 1u, *format,
3925 GRALLOC_USAGE_SW_WRITE_OFTEN |
3926 GRALLOC_USAGE_SW_READ_OFTEN),
3927 getInstance()->mRenderEngine,
3928 renderengine::impl::ExternalTexture::Usage::
3929 READABLE |
3930 renderengine::impl::ExternalTexture::
3931 Usage::WRITEABLE);
3932 EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_))
3933 .WillRepeatedly(Return(outputBuffer));
3934 }
3935 return nextState<DataspaceState>();
3936 }
3937 };
3938
3939 struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> {
3940 auto withDataspace(ui::Dataspace dataspace) {
3941 getInstance()->mOutput.mState.dataspace = dataspace;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003942 return nextState<ExpectDisplaySettingsState>();
3943 }
3944 };
3945
3946 struct ExpectDisplaySettingsState
3947 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3948 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00003949 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003950 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003951 return nextState<ExecuteState>();
3952 }
3953 };
3954
3955 // Call this member function to start using the mini-DSL defined above.
3956 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3957};
3958
3959TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3960 verify().ifMixedCompositionIs(true)
3961 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003962 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003963 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003964 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003965 .withRenderIntent(
3966 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003967 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003968 .withPixelFormat(std::nullopt)
3969 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00003970 .thenExpectDisplaySettingsUsed(
3971 {.physicalDisplay = kDefaultOutputDestinationClip,
3972 .clip = kDefaultOutputViewport,
3973 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003974 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003975 .outputDataspace = kDefaultOutputDataspace,
3976 .colorTransform = kDefaultColorTransformMat,
3977 .deviceHandlesColorTransform = true,
3978 .orientation = kDefaultOutputOrientationFlags,
3979 .targetLuminanceNits = kClientTargetLuminanceNits,
3980 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003981 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3982 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3983 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003984 .execute()
3985 .expectAFenceWasReturned();
3986}
3987
3988TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3989 forHdrMixedCompositionWithDisplayBrightness) {
3990 verify().ifMixedCompositionIs(true)
3991 .andIfUsesHdr(true)
3992 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003993 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003994 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003995 .withRenderIntent(
3996 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003997 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003998 .withPixelFormat(std::nullopt)
3999 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004000 .thenExpectDisplaySettingsUsed(
4001 {.physicalDisplay = kDefaultOutputDestinationClip,
4002 .clip = kDefaultOutputViewport,
4003 .maxLuminance = kDefaultMaxLuminance,
4004 .currentLuminanceNits = kDisplayLuminance,
4005 .outputDataspace = kDefaultOutputDataspace,
4006 .colorTransform = kDefaultColorTransformMat,
4007 .deviceHandlesColorTransform = true,
4008 .orientation = kDefaultOutputOrientationFlags,
4009 .targetLuminanceNits = kClientTargetLuminanceNits,
4010 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004011 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4012 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4013 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00004014 .execute()
4015 .expectAFenceWasReturned();
4016}
4017
4018TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4019 forHdrMixedCompositionWithDimmingStage) {
4020 verify().ifMixedCompositionIs(true)
4021 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004022 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004023 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004024 .withDimmingStage(
4025 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004026 .withRenderIntent(
4027 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004028 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004029 .withPixelFormat(std::nullopt)
4030 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004031 .thenExpectDisplaySettingsUsed(
4032 {.physicalDisplay = kDefaultOutputDestinationClip,
4033 .clip = kDefaultOutputViewport,
4034 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004035 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004036 .outputDataspace = kDefaultOutputDataspace,
4037 .colorTransform = kDefaultColorTransformMat,
4038 .deviceHandlesColorTransform = true,
4039 .orientation = kDefaultOutputOrientationFlags,
4040 .targetLuminanceNits = kClientTargetLuminanceNits,
4041 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004042 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
4043 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4044 COLORIMETRIC})
4045 .execute()
4046 .expectAFenceWasReturned();
4047}
4048
4049TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4050 forHdrMixedCompositionWithRenderIntent) {
4051 verify().ifMixedCompositionIs(true)
4052 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004053 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004054 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004055 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4056 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
4057 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004058 .withPixelFormat(std::nullopt)
4059 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004060 .thenExpectDisplaySettingsUsed(
4061 {.physicalDisplay = kDefaultOutputDestinationClip,
4062 .clip = kDefaultOutputViewport,
4063 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004064 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004065 .outputDataspace = kDefaultOutputDataspace,
4066 .colorTransform = kDefaultColorTransformMat,
4067 .deviceHandlesColorTransform = true,
4068 .orientation = kDefaultOutputOrientationFlags,
4069 .targetLuminanceNits = kClientTargetLuminanceNits,
4070 .dimmingStage =
4071 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4072 .renderIntent =
4073 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
4074 .execute()
4075 .expectAFenceWasReturned();
4076}
4077
4078TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
4079 verify().ifMixedCompositionIs(true)
4080 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004081 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004082 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004083 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4084 .withRenderIntent(
4085 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4086 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004087 .withPixelFormat(std::nullopt)
4088 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004089 .thenExpectDisplaySettingsUsed(
4090 {.physicalDisplay = kDefaultOutputDestinationClip,
4091 .clip = kDefaultOutputViewport,
4092 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004093 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004094 .outputDataspace = kDefaultOutputDataspace,
4095 .colorTransform = kDefaultColorTransformMat,
4096 .deviceHandlesColorTransform = true,
4097 .orientation = kDefaultOutputOrientationFlags,
4098 .targetLuminanceNits = kClientTargetLuminanceNits,
4099 .dimmingStage =
4100 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4101 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4102 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004103 .execute()
4104 .expectAFenceWasReturned();
4105}
4106
4107TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
4108 verify().ifMixedCompositionIs(false)
4109 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004110 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004111 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004112 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004113 .withRenderIntent(
4114 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004115 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004116 .withPixelFormat(std::nullopt)
4117 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004118 .thenExpectDisplaySettingsUsed(
4119 {.physicalDisplay = kDefaultOutputDestinationClip,
4120 .clip = kDefaultOutputViewport,
4121 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004122 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004123 .outputDataspace = kDefaultOutputDataspace,
4124 .colorTransform = kDefaultColorTransformMat,
4125 .deviceHandlesColorTransform = false,
4126 .orientation = kDefaultOutputOrientationFlags,
4127 .targetLuminanceNits = kClientTargetLuminanceNits,
4128 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004129 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4130 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4131 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004132 .execute()
4133 .expectAFenceWasReturned();
4134}
4135
4136TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
4137 verify().ifMixedCompositionIs(false)
4138 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004139 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004140 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004141 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004142 .withRenderIntent(
4143 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004144 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004145 .withPixelFormat(std::nullopt)
4146 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004147 .thenExpectDisplaySettingsUsed(
4148 {.physicalDisplay = kDefaultOutputDestinationClip,
4149 .clip = kDefaultOutputViewport,
4150 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004151 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004152 .outputDataspace = kDefaultOutputDataspace,
4153 .colorTransform = kDefaultColorTransformMat,
4154 .deviceHandlesColorTransform = false,
4155 .orientation = kDefaultOutputOrientationFlags,
4156 .targetLuminanceNits = kClientTargetLuminanceNits,
4157 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004158 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4159 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4160 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004161 .execute()
4162 .expectAFenceWasReturned();
4163}
4164
4165TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4166 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4167 verify().ifMixedCompositionIs(false)
4168 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004169 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004170 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004171 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004172 .withRenderIntent(
4173 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004174 .andIfSkipColorTransform(true)
Alec Mourif97df4d2023-09-06 02:10:05 +00004175 .withPixelFormat(std::nullopt)
4176 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004177 .thenExpectDisplaySettingsUsed(
4178 {.physicalDisplay = kDefaultOutputDestinationClip,
4179 .clip = kDefaultOutputViewport,
4180 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004181 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004182 .outputDataspace = kDefaultOutputDataspace,
4183 .colorTransform = kDefaultColorTransformMat,
4184 .deviceHandlesColorTransform = true,
4185 .orientation = kDefaultOutputOrientationFlags,
4186 .targetLuminanceNits = kClientTargetLuminanceNits,
4187 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004188 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4189 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4190 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004191 .execute()
4192 .expectAFenceWasReturned();
4193}
4194
Alec Mourif97df4d2023-09-06 02:10:05 +00004195TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4196 usesExpectedDisplaySettingsWithFp16Buffer) {
4197 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
Alec Mourif97df4d2023-09-06 02:10:05 +00004198 verify().ifMixedCompositionIs(false)
4199 .andIfUsesHdr(true)
4200 .withDisplayBrightnessNits(kDisplayLuminance)
4201 .withSdrWhitePointNits(kWhitePointLuminance)
4202 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4203 .withRenderIntent(
4204 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4205 .andIfSkipColorTransform(true)
4206 .withPixelFormat(PIXEL_FORMAT_RGBA_FP16)
4207 .withDataspace(ui::Dataspace::V0_SCRGB)
4208 .thenExpectDisplaySettingsUsed(
4209 {.physicalDisplay = kDefaultOutputDestinationClip,
4210 .clip = kDefaultOutputViewport,
4211 .maxLuminance = kDefaultMaxLuminance,
4212 .currentLuminanceNits = kDisplayLuminance,
4213 .outputDataspace = ui::Dataspace::V0_SCRGB,
4214 .colorTransform = kDefaultColorTransformMat,
4215 .deviceHandlesColorTransform = true,
4216 .orientation = kDefaultOutputOrientationFlags,
4217 .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f,
4218 .dimmingStage =
4219 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4220 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4221 COLORIMETRIC})
4222 .execute()
4223 .expectAFenceWasReturned();
4224}
4225
Lloyd Pique6818fa52019-12-03 12:32:13 -08004226struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4227 struct Layer {
4228 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004229 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4230 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Eason Chiu45099662023-10-23 08:55:48 +08004231 EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004232 }
4233
4234 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004235 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004236 LayerFECompositionState mLayerFEState;
4237 };
4238
4239 OutputComposeSurfacesTest_HandlesProtectedContent() {
4240 mLayer1.mLayerFEState.hasProtectedContent = false;
4241 mLayer2.mLayerFEState.hasProtectedContent = false;
4242
4243 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4244 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4245 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4246 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4247 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4248
4249 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4250
4251 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4252
Robert Carrccab4242021-09-28 16:53:03 -07004253 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004254 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004255 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4256 .WillRepeatedly(Return());
4257 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004258 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004259 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4260 const std::vector<renderengine::LayerSettings>&,
4261 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00004262 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00004263 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4264 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004265 }
4266
4267 Layer mLayer1;
4268 Layer mLayer2;
4269};
4270
Lloyd Pique6818fa52019-12-03 12:32:13 -08004271TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
Eason Chiu45099662023-10-23 08:55:48 +08004272 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004273 if (FlagManager::getInstance().display_protected()) {
4274 mOutput.mState.isProtected = true;
4275 } else {
4276 mOutput.mState.isSecure = true;
4277 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004278 mLayer2.mLayerFEState.hasProtectedContent = false;
4279 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004280 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004281 EXPECT_CALL(*mRenderSurface, setProtected(false));
4282
Vishnu Naira3140382022-02-24 14:07:11 -08004283 base::unique_fd fd;
4284 std::shared_ptr<renderengine::ExternalTexture> tex;
4285 mOutput.updateProtectedContentState();
4286 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004287 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004288}
4289
4290TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
Eason Chiu45099662023-10-23 08:55:48 +08004291 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004292 if (FlagManager::getInstance().display_protected()) {
4293 mOutput.mState.isProtected = true;
4294 } else {
4295 mOutput.mState.isSecure = true;
4296 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004297 mLayer2.mLayerFEState.hasProtectedContent = true;
4298 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4299
4300 // For this test, we also check the call order of key functions.
4301 InSequence seq;
4302
Lloyd Pique6818fa52019-12-03 12:32:13 -08004303 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004304 EXPECT_CALL(*mRenderSurface, setProtected(true));
4305 // Must happen after setting the protected content state.
4306 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004307 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004308 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004309
Vishnu Naira3140382022-02-24 14:07:11 -08004310 base::unique_fd fd;
4311 std::shared_ptr<renderengine::ExternalTexture> tex;
4312 mOutput.updateProtectedContentState();
4313 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004314 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004315}
4316
4317TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
Eason Chiu45099662023-10-23 08:55:48 +08004318 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004319 if (FlagManager::getInstance().display_protected()) {
4320 mOutput.mState.isProtected = true;
4321 } else {
4322 mOutput.mState.isSecure = true;
4323 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004324 mLayer2.mLayerFEState.hasProtectedContent = true;
4325 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004326 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4327
Vishnu Naira3140382022-02-24 14:07:11 -08004328 base::unique_fd fd;
4329 std::shared_ptr<renderengine::ExternalTexture> tex;
4330 mOutput.updateProtectedContentState();
4331 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004332 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004333}
4334
Lloyd Pique6818fa52019-12-03 12:32:13 -08004335TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
Eason Chiu45099662023-10-23 08:55:48 +08004336 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004337 if (FlagManager::getInstance().display_protected()) {
4338 mOutput.mState.isProtected = true;
4339 } else {
4340 mOutput.mState.isSecure = true;
4341 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004342 mLayer2.mLayerFEState.hasProtectedContent = true;
4343 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004344 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004345
Vishnu Naira3140382022-02-24 14:07:11 -08004346 base::unique_fd fd;
4347 std::shared_ptr<renderengine::ExternalTexture> tex;
4348 mOutput.updateProtectedContentState();
4349 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004350 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004351}
4352
4353struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4354 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4355 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4356 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4357 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004358 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004359 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4360 .WillRepeatedly(Return());
4361 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4362 }
4363};
4364
4365TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4366 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4367
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004368 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004369 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004370 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004371
4372 // For this test, we also check the call order of key functions.
4373 InSequence seq;
4374
4375 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004376 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004377 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004378
Vishnu Naira3140382022-02-24 14:07:11 -08004379 base::unique_fd fd;
4380 std::shared_ptr<renderengine::ExternalTexture> tex;
4381 mOutput.updateProtectedContentState();
4382 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004383 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004384}
4385
4386/*
4387 * Output::generateClientCompositionRequests()
4388 */
4389
4390struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004391 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004392 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004393 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004394 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004395 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004396 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004397 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004398 }
4399 };
4400
Lloyd Piquea4863342019-12-04 18:45:02 -08004401 struct Layer {
4402 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004403 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4404 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004405 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4406 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004407 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4408 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004409 }
4410
4411 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004412 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004413 LayerFECompositionState mLayerFEState;
4414 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004415 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004416 };
4417
Lloyd Pique56eba802019-08-28 15:45:25 -07004418 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004419 mOutput.mState.needsFiltering = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004420 mOutput.mState.isProtected = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08004421
Lloyd Pique56eba802019-08-28 15:45:25 -07004422 mOutput.setDisplayColorProfileForTest(
4423 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4424 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4425 }
4426
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004427 static constexpr float kLayerWhitePointNits = 200.f;
4428
Lloyd Pique56eba802019-08-28 15:45:25 -07004429 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4430 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004431 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004432};
4433
Lloyd Piquea4863342019-12-04 18:45:02 -08004434struct GenerateClientCompositionRequestsTest_ThreeLayers
4435 : public GenerateClientCompositionRequestsTest {
4436 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004437 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4438 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4439 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004440 mOutput.mState.transform =
4441 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004442 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004443 mOutput.mState.needsFiltering = false;
4444 mOutput.mState.isSecure = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004445 mOutput.mState.isProtected = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07004446
Lloyd Piquea4863342019-12-04 18:45:02 -08004447 for (size_t i = 0; i < mLayers.size(); i++) {
4448 mLayers[i].mOutputLayerState.clearClientTarget = false;
4449 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4450 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004451 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004452 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004453 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4454 mLayers[i].mLayerSettings.alpha = 1.0f;
4455 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004456
Lloyd Piquea4863342019-12-04 18:45:02 -08004457 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4458 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4459 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4460 .WillRepeatedly(Return(true));
4461 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4462 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004463
Lloyd Piquea4863342019-12-04 18:45:02 -08004464 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4465 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004466
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004467 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004468 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004469 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004470
Lloyd Piquea4863342019-12-04 18:45:02 -08004471 static const Rect kDisplayFrame;
4472 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004473 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004474
Lloyd Piquea4863342019-12-04 18:45:02 -08004475 std::array<Layer, 3> mLayers;
4476};
Lloyd Pique56eba802019-08-28 15:45:25 -07004477
Lloyd Piquea4863342019-12-04 18:45:02 -08004478const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4479const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004480const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4481 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004482
Lloyd Piquea4863342019-12-04 18:45:02 -08004483TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4484 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4485 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4486 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004487
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004488 auto requests =
4489 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4490 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004491 EXPECT_EQ(0u, requests.size());
4492}
4493
Lloyd Piquea4863342019-12-04 18:45:02 -08004494TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4495 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4496 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4497 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4498
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004499 auto requests =
4500 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4501 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004502 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004503}
4504
4505TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004506 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4507 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4508 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4509 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4510 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4511 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004512
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004513 auto requests =
4514 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4515 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004516 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004517 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004518 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004519
Lloyd Piquea4863342019-12-04 18:45:02 -08004520 // Check that a timestamp was set for the layers that generated requests
4521 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4522 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4523 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4524}
4525
Alec Mourif54453c2021-05-13 16:28:28 -07004526MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4527 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4528 *result_listener << "expected " << expectedBlurSetting << "\n";
4529 *result_listener << "actual " << arg.blurSetting << "\n";
4530
4531 return expectedBlurSetting == arg.blurSetting;
4532}
4533
4534TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004535 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4536
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004537 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4538 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4539 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4540 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004541 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004542 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004543 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004544 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004545 auto requests =
4546 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4547 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004548 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004549 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004550 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004551
Alec Mourif54453c2021-05-13 16:28:28 -07004552 // Check that a timestamp was set for the layers that generated requests
4553 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4554 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4555 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4556}
4557
Lloyd Piquea4863342019-12-04 18:45:02 -08004558TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4559 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4560 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4561 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4562 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4563
4564 mLayers[0].mOutputLayerState.clearClientTarget = false;
4565 mLayers[1].mOutputLayerState.clearClientTarget = false;
4566 mLayers[2].mOutputLayerState.clearClientTarget = false;
4567
4568 mLayers[0].mLayerFEState.isOpaque = true;
4569 mLayers[1].mLayerFEState.isOpaque = true;
4570 mLayers[2].mLayerFEState.isOpaque = true;
4571
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004572 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4573 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004574
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004575 auto requests =
4576 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4577 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004579 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004580}
4581
4582TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4583 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4584 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4585 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4586 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4587
4588 mLayers[0].mOutputLayerState.clearClientTarget = true;
4589 mLayers[1].mOutputLayerState.clearClientTarget = true;
4590 mLayers[2].mOutputLayerState.clearClientTarget = true;
4591
4592 mLayers[0].mLayerFEState.isOpaque = false;
4593 mLayers[1].mLayerFEState.isOpaque = false;
4594 mLayers[2].mLayerFEState.isOpaque = false;
4595
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004596 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4597 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004598
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004599 auto requests =
4600 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4601 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004602 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004603 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004604}
4605
4606TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004607 // If client composition is performed with some layers set to use device
4608 // composition, device layers after the first layer (device or client) will
4609 // clear the frame buffer if they are opaque and if that layer has a flag
4610 // set to do so. The first layer is skipped as the frame buffer is already
4611 // expected to be clear.
4612
Lloyd Piquea4863342019-12-04 18:45:02 -08004613 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4614 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4615 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004616
Lloyd Piquea4863342019-12-04 18:45:02 -08004617 mLayers[0].mOutputLayerState.clearClientTarget = true;
4618 mLayers[1].mOutputLayerState.clearClientTarget = true;
4619 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004620
Lloyd Piquea4863342019-12-04 18:45:02 -08004621 mLayers[0].mLayerFEState.isOpaque = true;
4622 mLayers[1].mLayerFEState.isOpaque = true;
4623 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004624
4625 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4626 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004627 false, /* needs filtering */
4628 false, /* secure */
4629 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004630 kDisplayViewport,
4631 kDisplayDataspace,
4632 false /* realContentIsVisible */,
4633 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004634 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004635 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004636 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004637 };
4638 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4639 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004640 false, /* needs filtering */
4641 false, /* secure */
4642 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004643 kDisplayViewport,
4644 kDisplayDataspace,
4645 true /* realContentIsVisible */,
4646 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004647 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004648 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004649 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004650 };
4651
4652 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4653 mBlackoutSettings.source.buffer.buffer = nullptr;
4654 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4655 mBlackoutSettings.alpha = 0.f;
4656 mBlackoutSettings.disableBlending = true;
4657
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004658 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4659 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4660 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4661 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004662
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004663 auto requests =
4664 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4665 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004666 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004667
Lloyd Piquea4863342019-12-04 18:45:02 -08004668 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004669 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004670
Vishnu Nair9b079a22020-01-21 14:36:08 -08004671 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004672}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004673
Lloyd Piquea4863342019-12-04 18:45:02 -08004674TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4675 clippedVisibleRegionUsedToGenerateRequest) {
4676 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4677 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4678 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004679
Lloyd Piquea4863342019-12-04 18:45:02 -08004680 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4681 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004682 false, /* needs filtering */
4683 false, /* secure */
4684 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004685 kDisplayViewport,
4686 kDisplayDataspace,
4687 true /* realContentIsVisible */,
4688 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004689 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004690 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004691 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004692 };
4693 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4694 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004695 false, /* needs filtering */
4696 false, /* secure */
4697 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004698 kDisplayViewport,
4699 kDisplayDataspace,
4700 true /* realContentIsVisible */,
4701 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004702 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004703 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004704 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004705 };
4706 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4707 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004708 false, /* needs filtering */
4709 false, /* secure */
4710 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004711 kDisplayViewport,
4712 kDisplayDataspace,
4713 true /* realContentIsVisible */,
4714 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004715 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004716 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004717 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004718 };
4719
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004720 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4721 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4722 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4723 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4724 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4725 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004726
4727 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004728 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004729 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004730}
4731
4732TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4733 perLayerNeedsFilteringUsedToGenerateRequests) {
4734 mOutput.mState.needsFiltering = false;
4735 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4736
Lloyd Piquea4863342019-12-04 18:45:02 -08004737 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4738 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004739 true, /* needs filtering */
4740 false, /* secure */
4741 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004742 kDisplayViewport,
4743 kDisplayDataspace,
4744 true /* realContentIsVisible */,
4745 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004746 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004747 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004748 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004749 };
4750 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4751 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004752 false, /* needs filtering */
4753 false, /* secure */
4754 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004755 kDisplayViewport,
4756 kDisplayDataspace,
4757 true /* realContentIsVisible */,
4758 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004759 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004760 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004761 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004762 };
4763 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4764 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004765 false, /* needs filtering */
4766 false, /* secure */
4767 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004768 kDisplayViewport,
4769 kDisplayDataspace,
4770 true /* realContentIsVisible */,
4771 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004772 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004773 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004774 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004775 };
4776
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004777 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4778 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4779 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4780 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4781 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4782 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004783
4784 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004785 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4786 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004787}
4788
4789TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4790 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4791 mOutput.mState.needsFiltering = true;
4792 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4793
Lloyd Piquea4863342019-12-04 18:45:02 -08004794 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4795 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004796 true, /* needs filtering */
4797 false, /* secure */
4798 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004799 kDisplayViewport,
4800 kDisplayDataspace,
4801 true /* realContentIsVisible */,
4802 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004803 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004804 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004805 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004806 };
4807 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4808 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004809 true, /* needs filtering */
4810 false, /* secure */
4811 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004812 kDisplayViewport,
4813 kDisplayDataspace,
4814 true /* realContentIsVisible */,
4815 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004816 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004817 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004818 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004819 };
4820 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4821 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004822 true, /* needs filtering */
4823 false, /* secure */
4824 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004825 kDisplayViewport,
4826 kDisplayDataspace,
4827 true /* realContentIsVisible */,
4828 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004829 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004830 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004831 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004832 };
4833
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004834 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4835 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4836 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4837 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4838 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4839 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004840
4841 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004842 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4843 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004844}
4845
4846TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4847 wholeOutputSecurityUsedToGenerateRequests) {
4848 mOutput.mState.isSecure = true;
4849
Lloyd Piquea4863342019-12-04 18:45:02 -08004850 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4851 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004852 false, /* needs filtering */
4853 true, /* secure */
4854 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004855 kDisplayViewport,
4856 kDisplayDataspace,
4857 true /* realContentIsVisible */,
4858 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004859 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004860 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004861 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004862 };
4863 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4864 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004865 false, /* needs filtering */
4866 true, /* secure */
4867 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004868 kDisplayViewport,
4869 kDisplayDataspace,
4870 true /* realContentIsVisible */,
4871 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004872 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004873 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004874 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004875 };
4876 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4877 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004878 false, /* needs filtering */
4879 true, /* secure */
4880 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004881 kDisplayViewport,
4882 kDisplayDataspace,
4883 true /* realContentIsVisible */,
4884 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004885 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004886 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004887 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004888 };
4889
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004890 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4891 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4892 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4893 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4894 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4895 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004896
4897 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004898 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4899 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004900}
4901
4902TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4903 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004904 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4905 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004906 false, /* needs filtering */
4907 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004908 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004909 kDisplayViewport,
4910 kDisplayDataspace,
4911 true /* realContentIsVisible */,
4912 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004913 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004914 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004915 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004916 };
4917 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4918 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004919 false, /* needs filtering */
4920 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004921 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004922 kDisplayViewport,
4923 kDisplayDataspace,
4924 true /* realContentIsVisible */,
4925 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004926 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004927 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004928 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004929 };
4930 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4931 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004932 false, /* needs filtering */
4933 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004934 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004935 kDisplayViewport,
4936 kDisplayDataspace,
4937 true /* realContentIsVisible */,
4938 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004939 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004940 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004941 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004942 };
4943
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004944 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4945 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4946 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4947 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4948 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4949 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004950
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004951 static_cast<void>(
4952 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4953 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004954}
4955
Lucas Dupin084a6d42021-08-26 22:10:29 +00004956TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4957 InjectedLayer layer1;
4958 InjectedLayer layer2;
4959
4960 uint32_t z = 0;
4961 // Layer requesting blur, or below, should request client composition, unless opaque.
Sally Qi0abc4a52024-09-26 16:13:06 -07004962 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004963 EXPECT_CALL(*layer1.outputLayer,
4964 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4965 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004966 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07004967 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004968 EXPECT_CALL(*layer2.outputLayer,
4969 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4970 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004971 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004972
4973 layer2.layerFEState.backgroundBlurRadius = 10;
4974 layer2.layerFEState.isOpaque = true;
4975
4976 injectOutputLayer(layer1);
4977 injectOutputLayer(layer2);
4978
4979 mOutput->editState().isEnabled = true;
4980
4981 CompositionRefreshArgs args;
4982 args.updatingGeometryThisFrame = false;
4983 args.devOptForceClientComposition = false;
4984 mOutput->updateCompositionState(args);
4985 mOutput->planComposition();
4986 mOutput->writeCompositionState(args);
4987}
4988
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004989TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004990 InjectedLayer layer1;
4991 InjectedLayer layer2;
4992 InjectedLayer layer3;
4993
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004994 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004995 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07004996 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08004997 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004998 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4999 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005000 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005001 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005002 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005003 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5004 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005005 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005006 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005007 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005008 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5009 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005010 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005011
Lloyd Piquede196652020-01-22 17:29:58 -08005012 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00005013 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005014
Lloyd Piquede196652020-01-22 17:29:58 -08005015 injectOutputLayer(layer1);
5016 injectOutputLayer(layer2);
5017 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005018
5019 mOutput->editState().isEnabled = true;
5020
5021 CompositionRefreshArgs args;
5022 args.updatingGeometryThisFrame = false;
5023 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005024 mOutput->updateCompositionState(args);
5025 mOutput->planComposition();
5026 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005027}
5028
Lucas Dupinc3800b82020-10-02 16:24:48 -07005029TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
5030 InjectedLayer layer1;
5031 InjectedLayer layer2;
5032 InjectedLayer layer3;
5033
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005034 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005035 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07005036 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005037 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005038 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5039 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005040 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005041 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005042 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005043 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5044 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005045 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005046 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005047 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005048 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5049 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005050 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005051
5052 BlurRegion region;
5053 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00005054 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005055
5056 injectOutputLayer(layer1);
5057 injectOutputLayer(layer2);
5058 injectOutputLayer(layer3);
5059
5060 mOutput->editState().isEnabled = true;
5061
5062 CompositionRefreshArgs args;
5063 args.updatingGeometryThisFrame = false;
5064 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005065 mOutput->updateCompositionState(args);
5066 mOutput->planComposition();
5067 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07005068}
5069
Brian Lindahl1a4ffd82024-10-30 11:00:37 -06005070TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsDisplayProfileBasedOnLayerPriority) {
5071 if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
5072 GTEST_SKIP() << "Feature flag disabled, skipping";
5073 }
5074
5075 mOutput->setDisplayIdForTest(PhysicalDisplayId::fromPort(1));
5076 // Has only one display-global picture processing pipeline
5077 mOutput->setHasPictureProcessingForTest(true);
5078 mOutput->setMaxLayerPictureProfilesForTest(0);
5079
5080 InjectedLayer layer1;
5081 injectOutputLayer(layer1);
5082 PictureProfileHandle profileForLayer1(1);
5083 EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3));
5084 EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle())
5085 .WillRepeatedly(ReturnRef(profileForLayer1));
5086
5087 InjectedLayer layer2;
5088 injectOutputLayer(layer2);
5089 PictureProfileHandle profileForLayer2(2);
5090 EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1));
5091 EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle())
5092 .WillRepeatedly(ReturnRef(profileForLayer2));
5093
5094 InjectedLayer layer3;
5095 injectOutputLayer(layer3);
5096 PictureProfileHandle profileForLayer3(3);
5097 EXPECT_CALL(*layer3.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(2));
5098 EXPECT_CALL(*layer3.outputLayer, getPictureProfileHandle())
5099 .WillRepeatedly(ReturnRef(profileForLayer3));
5100
5101 // Because StrictMock
5102 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5103 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _));
5104 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _));
5105 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5106 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _));
5107 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _));
5108 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5109 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _));
5110 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _));
5111
5112 // No layer picture profiles should be committed
5113 EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0);
5114 EXPECT_CALL(*layer2.outputLayer, commitPictureProfileToCompositionState).Times(0);
5115 EXPECT_CALL(*layer3.outputLayer, commitPictureProfileToCompositionState).Times(0);
5116
5117 // Sets display picture profile to the highest priority layer's profile
5118 EXPECT_CALL(mHwComposer, setDisplayPictureProfileHandle(_, Eq(profileForLayer2)));
5119
Brian Lindahlf5fdff82024-11-01 09:28:47 -06005120 // Marks only the highest priority layer as committed
5121 EXPECT_CALL(*layer1.layerFE, onPictureProfileCommitted).Times(0);
5122 EXPECT_CALL(*layer2.layerFE, onPictureProfileCommitted);
5123 EXPECT_CALL(*layer3.layerFE, onPictureProfileCommitted).Times(0);
5124
Brian Lindahl1a4ffd82024-10-30 11:00:37 -06005125 mOutput->editState().isEnabled = true;
5126 CompositionRefreshArgs args;
5127 args.updatingGeometryThisFrame = false;
5128 args.devOptForceClientComposition = false;
5129 mOutput->updateCompositionState(args);
5130 mOutput->planComposition();
5131 mOutput->writeCompositionState(args);
5132}
5133
5134TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsLayerProfileBasedOnLayerPriority) {
5135 if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
5136 GTEST_SKIP() << "Feature flag disabled, skipping";
5137 }
5138 mOutput->setDisplayIdForTest(PhysicalDisplayId::fromPort(1));
5139 // Has 2 layer-specific picture processing pipelines
5140 mOutput->setHasPictureProcessingForTest(true);
5141 mOutput->setMaxLayerPictureProfilesForTest(2);
5142
5143 InjectedLayer layer1;
5144 injectOutputLayer(layer1);
5145 PictureProfileHandle profileForLayer1(1);
5146 EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3));
5147 EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle())
5148 .WillRepeatedly(ReturnRef(profileForLayer1));
5149
5150 InjectedLayer layer2;
5151 injectOutputLayer(layer2);
5152 PictureProfileHandle profileForLayer2(2);
5153 EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1));
5154 EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle())
5155 .WillRepeatedly(ReturnRef(profileForLayer2));
5156
5157 InjectedLayer layer3;
5158 injectOutputLayer(layer3);
5159 PictureProfileHandle profileForLayer3(3);
5160 EXPECT_CALL(*layer3.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(2));
5161 EXPECT_CALL(*layer3.outputLayer, getPictureProfileHandle())
5162 .WillRepeatedly(ReturnRef(profileForLayer3));
5163
5164 // Because StrictMock
5165 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5166 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _));
5167 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _));
5168 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5169 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _));
5170 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _));
5171 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5172 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _));
5173 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _));
5174
5175 // The two highest priority layers should have their picture profiles committed
5176 EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0);
5177 EXPECT_CALL(*layer2.outputLayer, commitPictureProfileToCompositionState);
5178 EXPECT_CALL(*layer3.outputLayer, commitPictureProfileToCompositionState);
5179
Brian Lindahlf5fdff82024-11-01 09:28:47 -06005180 // Marks only the highest priority layers as committed
5181 EXPECT_CALL(*layer1.layerFE, onPictureProfileCommitted).Times(0);
5182 EXPECT_CALL(*layer2.layerFE, onPictureProfileCommitted);
5183 EXPECT_CALL(*layer3.layerFE, onPictureProfileCommitted);
5184
Brian Lindahl1a4ffd82024-10-30 11:00:37 -06005185 // No display picture profile is sent
5186 EXPECT_CALL(mHwComposer, setDisplayPictureProfileHandle).Times(0);
5187
5188 mOutput->editState().isEnabled = true;
5189 CompositionRefreshArgs args;
5190 args.updatingGeometryThisFrame = false;
5191 args.devOptForceClientComposition = false;
5192 mOutput->updateCompositionState(args);
5193 mOutput->planComposition();
5194 mOutput->writeCompositionState(args);
5195}
5196
Lloyd Piquea4863342019-12-04 18:45:02 -08005197TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
5198 // In split-screen landscape mode, the screen is rotated 90 degrees, with
5199 // one layer on the left covering the left side of the output, and one layer
5200 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005201
5202 const Rect kPortraitFrame(0, 0, 1000, 2000);
5203 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08005204 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005205 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08005206 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005207
Angel Aguayob084e0c2021-08-04 23:27:28 +00005208 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
5209 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
5210 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005211 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00005212 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08005213 mOutput.mState.needsFiltering = false;
5214 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005215
Lloyd Piquea4863342019-12-04 18:45:02 -08005216 Layer leftLayer;
5217 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005218
Lloyd Piquea4863342019-12-04 18:45:02 -08005219 leftLayer.mOutputLayerState.clearClientTarget = false;
5220 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
5221 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005222 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005223
Lloyd Piquea4863342019-12-04 18:45:02 -08005224 rightLayer.mOutputLayerState.clearClientTarget = false;
5225 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5226 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005227 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005228
5229 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5230 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5231 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5232 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5233 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5234
Lloyd Piquea4863342019-12-04 18:45:02 -08005235 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5236 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005237 false, /* needs filtering */
5238 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005239 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005240 kPortraitViewport,
5241 kOutputDataspace,
5242 true /* realContentIsVisible */,
5243 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005244 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005245 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005246 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005247 };
5248
5249 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5250 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005251 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
5252 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005253
5254 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5255 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005256 false, /* needs filtering */
5257 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005258 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005259 kPortraitViewport,
5260 kOutputDataspace,
5261 true /* realContentIsVisible */,
5262 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005263 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005264 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005265 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005266 };
5267
5268 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5269 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005270 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5271 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005272
5273 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005274 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
5275 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005276 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005277 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5278 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005279}
5280
Vishnu Naira483b4a2019-12-12 15:07:52 -08005281TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5282 shadowRegionOnlyVisibleSkipsContentComposition) {
5283 const Rect kContentWithShadow(40, 40, 70, 90);
5284 const Rect kContent(50, 50, 60, 80);
5285 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5286 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5287
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005288 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5289 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005290 false, /* needs filtering */
5291 false, /* secure */
5292 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005293 kDisplayViewport,
5294 kDisplayDataspace,
5295 false /* realContentIsVisible */,
5296 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005297 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005298 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005299 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005300 };
5301
Vishnu Nair9b079a22020-01-21 14:36:08 -08005302 LayerFE::LayerSettings mShadowSettings;
5303 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005304
5305 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5306 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5307
5308 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5309 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005310 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5311 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005312
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005313 auto requests =
5314 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5315 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005316 ASSERT_EQ(1u, requests.size());
5317
Vishnu Nair9b079a22020-01-21 14:36:08 -08005318 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005319}
5320
5321TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5322 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5323 const Rect kContentWithShadow(40, 40, 70, 90);
5324 const Rect kContent(50, 50, 60, 80);
5325 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5326 const Region kPartialContentWithPartialShadowRegion =
5327 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5328
Vishnu Naira483b4a2019-12-12 15:07:52 -08005329 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5330 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5331
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005332 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5333 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005334 false, /* needs filtering */
5335 false, /* secure */
5336 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005337 kDisplayViewport,
5338 kDisplayDataspace,
5339 true /* realContentIsVisible */,
5340 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005341 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005342 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005343 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005344 };
5345
Vishnu Naira483b4a2019-12-12 15:07:52 -08005346 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5347 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005348 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5349 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005350
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005351 auto requests =
5352 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5353 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005354 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005355
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005356 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005357}
5358
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005359struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
5360 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
5361 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
5362 // Set up the helper functions called by the function under test to use
5363 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005364 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
5365 MOCK_METHOD(ftl::Future<std::monostate>, presentFrameAndReleaseLayersAsync,
5366 (bool flushEvenWhenDisabled));
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005367 };
5368 OutputPresentFrameAndReleaseLayersAsyncTest() {
5369 mOutput->setDisplayColorProfileForTest(
5370 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
5371 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5372 mOutput->setCompositionEnabled(true);
5373 mRefreshArgs.outputs = {mOutput};
5374 }
5375
5376 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
5377 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
5378 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
5379 CompositionRefreshArgs mRefreshArgs;
5380};
5381
5382TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005383 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(_)).Times(0);
5384 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005385
5386 mOutput->present(mRefreshArgs);
5387}
5388
5389TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005390 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(false))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005391 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005392 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(0);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005393
5394 mOutput->offloadPresentNextFrame();
5395 mOutput->present(mRefreshArgs);
5396}
5397
5398TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
5399 ::testing::InSequence inseq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005400 constexpr bool kFlushEvenWhenDisabled = false;
5401 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(kFlushEvenWhenDisabled))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005402 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005403 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005404
5405 mOutput->offloadPresentNextFrame();
5406 mOutput->present(mRefreshArgs);
5407 mOutput->present(mRefreshArgs);
5408}
5409
Eason Chiu45099662023-10-23 08:55:48 +08005410/*
5411 * Output::updateProtectedContentState()
5412 */
5413
5414struct OutputUpdateProtectedContentStateTest : public testing::Test {
5415 struct OutputPartialMock : public OutputPartialMockBase {
5416 // Sets up the helper functions called by the function under test to use
5417 // mock implementations.
5418 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
5419 };
5420
5421 OutputUpdateProtectedContentStateTest() {
5422 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5423 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
5424 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
5425 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5426 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
5427 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
5428 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
5429 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
5430 }
5431
5432 struct Layer {
5433 Layer() {
5434 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
5435 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
5436 }
5437
5438 StrictMock<mock::OutputLayer> mOutputLayer;
5439 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
5440 LayerFECompositionState mLayerFEState;
5441 };
5442
5443 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
5444 StrictMock<OutputPartialMock> mOutput;
5445 StrictMock<mock::CompositionEngine> mCompositionEngine;
5446 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
5447 Layer mLayer1;
5448 Layer mLayer2;
5449};
5450
5451TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) {
5452 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5453 if (FlagManager::getInstance().display_protected()) {
5454 mOutput.mState.isProtected = true;
5455 } else {
5456 mOutput.mState.isSecure = true;
5457 }
5458 mLayer1.mLayerFEState.hasProtectedContent = false;
5459 mLayer2.mLayerFEState.hasProtectedContent = true;
5460 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5461 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5462 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5463 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5464 mOutput.updateProtectedContentState();
5465}
5466
5467TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) {
5468 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5469 if (FlagManager::getInstance().display_protected()) {
5470 mOutput.mState.isProtected = true;
5471 } else {
5472 mOutput.mState.isSecure = true;
5473 }
5474 mLayer1.mLayerFEState.hasProtectedContent = false;
5475 mLayer2.mLayerFEState.hasProtectedContent = true;
5476 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5477 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5478 EXPECT_CALL(*mRenderSurface, setProtected(true));
5479 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5480 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5481 mOutput.updateProtectedContentState();
5482}
5483
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005484struct OutputPresentFrameAndReleaseLayersTest : public testing::Test {
5485 struct OutputPartialMock : public OutputPartialMockBase {
5486 // Sets up the helper functions called by the function under test (and functions we can
5487 // ignore) to use mock implementations.
5488 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
5489 MOCK_METHOD1(updateCompositionState,
5490 void(const compositionengine::CompositionRefreshArgs&));
5491 MOCK_METHOD0(planComposition, void());
5492 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
5493 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
5494 MOCK_METHOD0(beginFrame, void());
5495 MOCK_METHOD0(prepareFrame, void());
5496 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
5497 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
5498 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
5499 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
5500 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
5501 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
5502 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
5503 (override));
5504 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
5505 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
5506 };
5507
5508 OutputPresentFrameAndReleaseLayersTest() {
5509 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
5510 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
5511 }
5512
5513 NiceMock<OutputPartialMock> mOutput;
5514};
5515
5516TEST_F(OutputPresentFrameAndReleaseLayersTest, noBuffersToUncache) {
5517 CompositionRefreshArgs args;
5518 ASSERT_TRUE(args.bufferIdsToUncache.empty());
5519 mOutput.editState().isEnabled = false;
5520
5521 constexpr bool kFlushEvenWhenDisabled = false;
5522 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5523
5524 mOutput.present(args);
5525}
5526
5527TEST_F(OutputPresentFrameAndReleaseLayersTest, buffersToUncache) {
5528 CompositionRefreshArgs args;
5529 args.bufferIdsToUncache.push_back(1);
5530 mOutput.editState().isEnabled = false;
5531
5532 constexpr bool kFlushEvenWhenDisabled = true;
5533 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5534
5535 mOutput.present(args);
5536}
5537
Lloyd Pique32cbe282018-10-19 13:09:22 -07005538} // namespace
5539} // namespace android::compositionengine