blob: bfd863b88aae8109795c930b7d9a235be0dcd73a [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>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080050using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080052using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080053using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080054using testing::Invoke;
55using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080056using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080057using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070060using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::StrictMock;
64
Lloyd Pique56eba802019-08-28 15:45:25 -070065constexpr auto TR_IDENT = 0u;
66constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070068
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080070const mat4 kNonIdentityHalf = mat4() * 0.5f;
71const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080072
Lloyd Pique17ca7422019-11-14 14:24:10 -080073constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
Vishnu Nair9cf89262022-02-26 09:17:49 -080076using CompositionStrategyPredictionState = android::compositionengine::impl::
77 OutputCompositionState::CompositionStrategyPredictionState;
78
Lloyd Piquefaa3f192019-11-14 14:05:09 -080079struct OutputPartialMockBase : public impl::Output {
80 // compositionengine::Output overrides
81 const OutputCompositionState& getState() const override { return mState; }
82 OutputCompositionState& editState() override { return mState; }
83
84 // Use mocks for all the remaining virtual functions
85 // not implemented by the base implementation class.
86 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
87 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD2(ensureOutputLayer,
89 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080090 MOCK_METHOD0(finalizePendingOutputLayers, void());
91 MOCK_METHOD0(clearOutputLayers, void());
92 MOCK_CONST_METHOD1(dumpState, void(std::string&));
93 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080094 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080095 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
96
97 impl::OutputCompositionState mState;
98};
99
Lloyd Piquede196652020-01-22 17:29:58 -0800100struct InjectedLayer {
101 InjectedLayer() {
102 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
103 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
104 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
105
106 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800107 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
108 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800109 }
110
111 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800112 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800113 LayerFECompositionState layerFEState;
114 impl::OutputLayerCompositionState outputLayerState;
115};
116
117struct NonInjectedLayer {
118 NonInjectedLayer() {
119 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
120 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
121 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
122
123 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800124 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
125 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800126 }
127
128 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800129 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800130 LayerFECompositionState layerFEState;
131 impl::OutputLayerCompositionState outputLayerState;
132};
133
Lloyd Pique66d68602019-02-13 14:23:31 -0800134struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700135 class Output : public impl::Output {
136 public:
137 using impl::Output::injectOutputLayerForTest;
138 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
139 };
140
141 static std::shared_ptr<Output> createOutput(
142 const compositionengine::CompositionEngine& compositionEngine) {
143 return impl::createOutputTemplated<Output>(compositionEngine);
144 }
145
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700148 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700149 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800150
Angel Aguayob084e0c2021-08-04 23:27:28 +0000151 mOutput->editState().displaySpace.setBounds(
152 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700153 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700155
Lloyd Piquede196652020-01-22 17:29:58 -0800156 void injectOutputLayer(InjectedLayer& layer) {
157 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
158 }
159
160 void injectNullOutputLayer() {
161 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
162 }
163
Lloyd Piqueef958122019-02-05 18:00:12 -0800164 static const Rect kDefaultDisplaySize;
165
Lloyd Pique32cbe282018-10-19 13:09:22 -0700166 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700167 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700170 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700171};
172
Lloyd Piqueef958122019-02-05 18:00:12 -0800173const Rect OutputTest::kDefaultDisplaySize{100, 200};
174
Lloyd Pique17ca7422019-11-14 14:24:10 -0800175using ColorProfile = compositionengine::Output::ColorProfile;
176
177void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
178 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
179 toString(profile.mode).c_str(), profile.mode,
180 toString(profile.dataspace).c_str(), profile.dataspace,
181 toString(profile.renderIntent).c_str(), profile.renderIntent,
182 toString(profile.colorSpaceAgnosticDataspace).c_str(),
183 profile.colorSpaceAgnosticDataspace);
184}
185
186// Checks for a ColorProfile match
187MATCHER_P(ColorProfileEq, expected, "") {
188 std::string buf;
189 buf.append("ColorProfiles are not equal\n");
190 dumpColorProfile(expected, buf, "expected value");
191 dumpColorProfile(arg, buf, "actual value");
192 *result_listener << buf;
193
194 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
195 (expected.renderIntent == arg.renderIntent) &&
196 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
197}
198
Lloyd Pique66d68602019-02-13 14:23:31 -0800199/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700200 * Basic construction
201 */
202
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203TEST_F(OutputTest, canInstantiateOutput) {
204 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700205 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
207
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209
210 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700211 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700212
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700213 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
214
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700215 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700216}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217
Lloyd Pique66d68602019-02-13 14:23:31 -0800218/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219 * Output::setCompositionEnabled()
220 */
221
222TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 EXPECT_TRUE(mOutput->getState().isEnabled);
228 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229}
230
231TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 EXPECT_TRUE(mOutput->getState().isEnabled);
237 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238}
239
240TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700243 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700245 EXPECT_FALSE(mOutput->getState().isEnabled);
246 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700247}
248
Lloyd Pique66d68602019-02-13 14:23:31 -0800249/*
Alec Mouridda07d92022-04-25 22:39:25 +0000250 * Output::setTreat170mAsSrgb()
251 */
252
253TEST_F(OutputTest, setTreat170mAsSrgb) {
254 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
255
256 mOutput->setTreat170mAsSrgb(true);
257 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
258
259 mOutput->setTreat170mAsSrgb(false);
260 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
261}
262
263/*
Alec Mouri023c1882021-05-08 16:36:33 -0700264 * Output::setLayerCachingEnabled()
265 */
266
267TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
268 const auto kSize = ui::Size(1, 1);
269 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
270 mOutput->setLayerCachingEnabled(false);
271 mOutput->setLayerCachingEnabled(true);
272
273 EXPECT_TRUE(mOutput->plannerEnabled());
274}
275
276TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
277 const auto kSize = ui::Size(1, 1);
278 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
279 mOutput->setLayerCachingEnabled(true);
280 mOutput->setLayerCachingEnabled(false);
281
282 EXPECT_FALSE(mOutput->plannerEnabled());
283}
284
Alec Mouric773472b2021-05-19 14:29:05 -0700285TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
286 renderengine::mock::RenderEngine renderEngine;
287 const auto kSize = ui::Size(1, 1);
288 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
289 mOutput->setLayerCachingEnabled(true);
290
291 // Inject some layers
292 InjectedLayer layer;
293 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800294 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700295 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800296 renderengine::impl::ExternalTexture::Usage::READABLE |
297 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700298 injectOutputLayer(layer);
299 // inject a null layer to check for null exceptions
300 injectNullOutputLayer();
301
302 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
303 mOutput->setLayerCachingEnabled(false);
304 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
305}
306
Alec Mouri023c1882021-05-08 16:36:33 -0700307/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308 * Output::setProjection()
309 */
310
Marin Shalamanov209ae612020-10-01 00:17:39 +0200311TEST_F(OutputTest, setProjectionWorks) {
312 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000313 mOutput->editState().displaySpace.setBounds(
314 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
315 mOutput->editState().framebufferSpace.setBounds(
316 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200317
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200318 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319 const Rect frame{50, 60, 100, 100};
320 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700321
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200322 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
325 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
326 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
328 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000329 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
330 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
331 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200332
Angel Aguayob084e0c2021-08-04 23:27:28 +0000333 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
334 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
335 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200336
Angel Aguayob084e0c2021-08-04 23:27:28 +0000337 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
338 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
339 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200340
Angel Aguayob084e0c2021-08-04 23:27:28 +0000341 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
342 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
343 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200344
Angel Aguayob084e0c2021-08-04 23:27:28 +0000345 EXPECT_EQ(state.displaySpace.getContent(),
346 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700347
348 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200349}
350
351TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
352 const Rect displayRect{0, 0, 1000, 2000};
353 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000354 mOutput->editState().displaySpace.setBounds(
355 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
356 mOutput->editState().framebufferSpace.setBounds(
357 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200358
359 const ui::Rotation orientation = ui::ROTATION_90;
360 const Rect frame{50, 60, 100, 100};
361 const Rect viewport{10, 20, 30, 40};
362
363 mOutput->setProjection(orientation, viewport, frame);
364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
366 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
367 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
369 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000370 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
371 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
372 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200373
Angel Aguayob084e0c2021-08-04 23:27:28 +0000374 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
375 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
376 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200377
Angel Aguayob084e0c2021-08-04 23:27:28 +0000378 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
379 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
380 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200381
Angel Aguayob084e0c2021-08-04 23:27:28 +0000382 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
383 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
384 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200385
Angel Aguayob084e0c2021-08-04 23:27:28 +0000386 EXPECT_EQ(state.displaySpace.getContent(),
387 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700388}
389
Lloyd Pique66d68602019-02-13 14:23:31 -0800390/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392 */
393
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000395 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
396 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
397 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
398 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
399 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
400 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
401 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
402 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
403 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
404 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700405
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200406 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700407
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200408 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700409
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700411
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200412 const auto state = mOutput->getState();
413
414 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000415 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
416 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
417 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200418
Angel Aguayob084e0c2021-08-04 23:27:28 +0000419 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
420 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200421
Angel Aguayob084e0c2021-08-04 23:27:28 +0000422 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
423 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200424
Angel Aguayob084e0c2021-08-04 23:27:28 +0000425 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
426 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200427
Angel Aguayob084e0c2021-08-04 23:27:28 +0000428 EXPECT_EQ(state.displaySpace.getContent(),
429 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200430
431 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700432}
433
Lloyd Pique66d68602019-02-13 14:23:31 -0800434/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700435 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436 */
437
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700438TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
439 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
440 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700441
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700442 const auto& state = mOutput->getState();
443 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
444 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700446 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700447}
448
Lloyd Pique66d68602019-02-13 14:23:31 -0800449/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700450 * Output::setColorTransform
451 */
452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456 // If no colorTransformMatrix is set the update should be skipped.
457 CompositionRefreshArgs refreshArgs;
458 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700461
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464
465 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467}
Lloyd Piqueef958122019-02-05 18:00:12 -0800468
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800469TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700471
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472 // Attempting to set the same colorTransformMatrix that is already set should
473 // also skip the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700478
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800479 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484}
485
486TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488
489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kIdentity;
492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494
495 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700501
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800502TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700504
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800505 // Setting a different colorTransformMatrix should perform the update.
506 CompositionRefreshArgs refreshArgs;
507 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700508
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800510
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800511 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513
514 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800516}
517
518TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700519 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800520
521 // Setting a different colorTransformMatrix should perform the update.
522 CompositionRefreshArgs refreshArgs;
523 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
524
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800526
527 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800529
530 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700532}
533
Lloyd Pique66d68602019-02-13 14:23:31 -0800534/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800535 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536 */
537
Lloyd Pique17ca7422019-11-14 14:24:10 -0800538using OutputSetColorProfileTest = OutputTest;
539
540TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800541 using ColorProfile = Output::ColorProfile;
542
Lloyd Piquef5275482019-01-29 18:42:42 -0800543 EXPECT_CALL(*mDisplayColorProfile,
544 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
545 ui::Dataspace::UNKNOWN))
546 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800547 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
550 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
551 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700552
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
554 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
555 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
556 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800557
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800559}
560
Lloyd Pique17ca7422019-11-14 14:24:10 -0800561TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800562 using ColorProfile = Output::ColorProfile;
563
Lloyd Piquef5275482019-01-29 18:42:42 -0800564 EXPECT_CALL(*mDisplayColorProfile,
565 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
566 ui::Dataspace::UNKNOWN))
567 .WillOnce(Return(ui::Dataspace::UNKNOWN));
568
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700569 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
570 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
571 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
572 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800573
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
575 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
576 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800577
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700578 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700579}
580
Lloyd Pique66d68602019-02-13 14:23:31 -0800581/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700582 * Output::setRenderSurface()
583 */
584
585TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
586 const ui::Size newDisplaySize{640, 480};
587
588 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
589 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
590
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700591 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700592
Angel Aguayob084e0c2021-08-04 23:27:28 +0000593 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700594}
595
Alec Mouricdf16792021-12-10 13:16:06 -0800596/**
597 * Output::setDisplayBrightness()
598 */
599
600TEST_F(OutputTest, setNextBrightness) {
601 constexpr float kDisplayBrightness = 0.5f;
602 mOutput->setNextBrightness(kDisplayBrightness);
603 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
604 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
605}
606
Lloyd Pique66d68602019-02-13 14:23:31 -0800607/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000608 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700609 */
610
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700611TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000612 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000613 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700614 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700615
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700616 // The dirty region should be clipped to the display bounds.
617 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700618}
619
Lloyd Pique66d68602019-02-13 14:23:31 -0800620/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800622 */
623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624TEST_F(OutputTest, layerFiltering) {
625 const ui::LayerStack layerStack1{123u};
626 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // If the output is associated to layerStack1 and to an internal display...
629 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // It excludes layers with no layer stack, internal-only or not.
632 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
633 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635 // It includes layers on layerStack1, internal-only or not.
636 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
637 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
638 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 // If the output is associated to layerStack1 but not to an internal display...
642 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 // It includes layers on layerStack1, unless they are internal-only.
645 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
646 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
647 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
648 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800649}
650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800652 NonInjectedLayer layer;
653 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800654
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700655 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800656 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800658}
659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800661 NonInjectedLayer layer;
662 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 const ui::LayerStack layerStack1{123u};
665 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 // If the output is associated to layerStack1 and to an internal display...
668 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800669
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700670 // It excludes layers with no layer stack, internal-only or not.
671 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // It includes layers on layerStack1, internal-only or not.
678 layer.layerFEState.outputFilter = {layerStack1, false};
679 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 layer.layerFEState.outputFilter = {layerStack1, true};
682 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack2, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack2, false};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 // If the output is associated to layerStack1 but not to an internal display...
691 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800692
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700693 // It includes layers on layerStack1, unless they are internal-only.
694 layer.layerFEState.outputFilter = {layerStack1, false};
695 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800696
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700697 layer.layerFEState.outputFilter = {layerStack1, true};
698 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800699
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700700 layer.layerFEState.outputFilter = {layerStack2, true};
701 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800702
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700703 layer.layerFEState.outputFilter = {layerStack2, false};
704 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800705}
706
Lloyd Pique66d68602019-02-13 14:23:31 -0800707/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800708 * Output::getOutputLayerForLayer()
709 */
710
711TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800712 InjectedLayer layer1;
713 InjectedLayer layer2;
714 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800715
Lloyd Piquede196652020-01-22 17:29:58 -0800716 injectOutputLayer(layer1);
717 injectNullOutputLayer();
718 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800719
720 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800721 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
722 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800723
724 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800725 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
726 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
727 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800728
729 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800730 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
731 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
732 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800733}
734
Lloyd Pique66d68602019-02-13 14:23:31 -0800735/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800736 * Output::setReleasedLayers()
737 */
738
739using OutputSetReleasedLayersTest = OutputTest;
740
741TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800742 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
743 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
744 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800745
746 Output::ReleasedLayers layers;
747 layers.push_back(layer1FE);
748 layers.push_back(layer2FE);
749 layers.push_back(layer3FE);
750
751 mOutput->setReleasedLayers(std::move(layers));
752
753 const auto& setLayers = mOutput->getReleasedLayersForTest();
754 ASSERT_EQ(3u, setLayers.size());
755 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
756 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
757 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
758}
759
760/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800761 * Output::updateAndWriteCompositionState()
762 */
763
Lloyd Piquede196652020-01-22 17:29:58 -0800764using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800765
766TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
767 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800768
769 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800770 mOutput->updateCompositionState(args);
771 mOutput->planComposition();
772 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800773}
774
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
779
Lloyd Piqueef63b612019-11-14 13:19:56 -0800780 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800781
Lloyd Piquede196652020-01-22 17:29:58 -0800782 injectOutputLayer(layer1);
783 injectOutputLayer(layer2);
784 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800785
786 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800787 mOutput->updateCompositionState(args);
788 mOutput->planComposition();
789 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800790}
791
792TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800793 InjectedLayer layer1;
794 InjectedLayer layer2;
795 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800796
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400797 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200798 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800799 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700802 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
803 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200804 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800805 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400806 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
807 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700808 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
809 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200810 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800811 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400812 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
813 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700814 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
815 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800816
817 injectOutputLayer(layer1);
818 injectOutputLayer(layer2);
819 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820
821 mOutput->editState().isEnabled = true;
822
823 CompositionRefreshArgs args;
824 args.updatingGeometryThisFrame = false;
825 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800827 mOutput->updateCompositionState(args);
828 mOutput->planComposition();
829 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800830}
831
832TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800833 InjectedLayer layer1;
834 InjectedLayer layer2;
835 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400837 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200838 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800839 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400840 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
841 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700842 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
843 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200844 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800845 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400846 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
847 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700848 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
849 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200850 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800851 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400852 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
853 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700854 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
855 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800856
857 injectOutputLayer(layer1);
858 injectOutputLayer(layer2);
859 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800860
861 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800862
863 CompositionRefreshArgs args;
864 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800865 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800866 mOutput->updateCompositionState(args);
867 mOutput->planComposition();
868 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800869}
870
871TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800872 InjectedLayer layer1;
873 InjectedLayer layer2;
874 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800875
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400876 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800878 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400879 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700881 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
882 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200883 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800884 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400885 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
886 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700887 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
888 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200889 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800890 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400891 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
892 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700893 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
894 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800895
896 injectOutputLayer(layer1);
897 injectOutputLayer(layer2);
898 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800899
900 mOutput->editState().isEnabled = true;
901
902 CompositionRefreshArgs args;
903 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800904 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800905 mOutput->updateCompositionState(args);
906 mOutput->planComposition();
907 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800908}
909
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400910TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
911 renderengine::mock::RenderEngine renderEngine;
912 InjectedLayer layer0;
913 InjectedLayer layer1;
914 InjectedLayer layer2;
915 InjectedLayer layer3;
916
917 InSequence seq;
918 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
919 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Robert Carrec8ccca2022-05-04 09:36:14 -0700920 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
921 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400922 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
923 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
924
925 uint32_t z = 0;
926 EXPECT_CALL(*layer0.outputLayer,
927 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
928 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700929 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
930 .WillRepeatedly(Return(false));
931
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400932
933 // After calling planComposition (which clears overrideInfo), this test sets
934 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
935 // comes first, setting isPeekingThrough to true and zIsOverridden to true
936 // for it and the following layers.
937 EXPECT_CALL(*layer3.outputLayer,
938 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
939 /*zIsOverridden*/ true, /*isPeekingThrough*/
940 true));
Robert Carrec8ccca2022-05-04 09:36:14 -0700941 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
942 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400943 EXPECT_CALL(*layer1.outputLayer,
944 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
945 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700946 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
947 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400948 EXPECT_CALL(*layer2.outputLayer,
949 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
950 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700951 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
952 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400953
954 injectOutputLayer(layer0);
955 injectOutputLayer(layer1);
956 injectOutputLayer(layer2);
957 injectOutputLayer(layer3);
958
959 mOutput->editState().isEnabled = true;
960
961 CompositionRefreshArgs args;
962 args.updatingGeometryThisFrame = true;
963 args.devOptForceClientComposition = false;
964 mOutput->updateCompositionState(args);
965 mOutput->planComposition();
966
967 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800968 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700969 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800970 renderengine::impl::ExternalTexture::Usage::READABLE |
971 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400972 layer1.outputLayerState.overrideInfo.buffer = buffer;
973 layer2.outputLayerState.overrideInfo.buffer = buffer;
974 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
975 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
976
977 mOutput->writeCompositionState(args);
978}
979
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800980/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800981 * Output::prepareFrame()
982 */
983
984struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800985 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800986 // Sets up the helper functions called by the function under test to use
987 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800988 MOCK_METHOD1(chooseCompositionStrategy,
989 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
990 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800991 };
992
993 OutputPrepareFrameTest() {
994 mOutput.setDisplayColorProfileForTest(
995 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
996 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
997 }
998
999 StrictMock<mock::CompositionEngine> mCompositionEngine;
1000 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1001 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001002 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001003};
1004
1005TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1006 mOutput.editState().isEnabled = false;
1007
1008 mOutput.prepareFrame();
1009}
1010
1011TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1012 mOutput.editState().isEnabled = true;
1013 mOutput.editState().usesClientComposition = false;
1014 mOutput.editState().usesDeviceComposition = true;
1015
Vishnu Naira3140382022-02-24 14:07:11 -08001016 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1017 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001018 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001019 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1020
1021 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001022 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001023}
1024
1025// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1026// base chooseCompositionStrategy() is invoked.
1027TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001028 mOutput->editState().isEnabled = true;
1029 mOutput->editState().usesClientComposition = false;
1030 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001031
1032 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1033
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001034 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001035
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1037 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001038 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001039}
1040
Vishnu Naira3140382022-02-24 14:07:11 -08001041struct OutputPrepareFrameAsyncTest : public testing::Test {
1042 struct OutputPartialMock : public OutputPartialMockBase {
1043 // Sets up the helper functions called by the function under test to use
1044 // mock implementations.
1045 MOCK_METHOD1(chooseCompositionStrategy,
1046 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1047 MOCK_METHOD0(updateProtectedContentState, void());
1048 MOCK_METHOD2(dequeueRenderBuffer,
1049 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1050 MOCK_METHOD1(
1051 chooseCompositionStrategyAsync,
1052 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1053 MOCK_METHOD4(composeSurfaces,
1054 std::optional<base::unique_fd>(
1055 const Region&, const compositionengine::CompositionRefreshArgs&,
1056 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1057 MOCK_METHOD0(resetCompositionStrategy, void());
1058 };
1059
1060 OutputPrepareFrameAsyncTest() {
1061 mOutput.setDisplayColorProfileForTest(
1062 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1063 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1064 }
1065
1066 StrictMock<mock::CompositionEngine> mCompositionEngine;
1067 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1068 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1069 StrictMock<OutputPartialMock> mOutput;
1070 CompositionRefreshArgs mRefreshArgs;
1071};
1072
1073TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1074 mOutput.editState().isEnabled = true;
1075 mOutput.editState().usesClientComposition = false;
1076 mOutput.editState().usesDeviceComposition = true;
1077 mOutput.editState().previousDeviceRequestedChanges =
1078 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1079 std::promise<bool> p;
1080 p.set_value(true);
1081
1082 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1083 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1084 EXPECT_CALL(mOutput, updateProtectedContentState());
1085 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1086 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1087 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1088 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1089 Return(ByMove(p.get_future()))));
1090 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1091
1092 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001093 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001094 EXPECT_FALSE(result.bufferAvailable());
1095}
1096
1097TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1098 mOutput.editState().isEnabled = true;
1099 mOutput.editState().usesClientComposition = false;
1100 mOutput.editState().usesDeviceComposition = true;
1101 mOutput.editState().previousDeviceRequestedChanges =
1102 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1103 std::promise<bool> p;
1104 p.set_value(true);
1105
1106 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1107 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1108 EXPECT_CALL(mOutput, updateProtectedContentState());
1109 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1110 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1111 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1112 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1113 Return(ByMove(p.get_future()))));
1114
1115 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001116 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001117 EXPECT_FALSE(result.bufferAvailable());
1118}
1119
1120// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1121// client composition
1122TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1123 mOutput.editState().isEnabled = true;
1124 mOutput.editState().usesClientComposition = false;
1125 mOutput.editState().usesDeviceComposition = true;
1126 mOutput.editState().previousDeviceRequestedChanges =
1127 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1128 std::promise<bool> p;
1129 p.set_value(false);
1130 std::shared_ptr<renderengine::ExternalTexture> tex =
1131 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1132 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1133 2);
1134 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1135 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1136 EXPECT_CALL(mOutput, updateProtectedContentState());
1137 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1138 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1139 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1140 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1141 return p.get_future();
1142 });
1143 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1144
1145 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001146 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001147 EXPECT_TRUE(result.bufferAvailable());
1148}
1149
1150TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1151 mOutput.editState().isEnabled = true;
1152 mOutput.editState().usesClientComposition = false;
1153 mOutput.editState().usesDeviceComposition = true;
1154 mOutput.editState().previousDeviceRequestedChanges =
1155 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1156 auto newDeviceRequestedChanges =
1157 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1158 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1159 std::promise<bool> p;
1160 p.set_value(false);
1161 std::shared_ptr<renderengine::ExternalTexture> tex =
1162 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1163 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1164 2);
1165
1166 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1167 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1168 EXPECT_CALL(mOutput, updateProtectedContentState());
1169 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1170 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1171 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1172 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1173 return p.get_future();
1174 });
1175 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1176
1177 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001178 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001179 EXPECT_TRUE(result.bufferAvailable());
1180}
1181
Lloyd Pique56eba802019-08-28 15:45:25 -07001182/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001183 * Output::prepare()
1184 */
1185
1186struct OutputPrepareTest : public testing::Test {
1187 struct OutputPartialMock : public OutputPartialMockBase {
1188 // Sets up the helper functions called by the function under test to use
1189 // mock implementations.
1190 MOCK_METHOD2(rebuildLayerStacks,
1191 void(const compositionengine::CompositionRefreshArgs&,
1192 compositionengine::LayerFESet&));
1193 };
1194
Brian Lindahl439afad2022-11-14 11:16:55 -07001195 OutputPrepareTest() {
1196 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1197 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1198 .WillRepeatedly(Return(&mLayer1.outputLayer));
1199 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1200 .WillRepeatedly(Return(&mLayer2.outputLayer));
1201
1202 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1203 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1204 }
1205
1206 struct Layer {
1207 StrictMock<mock::OutputLayer> outputLayer;
1208 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1209 };
1210
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001211 StrictMock<OutputPartialMock> mOutput;
1212 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001213 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001214 Layer mLayer1;
1215 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001216};
1217
Brian Lindahl439afad2022-11-14 11:16:55 -07001218TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001219 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001220
1221 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1222
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001223 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001224 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1225 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1226
1227 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1228}
1229
1230TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1231 InSequence seq;
1232
1233 mRefreshArgs.bufferIdsToUncache = {};
1234
1235 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1236 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1237 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001238
1239 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1240}
1241
1242/*
1243 * Output::rebuildLayerStacks()
1244 */
1245
1246struct OutputRebuildLayerStacksTest : public testing::Test {
1247 struct OutputPartialMock : public OutputPartialMockBase {
1248 // Sets up the helper functions called by the function under test to use
1249 // mock implementations.
1250 MOCK_METHOD2(collectVisibleLayers,
1251 void(const compositionengine::CompositionRefreshArgs&,
1252 compositionengine::Output::CoverageState&));
1253 };
1254
1255 OutputRebuildLayerStacksTest() {
1256 mOutput.mState.isEnabled = true;
1257 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001258 mOutput.mState.displaySpace.setBounds(
1259 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001260
1261 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1262
1263 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1264
1265 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1266 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1267 }
1268
1269 void setTestCoverageValues(const CompositionRefreshArgs&,
1270 compositionengine::Output::CoverageState& state) {
1271 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1272 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1273 state.dirtyRegion = mCoverageDirtyRegionToSet;
1274 }
1275
1276 static const ui::Transform kIdentityTransform;
1277 static const ui::Transform kRotate90Transform;
1278 static const Rect kOutputBounds;
1279
1280 StrictMock<OutputPartialMock> mOutput;
1281 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001282 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001283 Region mCoverageAboveCoveredLayersToSet;
1284 Region mCoverageAboveOpaqueLayersToSet;
1285 Region mCoverageDirtyRegionToSet;
1286};
1287
1288const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1289const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1290const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1291
1292TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1293 mOutput.mState.isEnabled = false;
1294
1295 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1296}
1297
1298TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1299 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1300
1301 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1302}
1303
1304TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1305 mOutput.mState.transform = kIdentityTransform;
1306
1307 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1308
1309 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1310
1311 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1312}
1313
1314TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1315 mOutput.mState.transform = kIdentityTransform;
1316
1317 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1318
1319 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1320
1321 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1322}
1323
1324TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1325 mOutput.mState.transform = kRotate90Transform;
1326
1327 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1328
1329 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1330
1331 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1332}
1333
1334TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1335 mOutput.mState.transform = kRotate90Transform;
1336
1337 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1338
1339 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1340
1341 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1342}
1343
1344TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1345 mOutput.mState.transform = kIdentityTransform;
1346 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1347
1348 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1349
1350 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1351
1352 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1353}
1354
1355TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1356 mOutput.mState.transform = kRotate90Transform;
1357 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1358
1359 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1360
1361 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1362
1363 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1364}
1365
1366/*
1367 * Output::collectVisibleLayers()
1368 */
1369
Lloyd Pique1ef93222019-11-21 16:41:53 -08001370struct OutputCollectVisibleLayersTest : public testing::Test {
1371 struct OutputPartialMock : public OutputPartialMockBase {
1372 // Sets up the helper functions called by the function under test to use
1373 // mock implementations.
1374 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001375 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001376 compositionengine::Output::CoverageState&));
1377 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1378 MOCK_METHOD0(finalizePendingOutputLayers, void());
1379 };
1380
1381 struct Layer {
1382 Layer() {
1383 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1384 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1385 }
1386
1387 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001388 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001389 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001390 };
1391
1392 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001393 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001394 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1395 .WillRepeatedly(Return(&mLayer1.outputLayer));
1396 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1397 .WillRepeatedly(Return(&mLayer2.outputLayer));
1398 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1399 .WillRepeatedly(Return(&mLayer3.outputLayer));
1400
Lloyd Piquede196652020-01-22 17:29:58 -08001401 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1402 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1403 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001404 }
1405
1406 StrictMock<OutputPartialMock> mOutput;
1407 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408 LayerFESet mGeomSnapshots;
1409 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001410 Layer mLayer1;
1411 Layer mLayer2;
1412 Layer mLayer3;
1413};
1414
1415TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1416 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001417 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001418
1419 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1420 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1421
1422 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1423}
1424
1425TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1426 // Enforce a call order sequence for this test.
1427 InSequence seq;
1428
1429 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1431 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1432 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001433
1434 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1435 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1436
1437 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001438}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001439
1440/*
1441 * Output::ensureOutputLayerIfVisible()
1442 */
1443
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1445 struct OutputPartialMock : public OutputPartialMockBase {
1446 // Sets up the helper functions called by the function under test to use
1447 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001448 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1449 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001451 MOCK_METHOD2(ensureOutputLayer,
1452 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 };
1454
1455 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001456 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001457 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001458 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001460 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461
Angel Aguayob084e0c2021-08-04 23:27:28 +00001462 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1463 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001464 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 mLayer.layerFEState.isVisible = true;
1467 mLayer.layerFEState.isOpaque = true;
1468 mLayer.layerFEState.contentDirty = true;
1469 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1470 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001471 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001472
Lloyd Piquede196652020-01-22 17:29:58 -08001473 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1474 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475
Lloyd Piquede196652020-01-22 17:29:58 -08001476 mGeomSnapshots.insert(mLayer.layerFE);
1477 }
1478
1479 void ensureOutputLayerIfVisible() {
1480 sp<LayerFE> layerFE(mLayer.layerFE);
1481 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001482 }
1483
1484 static const Region kEmptyRegion;
1485 static const Region kFullBoundsNoRotation;
1486 static const Region kRightHalfBoundsNoRotation;
1487 static const Region kLowerHalfBoundsNoRotation;
1488 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001489 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001490 static const Region kTransparentRegionHintTwo;
1491 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001492 static const Region kTransparentRegionHintNegative;
1493 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
1495 StrictMock<OutputPartialMock> mOutput;
1496 LayerFESet mGeomSnapshots;
1497 Output::CoverageState mCoverageState{mGeomSnapshots};
1498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500};
1501
1502const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1503const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1504 Region(Rect(0, 0, 100, 200));
1505const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1506 Region(Rect(0, 100, 100, 200));
1507const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1508 Region(Rect(50, 0, 100, 200));
1509const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1510 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001511const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001512 Region(Rect(0, 0, 100, 100));
1513const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001514 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001515const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001516 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001517const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1518 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1519const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1520 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001522TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1523 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001524 mGeomSnapshots.clear();
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527}
1528
1529TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001530 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1531 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001532
Lloyd Piquede196652020-01-22 17:29:58 -08001533 ensureOutputLayerIfVisible();
1534}
1535
1536TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1537 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1538
1539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540}
1541
1542TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001543 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546}
1547
1548TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001549 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552}
1553
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001554TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001555 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556
Lloyd Piquede196652020-01-22 17:29:58 -08001557 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558}
1559
1560TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1561 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001562 mLayer.layerFEState.isOpaque = true;
1563 mLayer.layerFEState.contentDirty = true;
1564 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565
1566 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1568 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571
1572 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1573 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1578 RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1580 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581}
1582
1583TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1584 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001585 mLayer.layerFEState.isOpaque = true;
1586 mLayer.layerFEState.contentDirty = true;
1587 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1590 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
1594 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1596 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1599 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1600 RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1602 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603}
1604
1605TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1606 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001607 mLayer.layerFEState.isOpaque = false;
1608 mLayer.layerFEState.contentDirty = true;
1609 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001610
1611 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001612 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1613 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001614
Lloyd Piquede196652020-01-22 17:29:58 -08001615 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616
1617 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1618 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1619 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1620
Lloyd Piquede196652020-01-22 17:29:58 -08001621 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1622 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001624 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1625 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001626}
1627
1628TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1629 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001630 mLayer.layerFEState.isOpaque = false;
1631 mLayer.layerFEState.contentDirty = true;
1632 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
Lloyd Piquede196652020-01-22 17:29:58 -08001634 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1635 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636
Lloyd Piquede196652020-01-22 17:29:58 -08001637 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001638
1639 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1640 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1641 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1642
Lloyd Piquede196652020-01-22 17:29:58 -08001643 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1644 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001646 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1647 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648}
1649
1650TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1651 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001652 mLayer.layerFEState.isOpaque = true;
1653 mLayer.layerFEState.contentDirty = false;
1654 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001655
1656 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001657 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1658 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001659
Lloyd Piquede196652020-01-22 17:29:58 -08001660 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661
1662 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1663 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1664 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1665
Lloyd Piquede196652020-01-22 17:29:58 -08001666 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1667 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1668 RegionEq(kFullBoundsNoRotation));
1669 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1670 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001671}
1672
1673TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1674 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001675 mLayer.layerFEState.isOpaque = true;
1676 mLayer.layerFEState.contentDirty = false;
1677 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1680 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001681
Lloyd Piquede196652020-01-22 17:29:58 -08001682 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001683
1684 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1685 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1687
Lloyd Piquede196652020-01-22 17:29:58 -08001688 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1689 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1690 RegionEq(kFullBoundsNoRotation));
1691 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1692 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001693}
1694
1695TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1696 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001697 mLayer.layerFEState.isOpaque = true;
1698 mLayer.layerFEState.contentDirty = true;
1699 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1700 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1701 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1702 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001703
1704 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001705 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1706 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001707
Lloyd Piquede196652020-01-22 17:29:58 -08001708 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001709
1710 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1711 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1712 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1713
Lloyd Piquede196652020-01-22 17:29:58 -08001714 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1715 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1716 RegionEq(kFullBoundsNoRotation));
1717 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1718 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001719}
1720
1721TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1722 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001723 mLayer.layerFEState.isOpaque = true;
1724 mLayer.layerFEState.contentDirty = true;
1725 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1726 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1727 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1728 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1731 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001732
Lloyd Piquede196652020-01-22 17:29:58 -08001733 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001734
1735 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1736 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1737 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1738
Lloyd Piquede196652020-01-22 17:29:58 -08001739 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1740 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1741 RegionEq(kFullBoundsNoRotation));
1742 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1743 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001744}
1745
1746TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1747 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001748 mLayer.layerFEState.isOpaque = true;
1749 mLayer.layerFEState.contentDirty = true;
1750 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001751
Angel Aguayob084e0c2021-08-04 23:27:28 +00001752 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1754
1755 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001756 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1757 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001758
Lloyd Piquede196652020-01-22 17:29:58 -08001759 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001760
1761 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1762 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1763 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1764
Lloyd Piquede196652020-01-22 17:29:58 -08001765 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1766 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1767 RegionEq(kFullBoundsNoRotation));
1768 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1769 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001770}
1771
1772TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1773 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001774 mLayer.layerFEState.isOpaque = true;
1775 mLayer.layerFEState.contentDirty = true;
1776 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001777
Angel Aguayob084e0c2021-08-04 23:27:28 +00001778 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001779 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1780
Lloyd Piquede196652020-01-22 17:29:58 -08001781 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1782 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001783
Lloyd Piquede196652020-01-22 17:29:58 -08001784 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001785
1786 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1787 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1788 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1789
Lloyd Piquede196652020-01-22 17:29:58 -08001790 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1791 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1792 RegionEq(kFullBoundsNoRotation));
1793 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1794 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001795}
1796
1797TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1798 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1799 ui::Transform arbitraryTransform;
1800 arbitraryTransform.set(1, 1, -1, 1);
1801 arbitraryTransform.set(0, 100);
1802
Lloyd Piquede196652020-01-22 17:29:58 -08001803 mLayer.layerFEState.isOpaque = true;
1804 mLayer.layerFEState.contentDirty = true;
1805 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1806 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001807
1808 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001809 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1810 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001811
Lloyd Piquede196652020-01-22 17:29:58 -08001812 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001813
1814 const Region kRegion = Region(Rect(0, 0, 300, 300));
1815 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1816
1817 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1818 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1819 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1822 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1823 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1824 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001825}
1826
1827TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001828 mLayer.layerFEState.isOpaque = false;
1829 mLayer.layerFEState.contentDirty = true;
1830 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001831
1832 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1833 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1834 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1835
Lloyd Piquede196652020-01-22 17:29:58 -08001836 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1837 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001838
Lloyd Piquede196652020-01-22 17:29:58 -08001839 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001840
1841 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1842 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1843 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1844 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1845 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1846 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1847
1848 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1849 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1850 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1851
Lloyd Piquede196652020-01-22 17:29:58 -08001852 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1853 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001854 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001855 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1856 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1857 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001858}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001859
Vishnu Naira483b4a2019-12-12 15:07:52 -08001860TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1861 ui::Transform translate;
1862 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001863 mLayer.layerFEState.geomLayerTransform = translate;
1864 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001865
1866 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1867 // half of the layer including the casting shadow is covered and opaque
1868 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1869 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1870
Lloyd Piquede196652020-01-22 17:29:58 -08001871 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1872 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001873
Lloyd Piquede196652020-01-22 17:29:58 -08001874 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001875
1876 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1877 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1878 // add starting opaque region to the opaque half of the casting layer bounds
1879 const Region kExpectedAboveOpaqueRegion =
1880 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1881 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1882 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1883 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1884 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1885 const Region kExpectedLayerShadowRegion =
1886 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1887
1888 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1889 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1890 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1891
Lloyd Piquede196652020-01-22 17:29:58 -08001892 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1893 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001894 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001895 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1896 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001897 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001898 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001899 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1900}
1901
1902TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1903 ui::Transform translate;
1904 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001905 mLayer.layerFEState.geomLayerTransform = translate;
1906 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001907
1908 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1909 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1910 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1911 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1912
Lloyd Piquede196652020-01-22 17:29:58 -08001913 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1914 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001915
Lloyd Piquede196652020-01-22 17:29:58 -08001916 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001917
1918 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1919 const Region kExpectedLayerShadowRegion =
1920 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1921
Lloyd Piquede196652020-01-22 17:29:58 -08001922 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1923 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001924 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1925}
1926
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001927TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001928 ui::Transform translate;
1929 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001930 mLayer.layerFEState.geomLayerTransform = translate;
1931 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001932
1933 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1934 // Casting layer and its shadows are covered by an opaque region
1935 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1936 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1937
Lloyd Piquede196652020-01-22 17:29:58 -08001938 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001939}
1940
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001941TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1942 mLayer.layerFEState.isOpaque = false;
1943 mLayer.layerFEState.contentDirty = true;
1944 mLayer.layerFEState.compositionType =
1945 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1946
1947 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1948 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1949 .WillOnce(Return(&mLayer.outputLayer));
1950 ensureOutputLayerIfVisible();
1951
1952 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1953 RegionEq(kTransparentRegionHint));
1954}
1955
1956TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1957 mLayer.layerFEState.isOpaque = false;
1958 mLayer.layerFEState.contentDirty = true;
1959
1960 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1961 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1962 .WillOnce(Return(&mLayer.outputLayer));
1963 ensureOutputLayerIfVisible();
1964
1965 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1966}
1967
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001968TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1969 mLayer.layerFEState.isOpaque = false;
1970 mLayer.layerFEState.contentDirty = true;
1971 mLayer.layerFEState.compositionType =
1972 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001973 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001974
1975 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1976 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1977
1978 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1979 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1980 .WillOnce(Return(&mLayer.outputLayer));
1981 ensureOutputLayerIfVisible();
1982
1983 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001984 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001985}
1986
Alec Mourie60f0b92022-06-10 19:15:20 +00001987TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1988 mLayer.layerFEState.isOpaque = false;
1989 mLayer.layerFEState.contentDirty = true;
1990 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1991 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1992
1993 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1994}
1995
1996TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1997 mLayer.layerFEState.isOpaque = false;
1998 mLayer.layerFEState.contentDirty = true;
1999 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2000 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
2001
2002 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2003}
2004
2005TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
2006 mLayer.layerFEState.isOpaque = false;
2007 mLayer.layerFEState.contentDirty = true;
2008 mLayer.layerFEState.compositionType =
2009 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
2010 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
2011
2012 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2013 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
2014 .WillOnce(Return(&mLayer.outputLayer));
2015 ensureOutputLayerIfVisible();
2016
2017 // Check that the blocking region clips an out-of-bounds transparent region.
2018 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2019 RegionEq(kTransparentRegionHint));
2020}
2021
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002022/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002023 * Output::present()
2024 */
2025
2026struct OutputPresentTest : public testing::Test {
2027 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002028 // Sets up the helper functions called by the function under test to use
2029 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002030 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002031 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002032 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002033 MOCK_METHOD0(planComposition, void());
2034 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002035 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2036 MOCK_METHOD0(beginFrame, void());
2037 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002038 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002039 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002040 MOCK_METHOD2(finishFrame,
2041 void(const compositionengine::CompositionRefreshArgs&,
2042 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002043 MOCK_METHOD0(postFramebuffer, void());
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&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002046 };
2047
2048 StrictMock<OutputPartialMock> mOutput;
2049};
2050
2051TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2052 CompositionRefreshArgs args;
2053
2054 InSequence seq;
2055 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002056 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2057 EXPECT_CALL(mOutput, planComposition());
2058 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002059 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2060 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002061 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002062 EXPECT_CALL(mOutput, prepareFrame());
2063 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002064 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2065 EXPECT_CALL(mOutput, postFramebuffer());
2066 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2067
2068 mOutput.present(args);
2069}
2070
2071TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2072 CompositionRefreshArgs args;
2073
2074 InSequence seq;
2075 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2076 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2077 EXPECT_CALL(mOutput, planComposition());
2078 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2079 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2080 EXPECT_CALL(mOutput, beginFrame());
2081 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2082 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2083 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2084 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002085 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002086 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002087
2088 mOutput.present(args);
2089}
2090
2091/*
2092 * Output::updateColorProfile()
2093 */
2094
Lloyd Pique17ca7422019-11-14 14:24:10 -08002095struct OutputUpdateColorProfileTest : public testing::Test {
2096 using TestType = OutputUpdateColorProfileTest;
2097
2098 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002099 // Sets up the helper functions called by the function under test to use
2100 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002101 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2102 };
2103
2104 struct Layer {
2105 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002106 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2107 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002108 }
2109
2110 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002111 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002112 LayerFECompositionState mLayerFEState;
2113 };
2114
2115 OutputUpdateColorProfileTest() {
2116 mOutput.setDisplayColorProfileForTest(
2117 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2118 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002119 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002120
2121 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2122 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2123 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2124 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2125 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2126 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2127 }
2128
2129 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2130 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2131 };
2132
2133 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2134 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2135 StrictMock<OutputPartialMock> mOutput;
2136
2137 Layer mLayer1;
2138 Layer mLayer2;
2139 Layer mLayer3;
2140
2141 CompositionRefreshArgs mRefreshArgs;
2142};
2143
2144// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2145// to make it easier to write unit tests.
2146
2147TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2148 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2149 // a simple default color profile without looking at anything else.
2150
Lloyd Pique0a456232020-01-16 17:51:13 -08002151 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002152 EXPECT_CALL(mOutput,
2153 setColorProfile(ColorProfileEq(
2154 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2155 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2156
2157 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2158 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2159
2160 mOutput.updateColorProfile(mRefreshArgs);
2161}
2162
2163struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2164 : public OutputUpdateColorProfileTest {
2165 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002166 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002167 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2168 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2169 }
2170
2171 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2172 : public CallOrderStateMachineHelper<
2173 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2174 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2175 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2176 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2177 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2178 _))
2179 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2180 SetArgPointee<4>(renderIntent)));
2181 EXPECT_CALL(getInstance()->mOutput,
2182 setColorProfile(
2183 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2184 ui::Dataspace::UNKNOWN})));
2185 return nextState<ExecuteState>();
2186 }
2187 };
2188
2189 // Call this member function to start using the mini-DSL defined above.
2190 [[nodiscard]] auto verify() {
2191 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2192 }
2193};
2194
2195TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2196 Native_Unknown_Colorimetric_Set) {
2197 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2198 ui::Dataspace::UNKNOWN,
2199 ui::RenderIntent::COLORIMETRIC)
2200 .execute();
2201}
2202
2203TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2204 DisplayP3_DisplayP3_Enhance_Set) {
2205 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2206 ui::Dataspace::DISPLAY_P3,
2207 ui::RenderIntent::ENHANCE)
2208 .execute();
2209}
2210
2211struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2212 : public OutputUpdateColorProfileTest {
2213 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002214 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002215 EXPECT_CALL(*mDisplayColorProfile,
2216 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2217 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2218 SetArgPointee<3>(ui::ColorMode::NATIVE),
2219 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2220 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2221 }
2222
2223 struct IfColorSpaceAgnosticDataspaceSetToState
2224 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2225 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2226 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2227 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2228 }
2229 };
2230
2231 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2232 : public CallOrderStateMachineHelper<
2233 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2234 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2235 ui::Dataspace dataspace) {
2236 EXPECT_CALL(getInstance()->mOutput,
2237 setColorProfile(ColorProfileEq(
2238 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2239 ui::RenderIntent::COLORIMETRIC, dataspace})));
2240 return nextState<ExecuteState>();
2241 }
2242 };
2243
2244 // Call this member function to start using the mini-DSL defined above.
2245 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2246};
2247
2248TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2249 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2250 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2251 .execute();
2252}
2253
2254TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2255 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2256 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2257 .execute();
2258}
2259
2260struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2261 : public OutputUpdateColorProfileTest {
2262 // Internally the implementation looks through the dataspaces of all the
2263 // visible layers. The topmost one that also has an actual dataspace
2264 // preference set is used to drive subsequent choices.
2265
2266 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2267 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2268 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2269
Lloyd Pique0a456232020-01-16 17:51:13 -08002270 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002271 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2272 }
2273
2274 struct IfTopLayerDataspaceState
2275 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2276 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2277 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2278 return nextState<AndIfMiddleLayerDataspaceState>();
2279 }
2280 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2281 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2282 }
2283 };
2284
2285 struct AndIfMiddleLayerDataspaceState
2286 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2287 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2288 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2289 return nextState<AndIfBottomLayerDataspaceState>();
2290 }
2291 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2292 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2293 }
2294 };
2295
2296 struct AndIfBottomLayerDataspaceState
2297 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2298 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2299 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2300 return nextState<ThenExpectBestColorModeCallUsesState>();
2301 }
2302 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2303 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2304 }
2305 };
2306
2307 struct ThenExpectBestColorModeCallUsesState
2308 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2309 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2310 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2311 getBestColorMode(dataspace, _, _, _, _));
2312 return nextState<ExecuteState>();
2313 }
2314 };
2315
2316 // Call this member function to start using the mini-DSL defined above.
2317 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2318};
2319
2320TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2321 noStrongLayerPrefenceUses_V0_SRGB) {
2322 // If none of the layers indicate a preference, then V0_SRGB is the
2323 // preferred choice (subject to additional checks).
2324 verify().ifTopLayerHasNoPreference()
2325 .andIfMiddleLayerHasNoPreference()
2326 .andIfBottomLayerHasNoPreference()
2327 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2328 .execute();
2329}
2330
2331TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2332 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2333 // If only the topmost layer has a preference, then that is what is chosen.
2334 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2335 .andIfMiddleLayerHasNoPreference()
2336 .andIfBottomLayerHasNoPreference()
2337 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2338 .execute();
2339}
2340
2341TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2342 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2343 // If only the middle layer has a preference, that that is what is chosen.
2344 verify().ifTopLayerHasNoPreference()
2345 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2346 .andIfBottomLayerHasNoPreference()
2347 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2348 .execute();
2349}
2350
2351TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2352 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2353 // If only the middle layer has a preference, that that is what is chosen.
2354 verify().ifTopLayerHasNoPreference()
2355 .andIfMiddleLayerHasNoPreference()
2356 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2357 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2358 .execute();
2359}
2360
2361TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2362 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2363 // If multiple layers have a preference, the topmost value is what is used.
2364 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2365 .andIfMiddleLayerHasNoPreference()
2366 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2367 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2372 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2373 // If multiple layers have a preference, the topmost value is what is used.
2374 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2375 .andIfMiddleLayerHasNoPreference()
2376 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2377 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2378 .execute();
2379}
2380
2381struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2382 : public OutputUpdateColorProfileTest {
2383 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2384 // values, it overrides the layer dataspace choice.
2385
2386 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2387 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2388 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2389
2390 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2391
Lloyd Pique0a456232020-01-16 17:51:13 -08002392 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002393 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2394 }
2395
2396 struct IfForceOutputColorModeState
2397 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2398 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2399 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2400 return nextState<ThenExpectBestColorModeCallUsesState>();
2401 }
2402 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2403 };
2404
2405 struct ThenExpectBestColorModeCallUsesState
2406 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2407 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2408 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2409 getBestColorMode(dataspace, _, _, _, _));
2410 return nextState<ExecuteState>();
2411 }
2412 };
2413
2414 // Call this member function to start using the mini-DSL defined above.
2415 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2416};
2417
2418TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2419 // By default the layer state is used to set the preferred dataspace
2420 verify().ifNoOverride()
2421 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2422 .execute();
2423}
2424
2425TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2426 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2427 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2428 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2429 .execute();
2430}
2431
2432TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2433 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2434 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2435 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2436 .execute();
2437}
2438
2439// HDR output requires all layers to be compatible with the chosen HDR
2440// dataspace, along with there being proper support.
2441struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2442 OutputUpdateColorProfileTest_Hdr() {
2443 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2444 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002445 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002446 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2447 }
2448
2449 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2450 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2451 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2452 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2453
2454 struct IfTopLayerDataspaceState
2455 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2456 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2457 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2458 return nextState<AndTopLayerCompositionTypeState>();
2459 }
2460 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2461 };
2462
2463 struct AndTopLayerCompositionTypeState
2464 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2465 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2466 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2467 return nextState<AndIfBottomLayerDataspaceState>();
2468 }
2469 };
2470
2471 struct AndIfBottomLayerDataspaceState
2472 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2473 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2474 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2475 return nextState<AndBottomLayerCompositionTypeState>();
2476 }
2477 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2478 return andIfBottomLayerIs(kNonHdrDataspace);
2479 }
2480 };
2481
2482 struct AndBottomLayerCompositionTypeState
2483 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2484 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2485 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2486 return nextState<AndIfHasLegacySupportState>();
2487 }
2488 };
2489
2490 struct AndIfHasLegacySupportState
2491 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2492 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2493 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2494 .WillOnce(Return(legacySupport));
2495 return nextState<ThenExpectBestColorModeCallUsesState>();
2496 }
2497 };
2498
2499 struct ThenExpectBestColorModeCallUsesState
2500 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2501 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2502 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2503 getBestColorMode(dataspace, _, _, _, _));
2504 return nextState<ExecuteState>();
2505 }
2506 };
2507
2508 // Call this member function to start using the mini-DSL defined above.
2509 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2510};
2511
2512TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2513 // If all layers use BT2020_PQ, and there are no other special conditions,
2514 // BT2020_PQ is used.
2515 verify().ifTopLayerIs(BT2020_PQ)
2516 .andTopLayerIsREComposed(false)
2517 .andIfBottomLayerIs(BT2020_PQ)
2518 .andBottomLayerIsREComposed(false)
2519 .andIfLegacySupportFor(BT2020_PQ, false)
2520 .thenExpectBestColorModeCallUses(BT2020_PQ)
2521 .execute();
2522}
2523
2524TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2525 // BT2020_PQ is not used if there is only legacy support for it.
2526 verify().ifTopLayerIs(BT2020_PQ)
2527 .andTopLayerIsREComposed(false)
2528 .andIfBottomLayerIs(BT2020_PQ)
2529 .andBottomLayerIsREComposed(false)
2530 .andIfLegacySupportFor(BT2020_PQ, true)
2531 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2532 .execute();
2533}
2534
2535TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2536 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2537 verify().ifTopLayerIs(BT2020_PQ)
2538 .andTopLayerIsREComposed(false)
2539 .andIfBottomLayerIs(BT2020_PQ)
2540 .andBottomLayerIsREComposed(true)
2541 .andIfLegacySupportFor(BT2020_PQ, false)
2542 .thenExpectBestColorModeCallUses(BT2020_PQ)
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2547 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2548 verify().ifTopLayerIs(BT2020_PQ)
2549 .andTopLayerIsREComposed(true)
2550 .andIfBottomLayerIs(BT2020_PQ)
2551 .andBottomLayerIsREComposed(false)
2552 .andIfLegacySupportFor(BT2020_PQ, false)
2553 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2554 .execute();
2555}
2556
2557TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2558 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2559 // are no other special conditions.
2560 verify().ifTopLayerIs(BT2020_PQ)
2561 .andTopLayerIsREComposed(false)
2562 .andIfBottomLayerIs(BT2020_HLG)
2563 .andBottomLayerIsREComposed(false)
2564 .andIfLegacySupportFor(BT2020_PQ, false)
2565 .thenExpectBestColorModeCallUses(BT2020_PQ)
2566 .execute();
2567}
2568
2569TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2570 // BT2020_PQ is not used if there is only legacy support for it.
2571 verify().ifTopLayerIs(BT2020_PQ)
2572 .andTopLayerIsREComposed(false)
2573 .andIfBottomLayerIs(BT2020_HLG)
2574 .andBottomLayerIsREComposed(false)
2575 .andIfLegacySupportFor(BT2020_PQ, true)
2576 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2577 .execute();
2578}
2579
2580TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2581 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2582 verify().ifTopLayerIs(BT2020_PQ)
2583 .andTopLayerIsREComposed(false)
2584 .andIfBottomLayerIs(BT2020_HLG)
2585 .andBottomLayerIsREComposed(true)
2586 .andIfLegacySupportFor(BT2020_PQ, false)
2587 .thenExpectBestColorModeCallUses(BT2020_PQ)
2588 .execute();
2589}
2590
2591TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2592 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2593 verify().ifTopLayerIs(BT2020_PQ)
2594 .andTopLayerIsREComposed(true)
2595 .andIfBottomLayerIs(BT2020_HLG)
2596 .andBottomLayerIsREComposed(false)
2597 .andIfLegacySupportFor(BT2020_PQ, false)
2598 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2599 .execute();
2600}
2601
2602TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2603 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2604 // used if there are no other special conditions.
2605 verify().ifTopLayerIs(BT2020_HLG)
2606 .andTopLayerIsREComposed(false)
2607 .andIfBottomLayerIs(BT2020_PQ)
2608 .andBottomLayerIsREComposed(false)
2609 .andIfLegacySupportFor(BT2020_PQ, false)
2610 .thenExpectBestColorModeCallUses(BT2020_PQ)
2611 .execute();
2612}
2613
2614TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2615 // BT2020_PQ is not used if there is only legacy support for it.
2616 verify().ifTopLayerIs(BT2020_HLG)
2617 .andTopLayerIsREComposed(false)
2618 .andIfBottomLayerIs(BT2020_PQ)
2619 .andBottomLayerIsREComposed(false)
2620 .andIfLegacySupportFor(BT2020_PQ, true)
2621 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2622 .execute();
2623}
2624
2625TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2626 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2627 verify().ifTopLayerIs(BT2020_HLG)
2628 .andTopLayerIsREComposed(false)
2629 .andIfBottomLayerIs(BT2020_PQ)
2630 .andBottomLayerIsREComposed(true)
2631 .andIfLegacySupportFor(BT2020_PQ, false)
2632 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2633 .execute();
2634}
2635
2636TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2637 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2638 verify().ifTopLayerIs(BT2020_HLG)
2639 .andTopLayerIsREComposed(true)
2640 .andIfBottomLayerIs(BT2020_PQ)
2641 .andBottomLayerIsREComposed(false)
2642 .andIfLegacySupportFor(BT2020_PQ, false)
2643 .thenExpectBestColorModeCallUses(BT2020_PQ)
2644 .execute();
2645}
2646
2647TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2648 // If all layers use HLG then HLG is used if there are no other special
2649 // conditions.
2650 verify().ifTopLayerIs(BT2020_HLG)
2651 .andTopLayerIsREComposed(false)
2652 .andIfBottomLayerIs(BT2020_HLG)
2653 .andBottomLayerIsREComposed(false)
2654 .andIfLegacySupportFor(BT2020_HLG, false)
2655 .thenExpectBestColorModeCallUses(BT2020_HLG)
2656 .execute();
2657}
2658
2659TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2660 // BT2020_HLG is not used if there is legacy support for it.
2661 verify().ifTopLayerIs(BT2020_HLG)
2662 .andTopLayerIsREComposed(false)
2663 .andIfBottomLayerIs(BT2020_HLG)
2664 .andBottomLayerIsREComposed(false)
2665 .andIfLegacySupportFor(BT2020_HLG, true)
2666 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2667 .execute();
2668}
2669
2670TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2671 // BT2020_HLG is used even if the bottom layer is client composed.
2672 verify().ifTopLayerIs(BT2020_HLG)
2673 .andTopLayerIsREComposed(false)
2674 .andIfBottomLayerIs(BT2020_HLG)
2675 .andBottomLayerIsREComposed(true)
2676 .andIfLegacySupportFor(BT2020_HLG, false)
2677 .thenExpectBestColorModeCallUses(BT2020_HLG)
2678 .execute();
2679}
2680
2681TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2682 // BT2020_HLG is used even if the top layer is client composed.
2683 verify().ifTopLayerIs(BT2020_HLG)
2684 .andTopLayerIsREComposed(true)
2685 .andIfBottomLayerIs(BT2020_HLG)
2686 .andBottomLayerIsREComposed(false)
2687 .andIfLegacySupportFor(BT2020_HLG, false)
2688 .thenExpectBestColorModeCallUses(BT2020_HLG)
2689 .execute();
2690}
2691
2692TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2693 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2694 verify().ifTopLayerIs(BT2020_PQ)
2695 .andTopLayerIsREComposed(false)
2696 .andIfBottomLayerIsNotHdr()
2697 .andBottomLayerIsREComposed(false)
2698 .andIfLegacySupportFor(BT2020_PQ, false)
2699 .thenExpectBestColorModeCallUses(BT2020_PQ)
2700 .execute();
2701}
2702
2703TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2704 // If all layers use HLG then HLG is used if there are no other special
2705 // conditions.
2706 verify().ifTopLayerIs(BT2020_HLG)
2707 .andTopLayerIsREComposed(false)
2708 .andIfBottomLayerIsNotHdr()
2709 .andBottomLayerIsREComposed(true)
2710 .andIfLegacySupportFor(BT2020_HLG, false)
2711 .thenExpectBestColorModeCallUses(BT2020_HLG)
2712 .execute();
2713}
2714
2715struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2716 : public OutputUpdateColorProfileTest {
2717 // The various values for CompositionRefreshArgs::outputColorSetting affect
2718 // the chosen renderIntent, along with whether the preferred dataspace is an
2719 // HDR dataspace or not.
2720
2721 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2722 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2723 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2724 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002725 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002726 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2727 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2728 .WillRepeatedly(Return(false));
2729 }
2730
2731 // The tests here involve enough state and GMock setup that using a mini-DSL
2732 // makes the tests much more readable, and allows the test to focus more on
2733 // the intent than on some of the details.
2734
2735 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2736 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2737
2738 struct IfDataspaceChosenState
2739 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2740 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2741 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2742 return nextState<AndOutputColorSettingState>();
2743 }
2744 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2745 return ifDataspaceChosenIs(kNonHdrDataspace);
2746 }
2747 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2748 };
2749
2750 struct AndOutputColorSettingState
2751 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2752 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2753 getInstance()->mRefreshArgs.outputColorSetting = setting;
2754 return nextState<ThenExpectBestColorModeCallUsesState>();
2755 }
2756 };
2757
2758 struct ThenExpectBestColorModeCallUsesState
2759 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2760 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2761 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2762 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2763 _, _));
2764 return nextState<ExecuteState>();
2765 }
2766 };
2767
2768 // Tests call one of these two helper member functions to start using the
2769 // mini-DSL defined above.
2770 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2771};
2772
2773TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2774 Managed_NonHdr_Prefers_Colorimetric) {
2775 verify().ifDataspaceChosenIsNonHdr()
2776 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2777 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2778 .execute();
2779}
2780
2781TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2782 Managed_Hdr_Prefers_ToneMapColorimetric) {
2783 verify().ifDataspaceChosenIsHdr()
2784 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2785 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2786 .execute();
2787}
2788
2789TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2790 verify().ifDataspaceChosenIsNonHdr()
2791 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2792 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2793 .execute();
2794}
2795
2796TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2797 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2798 verify().ifDataspaceChosenIsHdr()
2799 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2800 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2801 .execute();
2802}
2803
2804TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2805 verify().ifDataspaceChosenIsNonHdr()
2806 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2807 .thenExpectBestColorModeCallUses(
2808 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2809 .execute();
2810}
2811
2812TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2813 verify().ifDataspaceChosenIsHdr()
2814 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2815 .thenExpectBestColorModeCallUses(
2816 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2817 .execute();
2818}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002819
2820/*
2821 * Output::beginFrame()
2822 */
2823
Lloyd Piquee5965952019-11-18 16:16:32 -08002824struct OutputBeginFrameTest : public ::testing::Test {
2825 using TestType = OutputBeginFrameTest;
2826
2827 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002828 // Sets up the helper functions called by the function under test to use
2829 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002830 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002831 };
2832
2833 OutputBeginFrameTest() {
2834 mOutput.setDisplayColorProfileForTest(
2835 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2836 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2837 }
2838
2839 struct IfGetDirtyRegionExpectationState
2840 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2841 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002842 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002843 return nextState<AndIfGetOutputLayerCountExpectationState>();
2844 }
2845 };
2846
2847 struct AndIfGetOutputLayerCountExpectationState
2848 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2849 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2850 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2851 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2852 }
2853 };
2854
2855 struct AndIfLastCompositionHadVisibleLayersState
2856 : public CallOrderStateMachineHelper<TestType,
2857 AndIfLastCompositionHadVisibleLayersState> {
2858 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2859 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2860 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2861 }
2862 };
2863
2864 struct ThenExpectRenderSurfaceBeginFrameCallState
2865 : public CallOrderStateMachineHelper<TestType,
2866 ThenExpectRenderSurfaceBeginFrameCallState> {
2867 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2868 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2869 return nextState<ExecuteState>();
2870 }
2871 };
2872
2873 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2874 [[nodiscard]] auto execute() {
2875 getInstance()->mOutput.beginFrame();
2876 return nextState<CheckPostconditionHadVisibleLayersState>();
2877 }
2878 };
2879
2880 struct CheckPostconditionHadVisibleLayersState
2881 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2882 void checkPostconditionHadVisibleLayers(bool expected) {
2883 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2884 }
2885 };
2886
2887 // Tests call one of these two helper member functions to start using the
2888 // mini-DSL defined above.
2889 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2890
2891 static const Region kEmptyRegion;
2892 static const Region kNotEmptyRegion;
2893
2894 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2895 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2896 StrictMock<OutputPartialMock> mOutput;
2897};
2898
2899const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2900const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2901
2902TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2903 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2904 .andIfGetOutputLayerCountReturns(1u)
2905 .andIfLastCompositionHadVisibleLayersIs(true)
2906 .thenExpectRenderSurfaceBeginFrameCall(true)
2907 .execute()
2908 .checkPostconditionHadVisibleLayers(true);
2909}
2910
2911TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2912 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2913 .andIfGetOutputLayerCountReturns(0u)
2914 .andIfLastCompositionHadVisibleLayersIs(true)
2915 .thenExpectRenderSurfaceBeginFrameCall(true)
2916 .execute()
2917 .checkPostconditionHadVisibleLayers(false);
2918}
2919
2920TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2921 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2922 .andIfGetOutputLayerCountReturns(1u)
2923 .andIfLastCompositionHadVisibleLayersIs(false)
2924 .thenExpectRenderSurfaceBeginFrameCall(true)
2925 .execute()
2926 .checkPostconditionHadVisibleLayers(true);
2927}
2928
2929TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2930 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2931 .andIfGetOutputLayerCountReturns(0u)
2932 .andIfLastCompositionHadVisibleLayersIs(false)
2933 .thenExpectRenderSurfaceBeginFrameCall(false)
2934 .execute()
2935 .checkPostconditionHadVisibleLayers(false);
2936}
2937
2938TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2939 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2940 .andIfGetOutputLayerCountReturns(1u)
2941 .andIfLastCompositionHadVisibleLayersIs(true)
2942 .thenExpectRenderSurfaceBeginFrameCall(false)
2943 .execute()
2944 .checkPostconditionHadVisibleLayers(true);
2945}
2946
2947TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2948 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2949 .andIfGetOutputLayerCountReturns(0u)
2950 .andIfLastCompositionHadVisibleLayersIs(true)
2951 .thenExpectRenderSurfaceBeginFrameCall(false)
2952 .execute()
2953 .checkPostconditionHadVisibleLayers(true);
2954}
2955
2956TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2957 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2958 .andIfGetOutputLayerCountReturns(1u)
2959 .andIfLastCompositionHadVisibleLayersIs(false)
2960 .thenExpectRenderSurfaceBeginFrameCall(false)
2961 .execute()
2962 .checkPostconditionHadVisibleLayers(false);
2963}
2964
2965TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2966 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2967 .andIfGetOutputLayerCountReturns(0u)
2968 .andIfLastCompositionHadVisibleLayersIs(false)
2969 .thenExpectRenderSurfaceBeginFrameCall(false)
2970 .execute()
2971 .checkPostconditionHadVisibleLayers(false);
2972}
2973
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002974/*
2975 * Output::devOptRepaintFlash()
2976 */
2977
Lloyd Piquedb462d82019-11-19 17:58:46 -08002978struct OutputDevOptRepaintFlashTest : public testing::Test {
2979 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002980 // Sets up the helper functions called by the function under test to use
2981 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002982 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002983 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002984 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002985 const Region&, const compositionengine::CompositionRefreshArgs&,
2986 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002987 MOCK_METHOD0(postFramebuffer, void());
2988 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002989 MOCK_METHOD0(updateProtectedContentState, void());
2990 MOCK_METHOD2(dequeueRenderBuffer,
2991 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002992 };
2993
2994 OutputDevOptRepaintFlashTest() {
2995 mOutput.setDisplayColorProfileForTest(
2996 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2997 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2998 }
2999
3000 static const Region kEmptyRegion;
3001 static const Region kNotEmptyRegion;
3002
3003 StrictMock<OutputPartialMock> mOutput;
3004 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3005 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3006 CompositionRefreshArgs mRefreshArgs;
3007};
3008
3009const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
3010const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
3011
3012TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
3013 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08003014 mOutput.mState.isEnabled = true;
3015
3016 mOutput.devOptRepaintFlash(mRefreshArgs);
3017}
3018
3019TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
3020 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003021 mOutput.mState.isEnabled = false;
3022
3023 InSequence seq;
3024 EXPECT_CALL(mOutput, postFramebuffer());
3025 EXPECT_CALL(mOutput, prepareFrame());
3026
3027 mOutput.devOptRepaintFlash(mRefreshArgs);
3028}
3029
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003030TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003031 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003032 mOutput.mState.isEnabled = true;
3033
3034 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003035 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003036 EXPECT_CALL(mOutput, postFramebuffer());
3037 EXPECT_CALL(mOutput, prepareFrame());
3038
3039 mOutput.devOptRepaintFlash(mRefreshArgs);
3040}
3041
3042TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3043 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003044 mOutput.mState.isEnabled = true;
3045
3046 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003047 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003048 EXPECT_CALL(mOutput, updateProtectedContentState());
3049 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3050 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003051 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3052 EXPECT_CALL(mOutput, postFramebuffer());
3053 EXPECT_CALL(mOutput, prepareFrame());
3054
3055 mOutput.devOptRepaintFlash(mRefreshArgs);
3056}
3057
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003058/*
3059 * Output::finishFrame()
3060 */
3061
Lloyd Pique03561a62019-11-19 18:34:52 -08003062struct OutputFinishFrameTest : public testing::Test {
3063 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003064 // Sets up the helper functions called by the function under test to use
3065 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003066 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003067 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003068 const Region&, const compositionengine::CompositionRefreshArgs&,
3069 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003070 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003071 MOCK_METHOD0(updateProtectedContentState, void());
3072 MOCK_METHOD2(dequeueRenderBuffer,
3073 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003074 };
3075
3076 OutputFinishFrameTest() {
3077 mOutput.setDisplayColorProfileForTest(
3078 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3079 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3080 }
3081
3082 StrictMock<OutputPartialMock> mOutput;
3083 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3084 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3085 CompositionRefreshArgs mRefreshArgs;
3086};
3087
3088TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3089 mOutput.mState.isEnabled = false;
3090
Vishnu Naira3140382022-02-24 14:07:11 -08003091 impl::GpuCompositionResult result;
3092 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003093}
3094
3095TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3096 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003097 EXPECT_CALL(mOutput, updateProtectedContentState());
3098 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3099 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003100
Vishnu Naira3140382022-02-24 14:07:11 -08003101 impl::GpuCompositionResult result;
3102 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003103}
3104
3105TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3106 mOutput.mState.isEnabled = true;
3107
3108 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003109 EXPECT_CALL(mOutput, updateProtectedContentState());
3110 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3111 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003112 .WillOnce(Return(ByMove(base::unique_fd())));
3113 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3114
Vishnu Naira3140382022-02-24 14:07:11 -08003115 impl::GpuCompositionResult result;
3116 mOutput.finishFrame(mRefreshArgs, std::move(result));
3117}
3118
3119TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3120 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003121 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003122 InSequence seq;
3123 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3124
3125 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003126 mOutput.finishFrame(mRefreshArgs, std::move(result));
3127}
3128
3129TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3130 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003131 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003132
3133 InSequence seq;
3134
3135 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003136 result.buffer =
3137 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3138 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3139 2);
3140
3141 EXPECT_CALL(mOutput,
3142 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3143 Eq(ByRef(result.fence))))
3144 .WillOnce(Return(ByMove(base::unique_fd())));
3145 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3146 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003147}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003148
3149/*
3150 * Output::postFramebuffer()
3151 */
3152
Lloyd Pique07178e32019-11-19 19:15:26 -08003153struct OutputPostFramebufferTest : public testing::Test {
3154 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003155 // Sets up the helper functions called by the function under test to use
3156 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003157 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3158 };
3159
3160 struct Layer {
3161 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003162 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003163 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3164 }
3165
3166 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003167 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003168 StrictMock<HWC2::mock::Layer> hwc2Layer;
3169 };
3170
3171 OutputPostFramebufferTest() {
3172 mOutput.setDisplayColorProfileForTest(
3173 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3174 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3175
3176 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3177 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3178 .WillRepeatedly(Return(&mLayer1.outputLayer));
3179 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3180 .WillRepeatedly(Return(&mLayer2.outputLayer));
3181 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3182 .WillRepeatedly(Return(&mLayer3.outputLayer));
3183 }
3184
3185 StrictMock<OutputPartialMock> mOutput;
3186 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3187 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3188
3189 Layer mLayer1;
3190 Layer mLayer2;
3191 Layer mLayer3;
3192};
3193
3194TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3195 mOutput.mState.isEnabled = false;
3196
3197 mOutput.postFramebuffer();
3198}
3199
3200TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3201 mOutput.mState.isEnabled = true;
3202
3203 compositionengine::Output::FrameFences frameFences;
3204
3205 // This should happen even if there are no output layers.
3206 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3207
3208 // For this test in particular we want to make sure the call expectations
3209 // setup below are satisfied in the specific order.
3210 InSequence seq;
3211
Lloyd Pique07178e32019-11-19 19:15:26 -08003212 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3213 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3214
3215 mOutput.postFramebuffer();
3216}
3217
3218TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3219 // Simulate getting release fences from each layer, and ensure they are passed to the
3220 // front-end layer interface for each layer correctly.
3221
3222 mOutput.mState.isEnabled = true;
3223
3224 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003225 sp<Fence> layer1Fence = sp<Fence>::make();
3226 sp<Fence> layer2Fence = sp<Fence>::make();
3227 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003228
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003229 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003230 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3231 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3232 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3233
Lloyd Pique07178e32019-11-19 19:15:26 -08003234 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3235 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3236
3237 // Compare the pointers values of each fence to make sure the correct ones
3238 // are passed. This happens to work with the current implementation, but
3239 // would not survive certain calls like Fence::merge() which would return a
3240 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003241 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003242 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003243 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003244 });
3245 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003246 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003247 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003248 });
3249 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003250 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003251 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003252 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003253
3254 mOutput.postFramebuffer();
3255}
3256
3257TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3258 mOutput.mState.isEnabled = true;
3259 mOutput.mState.usesClientComposition = true;
3260
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003261 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003262 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3263 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3264 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3265 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003266
Lloyd Pique07178e32019-11-19 19:15:26 -08003267 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3268 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3269
3270 // Fence::merge is called, and since none of the fences are actually valid,
3271 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3272 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003273 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3274 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3275 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003276
3277 mOutput.postFramebuffer();
3278}
3279
3280TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3281 mOutput.mState.isEnabled = true;
3282 mOutput.mState.usesClientComposition = true;
3283
3284 // This should happen even if there are no (current) output layers.
3285 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3286
3287 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003288 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3289 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3290 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003291 Output::ReleasedLayers layers;
3292 layers.push_back(releasedLayer1);
3293 layers.push_back(releasedLayer2);
3294 layers.push_back(releasedLayer3);
3295 mOutput.setReleasedLayers(std::move(layers));
3296
3297 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003298 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003299 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003300 frameFences.presentFence = presentFence;
3301
Lloyd Pique07178e32019-11-19 19:15:26 -08003302 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3303 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3304
3305 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003306 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003307 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003308 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003309 });
3310 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003311 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003312 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003313 });
3314 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003315 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003316 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003317 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003318
3319 mOutput.postFramebuffer();
3320
3321 // After the call the list of released layers should have been cleared.
3322 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3323}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003324
3325/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003326 * Output::composeSurfaces()
3327 */
3328
3329struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003330 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003331
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003332 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003333 // Sets up the helper functions called by the function under test to use
3334 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003335 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003336 MOCK_METHOD3(generateClientCompositionRequests,
3337 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003338 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003339 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003340 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003341 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3342 (override));
3343 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003344 };
3345
3346 OutputComposeSurfacesTest() {
3347 mOutput.setDisplayColorProfileForTest(
3348 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3349 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003350 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003351
Angel Aguayob084e0c2021-08-04 23:27:28 +00003352 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3353 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3354 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3355 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3356 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003357 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003358 mOutput.mState.dataspace = kDefaultOutputDataspace;
3359 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3360 mOutput.mState.isSecure = false;
3361 mOutput.mState.needsFiltering = false;
3362 mOutput.mState.usesClientComposition = true;
3363 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003364 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003365 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003366 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003367
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003368 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003369 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003370 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003371 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3372 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003373 }
3374
Lloyd Pique6818fa52019-12-03 12:32:13 -08003375 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3376 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003377 base::unique_fd fence;
3378 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3379 const bool success =
3380 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3381 if (success) {
3382 getInstance()->mReadyFence =
3383 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3384 externalTexture, fence);
3385 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003386 return nextState<FenceCheckState>();
3387 }
3388 };
3389
3390 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3391 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3392
3393 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3394 };
3395
3396 // Call this member function to start using the mini-DSL defined above.
3397 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3398
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003399 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3400 static constexpr uint32_t kDefaultOutputOrientationFlags =
3401 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003402 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3403 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3404 static constexpr float kDefaultMaxLuminance = 0.9f;
3405 static constexpr float kDefaultAvgLuminance = 0.7f;
3406 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003407 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003408 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003409 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410
3411 static const Rect kDefaultOutputFrame;
3412 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003413 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003414 static const mat4 kDefaultColorTransformMat;
3415
3416 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003417 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003418 static const HdrCapabilities kHdrCapabilities;
3419
Lloyd Pique56eba802019-08-28 15:45:25 -07003420 StrictMock<mock::CompositionEngine> mCompositionEngine;
3421 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003422 // TODO: make this is a proper mock.
3423 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003424 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3425 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003426 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003427 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003428 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003429 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003430 renderengine::impl::ExternalTexture::Usage::READABLE |
3431 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432
3433 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003434};
3435
3436const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3437const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003438const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003439const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003440const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003441const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003442
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443const HdrCapabilities OutputComposeSurfacesTest::
3444 kHdrCapabilities{{},
3445 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3446 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3447 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003448
Lloyd Piquea76ce462020-01-14 13:06:37 -08003449TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003450 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003451
Lloyd Piquee9eff972020-05-05 12:36:44 -07003452 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003453 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003454
Lloyd Piquea76ce462020-01-14 13:06:37 -08003455 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3456
Lloyd Pique6818fa52019-12-03 12:32:13 -08003457 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003458}
3459
Lloyd Piquee9eff972020-05-05 12:36:44 -07003460TEST_F(OutputComposeSurfacesTest,
3461 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3462 mOutput.mState.usesClientComposition = false;
3463 mOutput.mState.flipClientTarget = true;
3464
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003466 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003467
3468 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3469 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3470
3471 verify().execute().expectAFenceWasReturned();
3472}
3473
3474TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3475 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003476 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003477
3478 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3479
3480 verify().execute().expectNoFenceWasReturned();
3481}
3482
3483TEST_F(OutputComposeSurfacesTest,
3484 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3485 mOutput.mState.usesClientComposition = false;
3486 mOutput.mState.flipClientTarget = true;
3487
3488 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003489 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003490
Lloyd Pique6818fa52019-12-03 12:32:13 -08003491 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003492
Lloyd Pique6818fa52019-12-03 12:32:13 -08003493 verify().execute().expectNoFenceWasReturned();
3494}
Lloyd Pique56eba802019-08-28 15:45:25 -07003495
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3497 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3498 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3499 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003500 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003501 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003502 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003503 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3504 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003505
Lloyd Pique6818fa52019-12-03 12:32:13 -08003506 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003507 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3508 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003509 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003510 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003511 base::unique_fd&&) -> ftl::Future<FenceResult> {
3512 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003513 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003514 verify().execute().expectAFenceWasReturned();
3515}
Lloyd Pique56eba802019-08-28 15:45:25 -07003516
Lloyd Pique6818fa52019-12-03 12:32:13 -08003517TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003518 LayerFE::LayerSettings r1;
3519 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003520
3521 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3522 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3523
3524 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3525 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3526 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003527 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003528 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003529 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003530 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3531 .WillRepeatedly(
3532 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003533 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003534 clientCompositionLayers.emplace_back(r2);
3535 }));
3536
3537 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003538 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003539 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003540 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003541 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003542 base::unique_fd&&) -> ftl::Future<FenceResult> {
3543 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003544 });
Alec Mouri1684c702021-02-04 12:27:26 -08003545
3546 verify().execute().expectAFenceWasReturned();
3547}
3548
3549TEST_F(OutputComposeSurfacesTest,
3550 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3551 LayerFE::LayerSettings r1;
3552 LayerFE::LayerSettings r2;
3553
3554 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3555 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003556 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003557
3558 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3559 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3560 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3561 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003562 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003563 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3564 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3565 .WillRepeatedly(
3566 Invoke([&](const Region&,
3567 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3568 clientCompositionLayers.emplace_back(r2);
3569 }));
3570
3571 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003572 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003573 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003574 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003575 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003576 base::unique_fd&&) -> ftl::Future<FenceResult> {
3577 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003578 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003579
3580 verify().execute().expectAFenceWasReturned();
3581}
3582
Vishnu Nair9b079a22020-01-21 14:36:08 -08003583TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3584 mOutput.cacheClientCompositionRequests(0);
3585 LayerFE::LayerSettings r1;
3586 LayerFE::LayerSettings r2;
3587
3588 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3589 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3590
3591 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3592 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3593 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003594 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003595 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003596 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3597 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3598 .WillRepeatedly(Return());
3599
3600 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003601 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003602 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003603 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3604 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003605
3606 verify().execute().expectAFenceWasReturned();
3607 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3608
3609 verify().execute().expectAFenceWasReturned();
3610 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3611}
3612
3613TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3614 mOutput.cacheClientCompositionRequests(3);
3615 LayerFE::LayerSettings r1;
3616 LayerFE::LayerSettings r2;
3617
3618 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3619 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3620
3621 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3622 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3623 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003624 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003625 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003626 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3627 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3628 .WillRepeatedly(Return());
3629
3630 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003631 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003632 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003633 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3634
3635 verify().execute().expectAFenceWasReturned();
3636 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3637
3638 // We do not expect another call to draw layers.
3639 verify().execute().expectAFenceWasReturned();
3640 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3641}
3642
3643TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3644 LayerFE::LayerSettings r1;
3645 LayerFE::LayerSettings r2;
3646
3647 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3648 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3649
3650 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3651 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3652 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003653 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003654 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003655 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3656 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3657 .WillRepeatedly(Return());
3658
Alec Mouria90a5702021-04-16 16:36:21 +00003659 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003660 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003661 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003662 renderengine::impl::ExternalTexture::Usage::READABLE |
3663 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003664 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3665 .WillOnce(Return(mOutputBuffer))
3666 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003667 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003668 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003669 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003670 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003671 base::unique_fd&&) -> ftl::Future<FenceResult> {
3672 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003673 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003674
3675 verify().execute().expectAFenceWasReturned();
3676 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3677
3678 verify().execute().expectAFenceWasReturned();
3679 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3680}
3681
3682TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3683 LayerFE::LayerSettings r1;
3684 LayerFE::LayerSettings r2;
3685 LayerFE::LayerSettings r3;
3686
3687 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3688 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3689 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3690
3691 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3692 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3693 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003694 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003695 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003696 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3697 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3698 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3699 .WillRepeatedly(Return());
3700
3701 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003702 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003703 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Sally Qi59a9f502021-10-12 18:53:23 +00003704 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003705 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706
3707 verify().execute().expectAFenceWasReturned();
3708 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3709
3710 verify().execute().expectAFenceWasReturned();
3711 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3712}
3713
Lloyd Pique6818fa52019-12-03 12:32:13 -08003714struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3715 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3716 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003717 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003718 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003719 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003720 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3721 .WillRepeatedly(Return());
3722 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3723 }
3724
3725 struct MixedCompositionState
3726 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3727 auto ifMixedCompositionIs(bool used) {
3728 getInstance()->mOutput.mState.usesDeviceComposition = used;
3729 return nextState<OutputUsesHdrState>();
3730 }
3731 };
3732
3733 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3734 auto andIfUsesHdr(bool used) {
3735 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3736 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003737 return nextState<OutputWithDisplayBrightnessNits>();
3738 }
3739 };
3740
3741 struct OutputWithDisplayBrightnessNits
3742 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3743 auto withDisplayBrightnessNits(float nits) {
3744 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003745 return nextState<OutputWithDimmingStage>();
3746 }
3747 };
3748
3749 struct OutputWithDimmingStage
3750 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3751 auto withDimmingStage(
3752 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3753 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003754 return nextState<OutputWithRenderIntent>();
3755 }
3756 };
3757
3758 struct OutputWithRenderIntent
3759 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3760 auto withRenderIntent(
3761 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3762 getInstance()->mOutput.mState.renderIntent =
3763 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003764 return nextState<SkipColorTransformState>();
3765 }
3766 };
3767
3768 struct SkipColorTransformState
3769 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3770 auto andIfSkipColorTransform(bool skip) {
3771 // May be called zero or one times.
3772 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3773 .WillRepeatedly(Return(skip));
3774 return nextState<ExpectDisplaySettingsState>();
3775 }
3776 };
3777
3778 struct ExpectDisplaySettingsState
3779 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3780 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003781 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003782 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003783 return nextState<ExecuteState>();
3784 }
3785 };
3786
3787 // Call this member function to start using the mini-DSL defined above.
3788 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3789};
3790
3791TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3792 verify().ifMixedCompositionIs(true)
3793 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003794 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003795 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003796 .withRenderIntent(
3797 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003798 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003799 .thenExpectDisplaySettingsUsed(
3800 {.physicalDisplay = kDefaultOutputDestinationClip,
3801 .clip = kDefaultOutputViewport,
3802 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003803 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003804 .outputDataspace = kDefaultOutputDataspace,
3805 .colorTransform = kDefaultColorTransformMat,
3806 .deviceHandlesColorTransform = true,
3807 .orientation = kDefaultOutputOrientationFlags,
3808 .targetLuminanceNits = kClientTargetLuminanceNits,
3809 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003810 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3811 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3812 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003813 .execute()
3814 .expectAFenceWasReturned();
3815}
3816
3817TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3818 forHdrMixedCompositionWithDisplayBrightness) {
3819 verify().ifMixedCompositionIs(true)
3820 .andIfUsesHdr(true)
3821 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003822 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003823 .withRenderIntent(
3824 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003825 .andIfSkipColorTransform(false)
3826 .thenExpectDisplaySettingsUsed(
3827 {.physicalDisplay = kDefaultOutputDestinationClip,
3828 .clip = kDefaultOutputViewport,
3829 .maxLuminance = kDefaultMaxLuminance,
3830 .currentLuminanceNits = kDisplayLuminance,
3831 .outputDataspace = kDefaultOutputDataspace,
3832 .colorTransform = kDefaultColorTransformMat,
3833 .deviceHandlesColorTransform = true,
3834 .orientation = kDefaultOutputOrientationFlags,
3835 .targetLuminanceNits = kClientTargetLuminanceNits,
3836 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003837 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3838 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3839 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003840 .execute()
3841 .expectAFenceWasReturned();
3842}
3843
3844TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3845 forHdrMixedCompositionWithDimmingStage) {
3846 verify().ifMixedCompositionIs(true)
3847 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003848 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003849 .withDimmingStage(
3850 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003851 .withRenderIntent(
3852 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003853 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003854 .thenExpectDisplaySettingsUsed(
3855 {.physicalDisplay = kDefaultOutputDestinationClip,
3856 .clip = kDefaultOutputViewport,
3857 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003858 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003859 .outputDataspace = kDefaultOutputDataspace,
3860 .colorTransform = kDefaultColorTransformMat,
3861 .deviceHandlesColorTransform = true,
3862 .orientation = kDefaultOutputOrientationFlags,
3863 .targetLuminanceNits = kClientTargetLuminanceNits,
3864 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003865 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3866 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3867 COLORIMETRIC})
3868 .execute()
3869 .expectAFenceWasReturned();
3870}
3871
3872TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3873 forHdrMixedCompositionWithRenderIntent) {
3874 verify().ifMixedCompositionIs(true)
3875 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003876 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003877 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3878 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3879 .andIfSkipColorTransform(false)
3880 .thenExpectDisplaySettingsUsed(
3881 {.physicalDisplay = kDefaultOutputDestinationClip,
3882 .clip = kDefaultOutputViewport,
3883 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003884 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003885 .outputDataspace = kDefaultOutputDataspace,
3886 .colorTransform = kDefaultColorTransformMat,
3887 .deviceHandlesColorTransform = true,
3888 .orientation = kDefaultOutputOrientationFlags,
3889 .targetLuminanceNits = kClientTargetLuminanceNits,
3890 .dimmingStage =
3891 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3892 .renderIntent =
3893 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3894 .execute()
3895 .expectAFenceWasReturned();
3896}
3897
3898TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3899 verify().ifMixedCompositionIs(true)
3900 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003901 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003902 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3903 .withRenderIntent(
3904 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3905 .andIfSkipColorTransform(false)
3906 .thenExpectDisplaySettingsUsed(
3907 {.physicalDisplay = kDefaultOutputDestinationClip,
3908 .clip = kDefaultOutputViewport,
3909 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003910 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003911 .outputDataspace = kDefaultOutputDataspace,
3912 .colorTransform = kDefaultColorTransformMat,
3913 .deviceHandlesColorTransform = true,
3914 .orientation = kDefaultOutputOrientationFlags,
3915 .targetLuminanceNits = kClientTargetLuminanceNits,
3916 .dimmingStage =
3917 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3918 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3919 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003920 .execute()
3921 .expectAFenceWasReturned();
3922}
3923
3924TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3925 verify().ifMixedCompositionIs(false)
3926 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003927 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003928 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003929 .withRenderIntent(
3930 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003931 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003932 .thenExpectDisplaySettingsUsed(
3933 {.physicalDisplay = kDefaultOutputDestinationClip,
3934 .clip = kDefaultOutputViewport,
3935 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003936 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003937 .outputDataspace = kDefaultOutputDataspace,
3938 .colorTransform = kDefaultColorTransformMat,
3939 .deviceHandlesColorTransform = false,
3940 .orientation = kDefaultOutputOrientationFlags,
3941 .targetLuminanceNits = kClientTargetLuminanceNits,
3942 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003943 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3944 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3945 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003946 .execute()
3947 .expectAFenceWasReturned();
3948}
3949
3950TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3951 verify().ifMixedCompositionIs(false)
3952 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003953 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003954 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003955 .withRenderIntent(
3956 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003957 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003958 .thenExpectDisplaySettingsUsed(
3959 {.physicalDisplay = kDefaultOutputDestinationClip,
3960 .clip = kDefaultOutputViewport,
3961 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003962 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003963 .outputDataspace = kDefaultOutputDataspace,
3964 .colorTransform = kDefaultColorTransformMat,
3965 .deviceHandlesColorTransform = false,
3966 .orientation = kDefaultOutputOrientationFlags,
3967 .targetLuminanceNits = kClientTargetLuminanceNits,
3968 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003969 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3970 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3971 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003972 .execute()
3973 .expectAFenceWasReturned();
3974}
3975
3976TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3977 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3978 verify().ifMixedCompositionIs(false)
3979 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003980 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003981 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003982 .withRenderIntent(
3983 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003984 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003985 .thenExpectDisplaySettingsUsed(
3986 {.physicalDisplay = kDefaultOutputDestinationClip,
3987 .clip = kDefaultOutputViewport,
3988 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003989 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003990 .outputDataspace = kDefaultOutputDataspace,
3991 .colorTransform = kDefaultColorTransformMat,
3992 .deviceHandlesColorTransform = true,
3993 .orientation = kDefaultOutputOrientationFlags,
3994 .targetLuminanceNits = kClientTargetLuminanceNits,
3995 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003996 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3997 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3998 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003999 .execute()
4000 .expectAFenceWasReturned();
4001}
4002
4003struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4004 struct Layer {
4005 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004006 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4007 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004008 }
4009
4010 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004011 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004012 LayerFECompositionState mLayerFEState;
4013 };
4014
4015 OutputComposeSurfacesTest_HandlesProtectedContent() {
4016 mLayer1.mLayerFEState.hasProtectedContent = false;
4017 mLayer2.mLayerFEState.hasProtectedContent = false;
4018
4019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4020 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4021 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4022 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4023 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4024
4025 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4026
4027 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4028
Robert Carrccab4242021-09-28 16:53:03 -07004029 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004030 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004031 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4032 .WillRepeatedly(Return());
4033 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004034 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004035 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4036 const std::vector<renderengine::LayerSettings>&,
4037 const std::shared_ptr<renderengine::ExternalTexture>&,
4038 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
4039 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4040 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004041 }
4042
4043 Layer mLayer1;
4044 Layer mLayer2;
4045};
4046
Lloyd Pique6818fa52019-12-03 12:32:13 -08004047TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4048 mOutput.mState.isSecure = true;
4049 mLayer2.mLayerFEState.hasProtectedContent = false;
4050 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004051 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004052 EXPECT_CALL(*mRenderSurface, setProtected(false));
4053
Vishnu Naira3140382022-02-24 14:07:11 -08004054 base::unique_fd fd;
4055 std::shared_ptr<renderengine::ExternalTexture> tex;
4056 mOutput.updateProtectedContentState();
4057 mOutput.dequeueRenderBuffer(&fd, &tex);
4058 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004059}
4060
4061TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4062 mOutput.mState.isSecure = true;
4063 mLayer2.mLayerFEState.hasProtectedContent = true;
4064 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4065
4066 // For this test, we also check the call order of key functions.
4067 InSequence seq;
4068
Lloyd Pique6818fa52019-12-03 12:32:13 -08004069 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004070 EXPECT_CALL(*mRenderSurface, setProtected(true));
4071 // Must happen after setting the protected content state.
4072 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004073 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004074 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004075
Vishnu Naira3140382022-02-24 14:07:11 -08004076 base::unique_fd fd;
4077 std::shared_ptr<renderengine::ExternalTexture> tex;
4078 mOutput.updateProtectedContentState();
4079 mOutput.dequeueRenderBuffer(&fd, &tex);
4080 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004081}
4082
4083TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4084 mOutput.mState.isSecure = true;
4085 mLayer2.mLayerFEState.hasProtectedContent = true;
4086 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004087 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4088
Vishnu Naira3140382022-02-24 14:07:11 -08004089 base::unique_fd fd;
4090 std::shared_ptr<renderengine::ExternalTexture> tex;
4091 mOutput.updateProtectedContentState();
4092 mOutput.dequeueRenderBuffer(&fd, &tex);
4093 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004094}
4095
Lloyd Pique6818fa52019-12-03 12:32:13 -08004096TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4097 mOutput.mState.isSecure = true;
4098 mLayer2.mLayerFEState.hasProtectedContent = true;
4099 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004100 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004101
Vishnu Naira3140382022-02-24 14:07:11 -08004102 base::unique_fd fd;
4103 std::shared_ptr<renderengine::ExternalTexture> tex;
4104 mOutput.updateProtectedContentState();
4105 mOutput.dequeueRenderBuffer(&fd, &tex);
4106 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004107}
4108
4109struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4110 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4111 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4112 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4113 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004114 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004115 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4116 .WillRepeatedly(Return());
4117 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4118 }
4119};
4120
4121TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4122 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4123
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004124 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004125 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004126 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004127
4128 // For this test, we also check the call order of key functions.
4129 InSequence seq;
4130
4131 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004132 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004133 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004134
Vishnu Naira3140382022-02-24 14:07:11 -08004135 base::unique_fd fd;
4136 std::shared_ptr<renderengine::ExternalTexture> tex;
4137 mOutput.updateProtectedContentState();
4138 mOutput.dequeueRenderBuffer(&fd, &tex);
4139 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004140}
4141
4142struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4143 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4144 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4145 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004146 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004147 mOutput.editState().isEnabled = true;
4148
Snild Dolkow9e217d62020-04-22 15:53:42 +02004149 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004150 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004151 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4152 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004153 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004154 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004155 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004156 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004157 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4158 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4159 .WillRepeatedly(Return(&mLayer.outputLayer));
4160 }
4161
4162 NonInjectedLayer mLayer;
4163 compositionengine::CompositionRefreshArgs mRefreshArgs;
4164};
4165
4166TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4167 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004168 mOutput.updateCompositionState(mRefreshArgs);
4169 mOutput.planComposition();
4170 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004171
4172 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004173
4174 base::unique_fd fd;
4175 std::shared_ptr<renderengine::ExternalTexture> tex;
4176 mOutput.updateProtectedContentState();
4177 mOutput.dequeueRenderBuffer(&fd, &tex);
4178 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004179}
4180
4181TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4182 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004183 mOutput.updateCompositionState(mRefreshArgs);
4184 mOutput.planComposition();
4185 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004186
4187 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004188
4189 base::unique_fd fd;
4190 std::shared_ptr<renderengine::ExternalTexture> tex;
4191 mOutput.updateProtectedContentState();
4192 mOutput.dequeueRenderBuffer(&fd, &tex);
4193 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004194}
4195
4196/*
4197 * Output::generateClientCompositionRequests()
4198 */
4199
4200struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004201 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004202 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004203 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4204 bool supportsProtectedContent, ui::Dataspace dataspace) {
4205 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004206 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004207 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004208 }
4209 };
4210
Lloyd Piquea4863342019-12-04 18:45:02 -08004211 struct Layer {
4212 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004213 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4214 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004215 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4216 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004217 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4218 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004219 }
4220
4221 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004222 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004223 LayerFECompositionState mLayerFEState;
4224 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004225 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004226 };
4227
Lloyd Pique56eba802019-08-28 15:45:25 -07004228 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004229 mOutput.mState.needsFiltering = false;
4230
Lloyd Pique56eba802019-08-28 15:45:25 -07004231 mOutput.setDisplayColorProfileForTest(
4232 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4233 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4234 }
4235
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004236 static constexpr float kLayerWhitePointNits = 200.f;
4237
Lloyd Pique56eba802019-08-28 15:45:25 -07004238 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4239 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004240 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004241};
4242
Lloyd Piquea4863342019-12-04 18:45:02 -08004243struct GenerateClientCompositionRequestsTest_ThreeLayers
4244 : public GenerateClientCompositionRequestsTest {
4245 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004246 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4247 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4248 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004249 mOutput.mState.transform =
4250 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004251 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004252 mOutput.mState.needsFiltering = false;
4253 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004254
Lloyd Piquea4863342019-12-04 18:45:02 -08004255 for (size_t i = 0; i < mLayers.size(); i++) {
4256 mLayers[i].mOutputLayerState.clearClientTarget = false;
4257 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4258 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004259 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004260 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004261 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4262 mLayers[i].mLayerSettings.alpha = 1.0f;
4263 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004264
Lloyd Piquea4863342019-12-04 18:45:02 -08004265 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4266 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4267 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4268 .WillRepeatedly(Return(true));
4269 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4270 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004271
Lloyd Piquea4863342019-12-04 18:45:02 -08004272 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4273 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004274
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004275 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004276 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004277 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004278
Lloyd Piquea4863342019-12-04 18:45:02 -08004279 static const Rect kDisplayFrame;
4280 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004281 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004282
Lloyd Piquea4863342019-12-04 18:45:02 -08004283 std::array<Layer, 3> mLayers;
4284};
Lloyd Pique56eba802019-08-28 15:45:25 -07004285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4287const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004288const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4289 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004290
Lloyd Piquea4863342019-12-04 18:45:02 -08004291TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4292 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4293 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4294 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004295
Robert Carrccab4242021-09-28 16:53:03 -07004296 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004297 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004298 EXPECT_EQ(0u, requests.size());
4299}
4300
Lloyd Piquea4863342019-12-04 18:45:02 -08004301TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4302 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4303 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4304 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4305
Robert Carrccab4242021-09-28 16:53:03 -07004306 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004307 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004308 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004309}
4310
4311TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004312 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4313 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4314 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4315 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4316 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4317 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004318
Robert Carrccab4242021-09-28 16:53:03 -07004319 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004320 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004321 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004322 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004323 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004324
Lloyd Piquea4863342019-12-04 18:45:02 -08004325 // Check that a timestamp was set for the layers that generated requests
4326 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4327 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4328 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4329}
4330
Alec Mourif54453c2021-05-13 16:28:28 -07004331MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4332 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4333 *result_listener << "expected " << expectedBlurSetting << "\n";
4334 *result_listener << "actual " << arg.blurSetting << "\n";
4335
4336 return expectedBlurSetting == arg.blurSetting;
4337}
4338
4339TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004340 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4341
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004342 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4343 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4344 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4345 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004346 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004347 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004348 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004349 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Robert Carrccab4242021-09-28 16:53:03 -07004350 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004351 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004352 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004353 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004354 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004355
Alec Mourif54453c2021-05-13 16:28:28 -07004356 // Check that a timestamp was set for the layers that generated requests
4357 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4358 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4359 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4360}
4361
Lloyd Piquea4863342019-12-04 18:45:02 -08004362TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4363 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4364 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4365 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4366 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4367
4368 mLayers[0].mOutputLayerState.clearClientTarget = false;
4369 mLayers[1].mOutputLayerState.clearClientTarget = false;
4370 mLayers[2].mOutputLayerState.clearClientTarget = false;
4371
4372 mLayers[0].mLayerFEState.isOpaque = true;
4373 mLayers[1].mLayerFEState.isOpaque = true;
4374 mLayers[2].mLayerFEState.isOpaque = true;
4375
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004376 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4377 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004378
Robert Carrccab4242021-09-28 16:53:03 -07004379 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004380 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004382 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004383}
4384
4385TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4386 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4387 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4388 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4389 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4390
4391 mLayers[0].mOutputLayerState.clearClientTarget = true;
4392 mLayers[1].mOutputLayerState.clearClientTarget = true;
4393 mLayers[2].mOutputLayerState.clearClientTarget = true;
4394
4395 mLayers[0].mLayerFEState.isOpaque = false;
4396 mLayers[1].mLayerFEState.isOpaque = false;
4397 mLayers[2].mLayerFEState.isOpaque = false;
4398
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004399 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4400 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004401
Robert Carrccab4242021-09-28 16:53:03 -07004402 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004403 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004404 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004405 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004406}
4407
4408TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004409 // If client composition is performed with some layers set to use device
4410 // composition, device layers after the first layer (device or client) will
4411 // clear the frame buffer if they are opaque and if that layer has a flag
4412 // set to do so. The first layer is skipped as the frame buffer is already
4413 // expected to be clear.
4414
Lloyd Piquea4863342019-12-04 18:45:02 -08004415 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4416 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4417 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004418
Lloyd Piquea4863342019-12-04 18:45:02 -08004419 mLayers[0].mOutputLayerState.clearClientTarget = true;
4420 mLayers[1].mOutputLayerState.clearClientTarget = true;
4421 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004422
Lloyd Piquea4863342019-12-04 18:45:02 -08004423 mLayers[0].mLayerFEState.isOpaque = true;
4424 mLayers[1].mLayerFEState.isOpaque = true;
4425 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004426
4427 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4428 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004429 false, /* needs filtering */
4430 false, /* secure */
4431 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004432 kDisplayViewport,
4433 kDisplayDataspace,
4434 false /* realContentIsVisible */,
4435 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004436 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004437 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004438 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004439 };
4440 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4441 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004442 false, /* needs filtering */
4443 false, /* secure */
4444 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004445 kDisplayViewport,
4446 kDisplayDataspace,
4447 true /* realContentIsVisible */,
4448 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004449 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004450 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004451 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004452 };
4453
4454 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4455 mBlackoutSettings.source.buffer.buffer = nullptr;
4456 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4457 mBlackoutSettings.alpha = 0.f;
4458 mBlackoutSettings.disableBlending = true;
4459
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004460 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4461 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4462 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4463 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004464
Robert Carrccab4242021-09-28 16:53:03 -07004465 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004466 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004467 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004468
Lloyd Piquea4863342019-12-04 18:45:02 -08004469 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004470 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004471
Vishnu Nair9b079a22020-01-21 14:36:08 -08004472 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004473}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004474
Lloyd Piquea4863342019-12-04 18:45:02 -08004475TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4476 clippedVisibleRegionUsedToGenerateRequest) {
4477 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4478 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4479 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004480
Lloyd Piquea4863342019-12-04 18:45:02 -08004481 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4482 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004483 false, /* needs filtering */
4484 false, /* secure */
4485 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004486 kDisplayViewport,
4487 kDisplayDataspace,
4488 true /* realContentIsVisible */,
4489 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004490 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004491 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004492 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004493 };
4494 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4495 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004496 false, /* needs filtering */
4497 false, /* secure */
4498 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004499 kDisplayViewport,
4500 kDisplayDataspace,
4501 true /* realContentIsVisible */,
4502 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004503 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004504 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004505 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004506 };
4507 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4508 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004509 false, /* needs filtering */
4510 false, /* secure */
4511 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004512 kDisplayViewport,
4513 kDisplayDataspace,
4514 true /* realContentIsVisible */,
4515 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004516 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004517 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004518 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004519 };
4520
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004521 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4522 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4523 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4524 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4525 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4526 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004527
4528 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004529 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004530 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004531}
4532
4533TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4534 perLayerNeedsFilteringUsedToGenerateRequests) {
4535 mOutput.mState.needsFiltering = false;
4536 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4537
Lloyd Piquea4863342019-12-04 18:45:02 -08004538 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4539 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004540 true, /* needs filtering */
4541 false, /* secure */
4542 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004543 kDisplayViewport,
4544 kDisplayDataspace,
4545 true /* realContentIsVisible */,
4546 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004547 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004548 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004549 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004550 };
4551 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4552 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004553 false, /* needs filtering */
4554 false, /* secure */
4555 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004556 kDisplayViewport,
4557 kDisplayDataspace,
4558 true /* realContentIsVisible */,
4559 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004560 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004561 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004562 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 };
4564 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4565 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004566 false, /* needs filtering */
4567 false, /* secure */
4568 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004569 kDisplayViewport,
4570 kDisplayDataspace,
4571 true /* realContentIsVisible */,
4572 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004573 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004574 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004575 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004576 };
4577
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004578 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4579 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4580 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4581 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4582 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4583 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004584
4585 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004586 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4587 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004588}
4589
4590TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4591 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4592 mOutput.mState.needsFiltering = true;
4593 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4594
Lloyd Piquea4863342019-12-04 18:45:02 -08004595 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4596 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004597 true, /* needs filtering */
4598 false, /* secure */
4599 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004600 kDisplayViewport,
4601 kDisplayDataspace,
4602 true /* realContentIsVisible */,
4603 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004604 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004605 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004606 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004607 };
4608 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4609 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004610 true, /* needs filtering */
4611 false, /* secure */
4612 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004613 kDisplayViewport,
4614 kDisplayDataspace,
4615 true /* realContentIsVisible */,
4616 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004617 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004618 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004619 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004620 };
4621 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4622 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004623 true, /* needs filtering */
4624 false, /* secure */
4625 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004626 kDisplayViewport,
4627 kDisplayDataspace,
4628 true /* realContentIsVisible */,
4629 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004630 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004631 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004632 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004633 };
4634
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004635 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4636 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4637 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4638 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4639 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4640 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004641
4642 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004643 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4644 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004645}
4646
4647TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4648 wholeOutputSecurityUsedToGenerateRequests) {
4649 mOutput.mState.isSecure = true;
4650
Lloyd Piquea4863342019-12-04 18:45:02 -08004651 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4652 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004653 false, /* needs filtering */
4654 true, /* secure */
4655 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004656 kDisplayViewport,
4657 kDisplayDataspace,
4658 true /* realContentIsVisible */,
4659 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004660 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004661 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004662 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004663 };
4664 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4665 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004666 false, /* needs filtering */
4667 true, /* secure */
4668 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004669 kDisplayViewport,
4670 kDisplayDataspace,
4671 true /* realContentIsVisible */,
4672 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004673 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004674 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004675 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004676 };
4677 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4678 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004679 false, /* needs filtering */
4680 true, /* secure */
4681 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004682 kDisplayViewport,
4683 kDisplayDataspace,
4684 true /* realContentIsVisible */,
4685 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004686 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004687 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004688 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004689 };
4690
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004691 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4692 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4693 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4694 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4695 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4696 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004697
4698 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004699 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4700 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004701}
4702
4703TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4704 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004705 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4706 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004707 false, /* needs filtering */
4708 false, /* secure */
4709 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004710 kDisplayViewport,
4711 kDisplayDataspace,
4712 true /* realContentIsVisible */,
4713 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004714 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004715 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004716 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004717 };
4718 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4719 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004720 false, /* needs filtering */
4721 false, /* secure */
4722 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004723 kDisplayViewport,
4724 kDisplayDataspace,
4725 true /* realContentIsVisible */,
4726 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004727 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004728 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004729 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004730 };
4731 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4732 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004733 false, /* needs filtering */
4734 false, /* secure */
4735 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004736 kDisplayViewport,
4737 kDisplayDataspace,
4738 true /* realContentIsVisible */,
4739 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004740 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004741 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004742 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004743 };
4744
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004745 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4746 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4747 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4748 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4749 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4750 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004751
Robert Carrccab4242021-09-28 16:53:03 -07004752 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004753 kDisplayDataspace));
4754}
4755
Lucas Dupin084a6d42021-08-26 22:10:29 +00004756TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4757 InjectedLayer layer1;
4758 InjectedLayer layer2;
4759
4760 uint32_t z = 0;
4761 // Layer requesting blur, or below, should request client composition, unless opaque.
4762 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4763 EXPECT_CALL(*layer1.outputLayer,
4764 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4765 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004766 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4767 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004768 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4769 EXPECT_CALL(*layer2.outputLayer,
4770 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4771 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004772 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4773 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004774
4775 layer2.layerFEState.backgroundBlurRadius = 10;
4776 layer2.layerFEState.isOpaque = true;
4777
4778 injectOutputLayer(layer1);
4779 injectOutputLayer(layer2);
4780
4781 mOutput->editState().isEnabled = true;
4782
4783 CompositionRefreshArgs args;
4784 args.updatingGeometryThisFrame = false;
4785 args.devOptForceClientComposition = false;
4786 mOutput->updateCompositionState(args);
4787 mOutput->planComposition();
4788 mOutput->writeCompositionState(args);
4789}
4790
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004791TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004792 InjectedLayer layer1;
4793 InjectedLayer layer2;
4794 InjectedLayer layer3;
4795
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004796 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004797 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004798 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004799 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004802 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4803 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004804 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004805 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004806 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4807 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004808 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4809 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004810 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004811 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004812 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4813 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004814 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4815 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004816
Lloyd Piquede196652020-01-22 17:29:58 -08004817 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004818 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004819
Lloyd Piquede196652020-01-22 17:29:58 -08004820 injectOutputLayer(layer1);
4821 injectOutputLayer(layer2);
4822 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004823
4824 mOutput->editState().isEnabled = true;
4825
4826 CompositionRefreshArgs args;
4827 args.updatingGeometryThisFrame = false;
4828 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004829 mOutput->updateCompositionState(args);
4830 mOutput->planComposition();
4831 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004832}
4833
Lucas Dupinc3800b82020-10-02 16:24:48 -07004834TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4835 InjectedLayer layer1;
4836 InjectedLayer layer2;
4837 InjectedLayer layer3;
4838
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004839 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004840 // Layer requesting blur, or below, should request client composition.
4841 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004842 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004843 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4844 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004845 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4846 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004847 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004848 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004849 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4850 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004851 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4852 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004853 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004854 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004855 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4856 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004857 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4858 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004859
4860 BlurRegion region;
4861 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004862 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004863
4864 injectOutputLayer(layer1);
4865 injectOutputLayer(layer2);
4866 injectOutputLayer(layer3);
4867
4868 mOutput->editState().isEnabled = true;
4869
4870 CompositionRefreshArgs args;
4871 args.updatingGeometryThisFrame = false;
4872 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004873 mOutput->updateCompositionState(args);
4874 mOutput->planComposition();
4875 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004876}
4877
Lloyd Piquea4863342019-12-04 18:45:02 -08004878TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4879 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4880 // one layer on the left covering the left side of the output, and one layer
4881 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004882
4883 const Rect kPortraitFrame(0, 0, 1000, 2000);
4884 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004885 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004886 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004887 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004888
Angel Aguayob084e0c2021-08-04 23:27:28 +00004889 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4890 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4891 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004892 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004893 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004894 mOutput.mState.needsFiltering = false;
4895 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004896
Lloyd Piquea4863342019-12-04 18:45:02 -08004897 Layer leftLayer;
4898 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004899
Lloyd Piquea4863342019-12-04 18:45:02 -08004900 leftLayer.mOutputLayerState.clearClientTarget = false;
4901 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4902 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004903 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004904
Lloyd Piquea4863342019-12-04 18:45:02 -08004905 rightLayer.mOutputLayerState.clearClientTarget = false;
4906 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4907 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004908 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004909
4910 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4911 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4912 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4913 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4914 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4915
Lloyd Piquea4863342019-12-04 18:45:02 -08004916 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4917 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004918 false, /* needs filtering */
4919 true, /* secure */
4920 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004921 kPortraitViewport,
4922 kOutputDataspace,
4923 true /* realContentIsVisible */,
4924 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004925 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004926 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004927 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004928 };
4929
4930 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4931 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004932 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4933 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004934
4935 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4936 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004937 false, /* needs filtering */
4938 true, /* secure */
4939 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004940 kPortraitViewport,
4941 kOutputDataspace,
4942 true /* realContentIsVisible */,
4943 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004944 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004945 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004946 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004947 };
4948
4949 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4950 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004951 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4952 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004953
4954 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004955 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004956 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004957 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004958 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4959 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004960}
4961
Vishnu Naira483b4a2019-12-12 15:07:52 -08004962TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4963 shadowRegionOnlyVisibleSkipsContentComposition) {
4964 const Rect kContentWithShadow(40, 40, 70, 90);
4965 const Rect kContent(50, 50, 60, 80);
4966 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4967 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4968
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004969 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4970 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004971 false, /* needs filtering */
4972 false, /* secure */
4973 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004974 kDisplayViewport,
4975 kDisplayDataspace,
4976 false /* realContentIsVisible */,
4977 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004978 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004979 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004980 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004981 };
4982
Vishnu Nair9b079a22020-01-21 14:36:08 -08004983 LayerFE::LayerSettings mShadowSettings;
4984 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004985
4986 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4987 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4988
4989 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4990 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004991 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4992 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004993
Robert Carrccab4242021-09-28 16:53:03 -07004994 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004995 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004996 ASSERT_EQ(1u, requests.size());
4997
Vishnu Nair9b079a22020-01-21 14:36:08 -08004998 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004999}
5000
5001TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5002 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5003 const Rect kContentWithShadow(40, 40, 70, 90);
5004 const Rect kContent(50, 50, 60, 80);
5005 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5006 const Region kPartialContentWithPartialShadowRegion =
5007 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5008
Vishnu Naira483b4a2019-12-12 15:07:52 -08005009 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5010 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5011
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005012 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5013 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005014 false, /* needs filtering */
5015 false, /* secure */
5016 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005017 kDisplayViewport,
5018 kDisplayDataspace,
5019 true /* realContentIsVisible */,
5020 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005021 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005022 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005023 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005024 };
5025
Vishnu Naira483b4a2019-12-12 15:07:52 -08005026 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5027 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005028 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5029 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005030
Robert Carrccab4242021-09-28 16:53:03 -07005031 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005032 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005033 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005034
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005035 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005036}
5037
Lloyd Pique32cbe282018-10-19 13:09:22 -07005038} // namespace
5039} // namespace android::compositionengine