blob: c4ae3a7f22f5368710696b95fa48d6e935ec93dc [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
17#include <cmath>
18
Lloyd Pique17ca7422019-11-14 14:24:10 -080019#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070020#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080022#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070023#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070024#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070025#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080026#include <compositionengine/mock/LayerFE.h>
27#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070028#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070030#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070031#include <ui/Rect.h>
32#include <ui/Region.h>
33
Lloyd Pique17ca7422019-11-14 14:24:10 -080034#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080035#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070036#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037
38namespace android::compositionengine {
39namespace {
40
Lloyd Pique56eba802019-08-28 15:45:25 -070041using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080042using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080043using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080044using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080045using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080046using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080047using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080048using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080049using testing::Invoke;
50using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080051using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080052using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070055using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070056using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::StrictMock;
59
Lloyd Pique56eba802019-08-28 15:45:25 -070060constexpr auto TR_IDENT = 0u;
61constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080062constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070063
Lloyd Pique3eb1b212019-03-07 21:15:40 -080064const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080065const mat4 kNonIdentityHalf = mat4() * 0.5f;
66const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080067
Lloyd Pique17ca7422019-11-14 14:24:10 -080068constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
69 static_cast<OutputColorSetting>(0x100);
70
Lloyd Piquefaa3f192019-11-14 14:05:09 -080071struct OutputPartialMockBase : public impl::Output {
72 // compositionengine::Output overrides
73 const OutputCompositionState& getState() const override { return mState; }
74 OutputCompositionState& editState() override { return mState; }
75
76 // Use mocks for all the remaining virtual functions
77 // not implemented by the base implementation class.
78 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
79 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080080 MOCK_METHOD2(ensureOutputLayer,
81 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080082 MOCK_METHOD0(finalizePendingOutputLayers, void());
83 MOCK_METHOD0(clearOutputLayers, void());
84 MOCK_CONST_METHOD1(dumpState, void(std::string&));
85 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080086 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080087 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
88
89 impl::OutputCompositionState mState;
90};
91
Lloyd Piquede196652020-01-22 17:29:58 -080092struct InjectedLayer {
93 InjectedLayer() {
94 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
95 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
96 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
97
98 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
99 }
100
101 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
102 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
103 LayerFECompositionState layerFEState;
104 impl::OutputLayerCompositionState outputLayerState;
105};
106
107struct NonInjectedLayer {
108 NonInjectedLayer() {
109 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
110 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
111 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
112
113 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
114 }
115
116 mock::OutputLayer outputLayer;
117 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
118 LayerFECompositionState layerFEState;
119 impl::OutputLayerCompositionState outputLayerState;
120};
121
Lloyd Pique66d68602019-02-13 14:23:31 -0800122struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700123 class Output : public impl::Output {
124 public:
125 using impl::Output::injectOutputLayerForTest;
126 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
127 };
128
129 static std::shared_ptr<Output> createOutput(
130 const compositionengine::CompositionEngine& compositionEngine) {
131 return impl::createOutputTemplated<Output>(compositionEngine);
132 }
133
Lloyd Pique31cb2942018-10-19 17:23:03 -0700134 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700135 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700136 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700137 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800138
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200139 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700141
Lloyd Piquede196652020-01-22 17:29:58 -0800142 void injectOutputLayer(InjectedLayer& layer) {
143 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
144 }
145
146 void injectNullOutputLayer() {
147 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
148 }
149
Lloyd Piqueef958122019-02-05 18:00:12 -0800150 static const Rect kDefaultDisplaySize;
151
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700153 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700155 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156};
157
Lloyd Piqueef958122019-02-05 18:00:12 -0800158const Rect OutputTest::kDefaultDisplaySize{100, 200};
159
Lloyd Pique17ca7422019-11-14 14:24:10 -0800160using ColorProfile = compositionengine::Output::ColorProfile;
161
162void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
163 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
164 toString(profile.mode).c_str(), profile.mode,
165 toString(profile.dataspace).c_str(), profile.dataspace,
166 toString(profile.renderIntent).c_str(), profile.renderIntent,
167 toString(profile.colorSpaceAgnosticDataspace).c_str(),
168 profile.colorSpaceAgnosticDataspace);
169}
170
171// Checks for a ColorProfile match
172MATCHER_P(ColorProfileEq, expected, "") {
173 std::string buf;
174 buf.append("ColorProfiles are not equal\n");
175 dumpColorProfile(expected, buf, "expected value");
176 dumpColorProfile(arg, buf, "actual value");
177 *result_listener << buf;
178
179 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
180 (expected.renderIntent == arg.renderIntent) &&
181 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
182}
183
Lloyd Pique66d68602019-02-13 14:23:31 -0800184/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700185 * Basic construction
186 */
187
Lloyd Pique31cb2942018-10-19 17:23:03 -0700188TEST_F(OutputTest, canInstantiateOutput) {
189 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700190 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700191 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
192
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700193 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700194
195 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700196 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700198 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
199
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700200 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700202
Lloyd Pique66d68602019-02-13 14:23:31 -0800203/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700204 * Output::setCompositionEnabled()
205 */
206
207TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_TRUE(mOutput->getState().isEnabled);
213 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214}
215
216TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700219 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 EXPECT_TRUE(mOutput->getState().isEnabled);
222 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223}
224
225TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_FALSE(mOutput->getState().isEnabled);
231 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232}
233
Lloyd Pique66d68602019-02-13 14:23:31 -0800234/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235 * Output::setProjection()
236 */
237
Marin Shalamanov209ae612020-10-01 00:17:39 +0200238TEST_F(OutputTest, setProjectionWorks) {
239 const Rect displayRect{0, 0, 1000, 2000};
240 mOutput->editState().displaySpace.bounds = displayRect;
241 mOutput->editState().framebufferSpace.bounds = displayRect;
242
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200243 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200244 const Rect frame{50, 60, 100, 100};
245 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200247 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200249 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200250 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
251 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200252
253 const auto state = mOutput->getState();
254 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
255 EXPECT_EQ(viewport, state.layerStackSpace.content);
256 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
257
258 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
259 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
260 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
261
262 EXPECT_EQ(displayRect, state.displaySpace.bounds);
263 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
264 EXPECT_EQ(orientation, state.displaySpace.orientation);
265
266 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
267 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
268 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
269
270 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700271
272 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200273}
274
275TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
276 const Rect displayRect{0, 0, 1000, 2000};
277 const Rect framebufferRect{0, 0, 500, 1000};
278 mOutput->editState().displaySpace.bounds = displayRect;
279 mOutput->editState().framebufferSpace.bounds = framebufferRect;
280
281 const ui::Rotation orientation = ui::ROTATION_90;
282 const Rect frame{50, 60, 100, 100};
283 const Rect viewport{10, 20, 30, 40};
284
285 mOutput->setProjection(orientation, viewport, frame);
286
287 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
288 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
289 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
290
291 const auto state = mOutput->getState();
292 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
293 EXPECT_EQ(viewport, state.layerStackSpace.content);
294 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
295
296 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
297 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
298 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
299
300 EXPECT_EQ(displayRect, state.displaySpace.bounds);
301 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
302 EXPECT_EQ(orientation, state.displaySpace.orientation);
303
304 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
305 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
306 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
307
308 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700309}
310
Lloyd Pique66d68602019-02-13 14:23:31 -0800311/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200312 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700313 */
314
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200315TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
316 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
317 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
318 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
319 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
320 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
321 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
322 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
323 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
324 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
325 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700326
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200327 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700328
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200329 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700330
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200331 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700332
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200333 const auto state = mOutput->getState();
334
335 const Rect displayRect(newDisplaySize);
336 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
337 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
338 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200339
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200340 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200341 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200342
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200343 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200344 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200346 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200347 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
348
349 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
350
351 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700352}
353
Lloyd Pique66d68602019-02-13 14:23:31 -0800354/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700355 * Output::setLayerStackFilter()
356 */
357
358TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700359 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700360 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700361
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700362 EXPECT_TRUE(mOutput->getState().layerStackInternal);
363 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700364
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700365 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700366}
367
Lloyd Pique66d68602019-02-13 14:23:31 -0800368/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700369 * Output::setColorTransform
370 */
371
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800372TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700373 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700374
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800375 // If no colorTransformMatrix is set the update should be skipped.
376 CompositionRefreshArgs refreshArgs;
377 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700378
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700379 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700380
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800381 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700382 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800383
384 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700385 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800386}
Lloyd Piqueef958122019-02-05 18:00:12 -0800387
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800388TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700389 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700390
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800391 // Attempting to set the same colorTransformMatrix that is already set should
392 // also skip the update.
393 CompositionRefreshArgs refreshArgs;
394 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700395
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700396 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700397
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800398 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700399 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800400
401 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700402 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800403}
404
405TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700406 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800407
408 // Setting a different colorTransformMatrix should perform the update.
409 CompositionRefreshArgs refreshArgs;
410 refreshArgs.colorTransformMatrix = kIdentity;
411
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700412 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800413
414 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700415 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800416
417 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700418 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800419}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700420
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800421TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700422 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700423
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800424 // Setting a different colorTransformMatrix should perform the update.
425 CompositionRefreshArgs refreshArgs;
426 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700427
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700428 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800429
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800430 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700431 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800432
433 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435}
436
437TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439
440 // Setting a different colorTransformMatrix should perform the update.
441 CompositionRefreshArgs refreshArgs;
442 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
443
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800445
446 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800448
449 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451}
452
Lloyd Pique66d68602019-02-13 14:23:31 -0800453/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800454 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455 */
456
Lloyd Pique17ca7422019-11-14 14:24:10 -0800457using OutputSetColorProfileTest = OutputTest;
458
459TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800460 using ColorProfile = Output::ColorProfile;
461
Lloyd Piquef5275482019-01-29 18:42:42 -0800462 EXPECT_CALL(*mDisplayColorProfile,
463 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
464 ui::Dataspace::UNKNOWN))
465 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800466 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700467
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700468 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
469 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
470 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700471
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700472 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
473 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
474 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
475 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800478}
479
Lloyd Pique17ca7422019-11-14 14:24:10 -0800480TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800481 using ColorProfile = Output::ColorProfile;
482
Lloyd Piquef5275482019-01-29 18:42:42 -0800483 EXPECT_CALL(*mDisplayColorProfile,
484 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
485 ui::Dataspace::UNKNOWN))
486 .WillOnce(Return(ui::Dataspace::UNKNOWN));
487
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700488 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
489 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
490 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
491 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
494 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
495 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800496
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700498}
499
Lloyd Pique66d68602019-02-13 14:23:31 -0800500/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700501 * Output::setRenderSurface()
502 */
503
504TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
505 const ui::Size newDisplaySize{640, 480};
506
507 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
508 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
509
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700510 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700511
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200512 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700513}
514
Lloyd Pique66d68602019-02-13 14:23:31 -0800515/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000516 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700517 */
518
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000519TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
520 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200521 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700522 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700523
524 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700526
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000527 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700528 }
529}
530
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000531TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
532 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200533 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700534 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700535
536 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700538
539 // The dirtyRegion should be clipped to the display bounds.
540 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
541 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700542}
543
Lloyd Pique66d68602019-02-13 14:23:31 -0800544/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800545 * Output::belongsInOutput()
546 */
547
548TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
549 const uint32_t layerStack1 = 123u;
550 const uint32_t layerStack2 = 456u;
551
552 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800554
Lloyd Piquec6687342019-03-07 21:34:57 -0800555 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700556 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
557 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800558
Lloyd Piqueef36b002019-01-23 17:52:04 -0800559 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700560 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
561 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
562 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
563 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800564
565 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700566 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800567
568 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700569 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
570 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
571 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
572 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800573}
574
Lloyd Piquede196652020-01-22 17:29:58 -0800575TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
576 NonInjectedLayer layer;
577 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800578
Lloyd Piquede196652020-01-22 17:29:58 -0800579 // If the layer has no composition state, it does not belong to any output.
580 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
581 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
582}
583
584TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
585 NonInjectedLayer layer;
586 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800587
588 const uint32_t layerStack1 = 123u;
589 const uint32_t layerStack2 = 456u;
590
591 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700592 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800593
Lloyd Pique66c20c42019-03-07 21:44:02 -0800594 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800595 layer.layerFEState.layerStackId = std::nullopt;
596 layer.layerFEState.internalOnly = false;
597 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800598
Lloyd Piquede196652020-01-22 17:29:58 -0800599 layer.layerFEState.layerStackId = std::nullopt;
600 layer.layerFEState.internalOnly = true;
601 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800602
603 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800604 layer.layerFEState.layerStackId = layerStack1;
605 layer.layerFEState.internalOnly = false;
606 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800607
Lloyd Piquede196652020-01-22 17:29:58 -0800608 layer.layerFEState.layerStackId = layerStack1;
609 layer.layerFEState.internalOnly = true;
610 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800611
Lloyd Piquede196652020-01-22 17:29:58 -0800612 layer.layerFEState.layerStackId = layerStack2;
613 layer.layerFEState.internalOnly = true;
614 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800615
Lloyd Piquede196652020-01-22 17:29:58 -0800616 layer.layerFEState.layerStackId = layerStack2;
617 layer.layerFEState.internalOnly = false;
618 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800619
620 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700621 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800622
Lloyd Pique66c20c42019-03-07 21:44:02 -0800623 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800624 layer.layerFEState.layerStackId = layerStack1;
625 layer.layerFEState.internalOnly = false;
626 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800627
Lloyd Piquede196652020-01-22 17:29:58 -0800628 layer.layerFEState.layerStackId = layerStack1;
629 layer.layerFEState.internalOnly = true;
630 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800631
Lloyd Piquede196652020-01-22 17:29:58 -0800632 layer.layerFEState.layerStackId = layerStack2;
633 layer.layerFEState.internalOnly = true;
634 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Lloyd Piquede196652020-01-22 17:29:58 -0800636 layer.layerFEState.layerStackId = layerStack2;
637 layer.layerFEState.internalOnly = false;
638 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800639}
640
Lloyd Pique66d68602019-02-13 14:23:31 -0800641/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800642 * Output::getOutputLayerForLayer()
643 */
644
645TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800646 InjectedLayer layer1;
647 InjectedLayer layer2;
648 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800649
Lloyd Piquede196652020-01-22 17:29:58 -0800650 injectOutputLayer(layer1);
651 injectNullOutputLayer();
652 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800653
654 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800655 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
656 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800657
658 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800659 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
660 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
661 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800662
663 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800664 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
665 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
666 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800667}
668
Lloyd Pique66d68602019-02-13 14:23:31 -0800669/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800670 * Output::setReleasedLayers()
671 */
672
673using OutputSetReleasedLayersTest = OutputTest;
674
675TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
676 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
677 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
678 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
679
680 Output::ReleasedLayers layers;
681 layers.push_back(layer1FE);
682 layers.push_back(layer2FE);
683 layers.push_back(layer3FE);
684
685 mOutput->setReleasedLayers(std::move(layers));
686
687 const auto& setLayers = mOutput->getReleasedLayersForTest();
688 ASSERT_EQ(3u, setLayers.size());
689 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
690 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
691 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
692}
693
694/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800695 * Output::updateLayerStateFromFE()
696 */
697
Lloyd Piquede196652020-01-22 17:29:58 -0800698using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800699
700TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
701 CompositionRefreshArgs refreshArgs;
702
703 mOutput->updateLayerStateFromFE(refreshArgs);
704}
705
Lloyd Piquede196652020-01-22 17:29:58 -0800706TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
707 InjectedLayer layer1;
708 InjectedLayer layer2;
709 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800710
Lloyd Piquede196652020-01-22 17:29:58 -0800711 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
712 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
713 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
714
715 injectOutputLayer(layer1);
716 injectOutputLayer(layer2);
717 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800718
719 CompositionRefreshArgs refreshArgs;
720 refreshArgs.updatingGeometryThisFrame = false;
721
722 mOutput->updateLayerStateFromFE(refreshArgs);
723}
724
Lloyd Piquede196652020-01-22 17:29:58 -0800725TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
726 InjectedLayer layer1;
727 InjectedLayer layer2;
728 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800729
Lloyd Piquede196652020-01-22 17:29:58 -0800730 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
731 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
732 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
733
734 injectOutputLayer(layer1);
735 injectOutputLayer(layer2);
736 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800737
738 CompositionRefreshArgs refreshArgs;
739 refreshArgs.updatingGeometryThisFrame = true;
740
741 mOutput->updateLayerStateFromFE(refreshArgs);
742}
743
744/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800745 * Output::updateAndWriteCompositionState()
746 */
747
Lloyd Piquede196652020-01-22 17:29:58 -0800748using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800749
750TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
751 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800752
753 CompositionRefreshArgs args;
754 mOutput->updateAndWriteCompositionState(args);
755}
756
Lloyd Piqueef63b612019-11-14 13:19:56 -0800757TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800758 InjectedLayer layer1;
759 InjectedLayer layer2;
760 InjectedLayer layer3;
761
Lloyd Piqueef63b612019-11-14 13:19:56 -0800762 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800763
Lloyd Piquede196652020-01-22 17:29:58 -0800764 injectOutputLayer(layer1);
765 injectOutputLayer(layer2);
766 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800767
768 CompositionRefreshArgs args;
769 mOutput->updateAndWriteCompositionState(args);
770}
771
772TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800773 InjectedLayer layer1;
774 InjectedLayer layer2;
775 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800776
Snild Dolkow9e217d62020-04-22 15:53:42 +0200777 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800778 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200779 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800780 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200781 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800782 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
783
784 injectOutputLayer(layer1);
785 injectOutputLayer(layer2);
786 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800787
788 mOutput->editState().isEnabled = true;
789
790 CompositionRefreshArgs args;
791 args.updatingGeometryThisFrame = false;
792 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200793 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800794 mOutput->updateAndWriteCompositionState(args);
795}
796
797TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800798 InjectedLayer layer1;
799 InjectedLayer layer2;
800 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800801
Snild Dolkow9e217d62020-04-22 15:53:42 +0200802 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800803 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200804 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800805 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200806 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800807 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
808
809 injectOutputLayer(layer1);
810 injectOutputLayer(layer2);
811 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800812
813 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800814
815 CompositionRefreshArgs args;
816 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817 args.devOptForceClientComposition = false;
818 mOutput->updateAndWriteCompositionState(args);
819}
820
821TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800822 InjectedLayer layer1;
823 InjectedLayer layer2;
824 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800825
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800827 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200828 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800829 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200830 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800831 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
832
833 injectOutputLayer(layer1);
834 injectOutputLayer(layer2);
835 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
837 mOutput->editState().isEnabled = true;
838
839 CompositionRefreshArgs args;
840 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800841 args.devOptForceClientComposition = true;
842 mOutput->updateAndWriteCompositionState(args);
843}
844
845/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800846 * Output::prepareFrame()
847 */
848
849struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800850 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800851 // Sets up the helper functions called by the function under test to use
852 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800853 MOCK_METHOD0(chooseCompositionStrategy, void());
854 };
855
856 OutputPrepareFrameTest() {
857 mOutput.setDisplayColorProfileForTest(
858 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
859 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
860 }
861
862 StrictMock<mock::CompositionEngine> mCompositionEngine;
863 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
864 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700865 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800866};
867
868TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
869 mOutput.editState().isEnabled = false;
870
871 mOutput.prepareFrame();
872}
873
874TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
875 mOutput.editState().isEnabled = true;
876 mOutput.editState().usesClientComposition = false;
877 mOutput.editState().usesDeviceComposition = true;
878
879 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
880 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
881
882 mOutput.prepareFrame();
883}
884
885// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
886// base chooseCompositionStrategy() is invoked.
887TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700888 mOutput->editState().isEnabled = true;
889 mOutput->editState().usesClientComposition = false;
890 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800891
892 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
893
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700894 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800895
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700896 EXPECT_TRUE(mOutput->getState().usesClientComposition);
897 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800898}
899
Lloyd Pique56eba802019-08-28 15:45:25 -0700900/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800901 * Output::prepare()
902 */
903
904struct OutputPrepareTest : public testing::Test {
905 struct OutputPartialMock : public OutputPartialMockBase {
906 // Sets up the helper functions called by the function under test to use
907 // mock implementations.
908 MOCK_METHOD2(rebuildLayerStacks,
909 void(const compositionengine::CompositionRefreshArgs&,
910 compositionengine::LayerFESet&));
911 };
912
913 StrictMock<OutputPartialMock> mOutput;
914 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800915 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800916};
917
918TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
919 InSequence seq;
920 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
921
922 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
923}
924
925/*
926 * Output::rebuildLayerStacks()
927 */
928
929struct OutputRebuildLayerStacksTest : public testing::Test {
930 struct OutputPartialMock : public OutputPartialMockBase {
931 // Sets up the helper functions called by the function under test to use
932 // mock implementations.
933 MOCK_METHOD2(collectVisibleLayers,
934 void(const compositionengine::CompositionRefreshArgs&,
935 compositionengine::Output::CoverageState&));
936 };
937
938 OutputRebuildLayerStacksTest() {
939 mOutput.mState.isEnabled = true;
940 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200941 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800942
943 mRefreshArgs.updatingOutputGeometryThisFrame = true;
944
945 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
946
947 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
948 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
949 }
950
951 void setTestCoverageValues(const CompositionRefreshArgs&,
952 compositionengine::Output::CoverageState& state) {
953 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
954 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
955 state.dirtyRegion = mCoverageDirtyRegionToSet;
956 }
957
958 static const ui::Transform kIdentityTransform;
959 static const ui::Transform kRotate90Transform;
960 static const Rect kOutputBounds;
961
962 StrictMock<OutputPartialMock> mOutput;
963 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800964 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800965 Region mCoverageAboveCoveredLayersToSet;
966 Region mCoverageAboveOpaqueLayersToSet;
967 Region mCoverageDirtyRegionToSet;
968};
969
970const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
971const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
972const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
973
974TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
975 mOutput.mState.isEnabled = false;
976
977 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
978}
979
980TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
981 mRefreshArgs.updatingOutputGeometryThisFrame = false;
982
983 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
984}
985
986TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
987 mOutput.mState.transform = kIdentityTransform;
988
989 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
990
991 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
992
993 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
994}
995
996TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
997 mOutput.mState.transform = kIdentityTransform;
998
999 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1000
1001 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1002
1003 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1004}
1005
1006TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1007 mOutput.mState.transform = kRotate90Transform;
1008
1009 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1010
1011 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1012
1013 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1014}
1015
1016TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1017 mOutput.mState.transform = kRotate90Transform;
1018
1019 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1020
1021 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1022
1023 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1024}
1025
1026TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1027 mOutput.mState.transform = kIdentityTransform;
1028 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1029
1030 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1031
1032 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1033
1034 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1035}
1036
1037TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1038 mOutput.mState.transform = kRotate90Transform;
1039 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1040
1041 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1042
1043 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1044
1045 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1046}
1047
1048/*
1049 * Output::collectVisibleLayers()
1050 */
1051
Lloyd Pique1ef93222019-11-21 16:41:53 -08001052struct OutputCollectVisibleLayersTest : public testing::Test {
1053 struct OutputPartialMock : public OutputPartialMockBase {
1054 // Sets up the helper functions called by the function under test to use
1055 // mock implementations.
1056 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001057 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001058 compositionengine::Output::CoverageState&));
1059 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1060 MOCK_METHOD0(finalizePendingOutputLayers, void());
1061 };
1062
1063 struct Layer {
1064 Layer() {
1065 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1066 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1067 }
1068
1069 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001070 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001071 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001072 };
1073
1074 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001075 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001076 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1077 .WillRepeatedly(Return(&mLayer1.outputLayer));
1078 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1079 .WillRepeatedly(Return(&mLayer2.outputLayer));
1080 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1081 .WillRepeatedly(Return(&mLayer3.outputLayer));
1082
Lloyd Piquede196652020-01-22 17:29:58 -08001083 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1084 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1085 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001086 }
1087
1088 StrictMock<OutputPartialMock> mOutput;
1089 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001090 LayerFESet mGeomSnapshots;
1091 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001092 Layer mLayer1;
1093 Layer mLayer2;
1094 Layer mLayer3;
1095};
1096
1097TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1098 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001099 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001100
1101 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1102 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1103
1104 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1105}
1106
1107TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1108 // Enforce a call order sequence for this test.
1109 InSequence seq;
1110
1111 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001112 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1113 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1114 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001115
1116 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1117 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1118
1119 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1120
1121 // Ensure all output layers have been assigned a simple/flattened z-order.
1122 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1123 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1124 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1125}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001126
1127/*
1128 * Output::ensureOutputLayerIfVisible()
1129 */
1130
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001131struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1132 struct OutputPartialMock : public OutputPartialMockBase {
1133 // Sets up the helper functions called by the function under test to use
1134 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001135 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001136 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001137 MOCK_METHOD2(ensureOutputLayer,
1138 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001139 };
1140
1141 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001142 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1143 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001144 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001145 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001146 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001147
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001148 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1149 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001150 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1151
Lloyd Piquede196652020-01-22 17:29:58 -08001152 mLayer.layerFEState.isVisible = true;
1153 mLayer.layerFEState.isOpaque = true;
1154 mLayer.layerFEState.contentDirty = true;
1155 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1156 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1157 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001158
Lloyd Piquede196652020-01-22 17:29:58 -08001159 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1160 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001161
Lloyd Piquede196652020-01-22 17:29:58 -08001162 mGeomSnapshots.insert(mLayer.layerFE);
1163 }
1164
1165 void ensureOutputLayerIfVisible() {
1166 sp<LayerFE> layerFE(mLayer.layerFE);
1167 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001168 }
1169
1170 static const Region kEmptyRegion;
1171 static const Region kFullBoundsNoRotation;
1172 static const Region kRightHalfBoundsNoRotation;
1173 static const Region kLowerHalfBoundsNoRotation;
1174 static const Region kFullBounds90Rotation;
1175
1176 StrictMock<OutputPartialMock> mOutput;
1177 LayerFESet mGeomSnapshots;
1178 Output::CoverageState mCoverageState{mGeomSnapshots};
1179
Lloyd Piquede196652020-01-22 17:29:58 -08001180 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001181};
1182
1183const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1184const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1185 Region(Rect(0, 0, 100, 200));
1186const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1187 Region(Rect(0, 100, 100, 200));
1188const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1189 Region(Rect(50, 0, 100, 200));
1190const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1191 Region(Rect(0, 0, 200, 100));
1192
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001193TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001194 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1195 EXPECT_CALL(*mLayer.layerFE,
1196 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001197
1198 mGeomSnapshots.clear();
1199
Lloyd Piquede196652020-01-22 17:29:58 -08001200 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001201}
1202
1203TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1204 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001205 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001206
Lloyd Piquede196652020-01-22 17:29:58 -08001207 ensureOutputLayerIfVisible();
1208}
1209
1210TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1211 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1212
1213 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001214}
1215
1216TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001217 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001218
Lloyd Piquede196652020-01-22 17:29:58 -08001219 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220}
1221
1222TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001223 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001224
Lloyd Piquede196652020-01-22 17:29:58 -08001225 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001226}
1227
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001228TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001229 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001230
Lloyd Piquede196652020-01-22 17:29:58 -08001231 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232}
1233
1234TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1235 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001236 mLayer.layerFEState.isOpaque = true;
1237 mLayer.layerFEState.contentDirty = true;
1238 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001239
1240 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001241 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1242 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001243
Lloyd Piquede196652020-01-22 17:29:58 -08001244 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001245
1246 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1247 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1248 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1249
Lloyd Piquede196652020-01-22 17:29:58 -08001250 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1251 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1252 RegionEq(kFullBoundsNoRotation));
1253 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1254 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001255}
1256
1257TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1258 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001259 mLayer.layerFEState.isOpaque = true;
1260 mLayer.layerFEState.contentDirty = true;
1261 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262
Lloyd Piquede196652020-01-22 17:29:58 -08001263 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1264 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265
Lloyd Piquede196652020-01-22 17:29:58 -08001266 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267
1268 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1269 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1270 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1271
Lloyd Piquede196652020-01-22 17:29:58 -08001272 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1273 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1274 RegionEq(kFullBoundsNoRotation));
1275 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1276 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001277}
1278
1279TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1280 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001281 mLayer.layerFEState.isOpaque = false;
1282 mLayer.layerFEState.contentDirty = true;
1283 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
1285 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001286 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1287 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001288
Lloyd Piquede196652020-01-22 17:29:58 -08001289 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001290
1291 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1292 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1293 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1294
Lloyd Piquede196652020-01-22 17:29:58 -08001295 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1296 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001297 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001298 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1299 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001300}
1301
1302TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1303 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001304 mLayer.layerFEState.isOpaque = false;
1305 mLayer.layerFEState.contentDirty = true;
1306 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001307
Lloyd Piquede196652020-01-22 17:29:58 -08001308 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1309 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310
Lloyd Piquede196652020-01-22 17:29:58 -08001311 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001312
1313 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1314 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1315 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1316
Lloyd Piquede196652020-01-22 17:29:58 -08001317 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1318 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001320 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1321 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001322}
1323
1324TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1325 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001326 mLayer.layerFEState.isOpaque = true;
1327 mLayer.layerFEState.contentDirty = false;
1328 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329
1330 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001331 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1332 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335
1336 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1337 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1338 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1339
Lloyd Piquede196652020-01-22 17:29:58 -08001340 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1341 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1342 RegionEq(kFullBoundsNoRotation));
1343 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1344 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345}
1346
1347TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1348 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001349 mLayer.layerFEState.isOpaque = true;
1350 mLayer.layerFEState.contentDirty = false;
1351 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1354 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357
1358 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1359 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1361
Lloyd Piquede196652020-01-22 17:29:58 -08001362 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1364 RegionEq(kFullBoundsNoRotation));
1365 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1366 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367}
1368
1369TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1370 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001371 mLayer.layerFEState.isOpaque = true;
1372 mLayer.layerFEState.contentDirty = true;
1373 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1374 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1375 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1376 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
1378 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001379 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1380 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381
Lloyd Piquede196652020-01-22 17:29:58 -08001382 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383
1384 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1390 RegionEq(kFullBoundsNoRotation));
1391 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1392 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393}
1394
1395TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1396 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001397 mLayer.layerFEState.isOpaque = true;
1398 mLayer.layerFEState.contentDirty = true;
1399 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1400 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1401 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1402 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
Lloyd Piquede196652020-01-22 17:29:58 -08001404 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1405 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001406
Lloyd Piquede196652020-01-22 17:29:58 -08001407 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408
1409 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1410 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1411 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1412
Lloyd Piquede196652020-01-22 17:29:58 -08001413 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1414 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1415 RegionEq(kFullBoundsNoRotation));
1416 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1417 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418}
1419
1420TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1421 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001422 mLayer.layerFEState.isOpaque = true;
1423 mLayer.layerFEState.contentDirty = true;
1424 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001426 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1428
1429 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1431 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432
Lloyd Piquede196652020-01-22 17:29:58 -08001433 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
1435 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1440 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1441 RegionEq(kFullBoundsNoRotation));
1442 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1443 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444}
1445
1446TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1447 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001448 mLayer.layerFEState.isOpaque = true;
1449 mLayer.layerFEState.contentDirty = true;
1450 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001452 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1454
Lloyd Piquede196652020-01-22 17:29:58 -08001455 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1456 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457
Lloyd Piquede196652020-01-22 17:29:58 -08001458 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459
1460 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1461 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1462 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1463
Lloyd Piquede196652020-01-22 17:29:58 -08001464 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1465 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1466 RegionEq(kFullBoundsNoRotation));
1467 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1468 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469}
1470
1471TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1472 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1473 ui::Transform arbitraryTransform;
1474 arbitraryTransform.set(1, 1, -1, 1);
1475 arbitraryTransform.set(0, 100);
1476
Lloyd Piquede196652020-01-22 17:29:58 -08001477 mLayer.layerFEState.isOpaque = true;
1478 mLayer.layerFEState.contentDirty = true;
1479 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1480 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001481
1482 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001483 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1484 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485
Lloyd Piquede196652020-01-22 17:29:58 -08001486 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001487
1488 const Region kRegion = Region(Rect(0, 0, 300, 300));
1489 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1490
1491 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1492 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1493 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1494
Lloyd Piquede196652020-01-22 17:29:58 -08001495 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1496 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1497 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1498 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499}
1500
1501TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001502 mLayer.layerFEState.isOpaque = false;
1503 mLayer.layerFEState.contentDirty = true;
1504 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505
1506 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1507 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1508 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1511 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514
1515 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1516 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1517 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1518 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1519 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1520 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1521
1522 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1523 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1524 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1527 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001529 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1531 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001532}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001533
Vishnu Naira483b4a2019-12-12 15:07:52 -08001534TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1535 ui::Transform translate;
1536 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001537 mLayer.layerFEState.geomLayerTransform = translate;
1538 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001539
1540 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1541 // half of the layer including the casting shadow is covered and opaque
1542 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1543 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1546 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001549
1550 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1551 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1552 // add starting opaque region to the opaque half of the casting layer bounds
1553 const Region kExpectedAboveOpaqueRegion =
1554 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1555 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1556 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1557 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1558 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1559 const Region kExpectedLayerShadowRegion =
1560 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1561
1562 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1563 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1564 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1565
Lloyd Piquede196652020-01-22 17:29:58 -08001566 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1567 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001568 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001569 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1570 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001571 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001572 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001573 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1574}
1575
1576TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1577 ui::Transform translate;
1578 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001579 mLayer.layerFEState.geomLayerTransform = translate;
1580 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001581
1582 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1583 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1584 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1585 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1586
Lloyd Piquede196652020-01-22 17:29:58 -08001587 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1588 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001591
1592 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1593 const Region kExpectedLayerShadowRegion =
1594 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1595
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1597 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001598 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1599}
1600
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001601TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001602 ui::Transform translate;
1603 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001604 mLayer.layerFEState.geomLayerTransform = translate;
1605 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001606
1607 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1608 // Casting layer and its shadows are covered by an opaque region
1609 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1610 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1611
Lloyd Piquede196652020-01-22 17:29:58 -08001612 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001613}
1614
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001615/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001616 * Output::present()
1617 */
1618
1619struct OutputPresentTest : public testing::Test {
1620 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001621 // Sets up the helper functions called by the function under test to use
1622 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001623 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1624 MOCK_METHOD1(updateAndWriteCompositionState,
1625 void(const compositionengine::CompositionRefreshArgs&));
1626 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1627 MOCK_METHOD0(beginFrame, void());
1628 MOCK_METHOD0(prepareFrame, void());
1629 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1630 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1631 MOCK_METHOD0(postFramebuffer, void());
1632 };
1633
1634 StrictMock<OutputPartialMock> mOutput;
1635};
1636
1637TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1638 CompositionRefreshArgs args;
1639
1640 InSequence seq;
1641 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1642 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1643 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1644 EXPECT_CALL(mOutput, beginFrame());
1645 EXPECT_CALL(mOutput, prepareFrame());
1646 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1647 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1648 EXPECT_CALL(mOutput, postFramebuffer());
1649
1650 mOutput.present(args);
1651}
1652
1653/*
1654 * Output::updateColorProfile()
1655 */
1656
Lloyd Pique17ca7422019-11-14 14:24:10 -08001657struct OutputUpdateColorProfileTest : public testing::Test {
1658 using TestType = OutputUpdateColorProfileTest;
1659
1660 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001661 // Sets up the helper functions called by the function under test to use
1662 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001663 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1664 };
1665
1666 struct Layer {
1667 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001668 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001669 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001670 }
1671
1672 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001673 StrictMock<mock::LayerFE> mLayerFE;
1674 LayerFECompositionState mLayerFEState;
1675 };
1676
1677 OutputUpdateColorProfileTest() {
1678 mOutput.setDisplayColorProfileForTest(
1679 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1680 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1681
1682 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1683 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1684 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1685 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1686 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1687 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1688 }
1689
1690 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1691 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1692 };
1693
1694 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1695 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1696 StrictMock<OutputPartialMock> mOutput;
1697
1698 Layer mLayer1;
1699 Layer mLayer2;
1700 Layer mLayer3;
1701
1702 CompositionRefreshArgs mRefreshArgs;
1703};
1704
1705// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1706// to make it easier to write unit tests.
1707
1708TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1709 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1710 // a simple default color profile without looking at anything else.
1711
Lloyd Pique0a456232020-01-16 17:51:13 -08001712 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001713 EXPECT_CALL(mOutput,
1714 setColorProfile(ColorProfileEq(
1715 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1716 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1717
1718 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1719 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1720
1721 mOutput.updateColorProfile(mRefreshArgs);
1722}
1723
1724struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1725 : public OutputUpdateColorProfileTest {
1726 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001727 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001728 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1729 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1730 }
1731
1732 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1733 : public CallOrderStateMachineHelper<
1734 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1735 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1736 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1737 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1738 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1739 _))
1740 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1741 SetArgPointee<4>(renderIntent)));
1742 EXPECT_CALL(getInstance()->mOutput,
1743 setColorProfile(
1744 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1745 ui::Dataspace::UNKNOWN})));
1746 return nextState<ExecuteState>();
1747 }
1748 };
1749
1750 // Call this member function to start using the mini-DSL defined above.
1751 [[nodiscard]] auto verify() {
1752 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1753 }
1754};
1755
1756TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1757 Native_Unknown_Colorimetric_Set) {
1758 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1759 ui::Dataspace::UNKNOWN,
1760 ui::RenderIntent::COLORIMETRIC)
1761 .execute();
1762}
1763
1764TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1765 DisplayP3_DisplayP3_Enhance_Set) {
1766 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1767 ui::Dataspace::DISPLAY_P3,
1768 ui::RenderIntent::ENHANCE)
1769 .execute();
1770}
1771
1772struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1773 : public OutputUpdateColorProfileTest {
1774 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001775 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001776 EXPECT_CALL(*mDisplayColorProfile,
1777 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1778 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1779 SetArgPointee<3>(ui::ColorMode::NATIVE),
1780 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1781 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1782 }
1783
1784 struct IfColorSpaceAgnosticDataspaceSetToState
1785 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1786 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1787 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1788 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1789 }
1790 };
1791
1792 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1793 : public CallOrderStateMachineHelper<
1794 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1795 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1796 ui::Dataspace dataspace) {
1797 EXPECT_CALL(getInstance()->mOutput,
1798 setColorProfile(ColorProfileEq(
1799 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1800 ui::RenderIntent::COLORIMETRIC, dataspace})));
1801 return nextState<ExecuteState>();
1802 }
1803 };
1804
1805 // Call this member function to start using the mini-DSL defined above.
1806 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1807};
1808
1809TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1810 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1811 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1812 .execute();
1813}
1814
1815TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1816 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1817 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1818 .execute();
1819}
1820
1821struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1822 : public OutputUpdateColorProfileTest {
1823 // Internally the implementation looks through the dataspaces of all the
1824 // visible layers. The topmost one that also has an actual dataspace
1825 // preference set is used to drive subsequent choices.
1826
1827 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1828 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1829 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1830
Lloyd Pique0a456232020-01-16 17:51:13 -08001831 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001832 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1833 }
1834
1835 struct IfTopLayerDataspaceState
1836 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1837 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1838 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1839 return nextState<AndIfMiddleLayerDataspaceState>();
1840 }
1841 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1842 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1843 }
1844 };
1845
1846 struct AndIfMiddleLayerDataspaceState
1847 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1848 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1849 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1850 return nextState<AndIfBottomLayerDataspaceState>();
1851 }
1852 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1853 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1854 }
1855 };
1856
1857 struct AndIfBottomLayerDataspaceState
1858 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1859 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1860 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1861 return nextState<ThenExpectBestColorModeCallUsesState>();
1862 }
1863 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1864 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1865 }
1866 };
1867
1868 struct ThenExpectBestColorModeCallUsesState
1869 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1870 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1871 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1872 getBestColorMode(dataspace, _, _, _, _));
1873 return nextState<ExecuteState>();
1874 }
1875 };
1876
1877 // Call this member function to start using the mini-DSL defined above.
1878 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1879};
1880
1881TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1882 noStrongLayerPrefenceUses_V0_SRGB) {
1883 // If none of the layers indicate a preference, then V0_SRGB is the
1884 // preferred choice (subject to additional checks).
1885 verify().ifTopLayerHasNoPreference()
1886 .andIfMiddleLayerHasNoPreference()
1887 .andIfBottomLayerHasNoPreference()
1888 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1889 .execute();
1890}
1891
1892TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1893 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1894 // If only the topmost layer has a preference, then that is what is chosen.
1895 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1896 .andIfMiddleLayerHasNoPreference()
1897 .andIfBottomLayerHasNoPreference()
1898 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1899 .execute();
1900}
1901
1902TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1903 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1904 // If only the middle layer has a preference, that that is what is chosen.
1905 verify().ifTopLayerHasNoPreference()
1906 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1907 .andIfBottomLayerHasNoPreference()
1908 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1909 .execute();
1910}
1911
1912TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1913 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1914 // If only the middle layer has a preference, that that is what is chosen.
1915 verify().ifTopLayerHasNoPreference()
1916 .andIfMiddleLayerHasNoPreference()
1917 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1918 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1919 .execute();
1920}
1921
1922TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1923 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1924 // If multiple layers have a preference, the topmost value is what is used.
1925 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1926 .andIfMiddleLayerHasNoPreference()
1927 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1928 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1929 .execute();
1930}
1931
1932TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1933 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1934 // If multiple layers have a preference, the topmost value is what is used.
1935 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1936 .andIfMiddleLayerHasNoPreference()
1937 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1938 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1939 .execute();
1940}
1941
1942struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1943 : public OutputUpdateColorProfileTest {
1944 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1945 // values, it overrides the layer dataspace choice.
1946
1947 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1948 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1949 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1950
1951 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1952
Lloyd Pique0a456232020-01-16 17:51:13 -08001953 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001954 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1955 }
1956
1957 struct IfForceOutputColorModeState
1958 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1959 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1960 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1961 return nextState<ThenExpectBestColorModeCallUsesState>();
1962 }
1963 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1964 };
1965
1966 struct ThenExpectBestColorModeCallUsesState
1967 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1968 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1969 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1970 getBestColorMode(dataspace, _, _, _, _));
1971 return nextState<ExecuteState>();
1972 }
1973 };
1974
1975 // Call this member function to start using the mini-DSL defined above.
1976 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1977};
1978
1979TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1980 // By default the layer state is used to set the preferred dataspace
1981 verify().ifNoOverride()
1982 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1983 .execute();
1984}
1985
1986TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1987 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1988 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1989 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1990 .execute();
1991}
1992
1993TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1994 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1995 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1996 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1997 .execute();
1998}
1999
2000// HDR output requires all layers to be compatible with the chosen HDR
2001// dataspace, along with there being proper support.
2002struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2003 OutputUpdateColorProfileTest_Hdr() {
2004 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2005 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002006 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002007 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2008 }
2009
2010 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2011 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2012 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2013 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2014
2015 struct IfTopLayerDataspaceState
2016 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2017 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2018 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2019 return nextState<AndTopLayerCompositionTypeState>();
2020 }
2021 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2022 };
2023
2024 struct AndTopLayerCompositionTypeState
2025 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2026 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2027 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2028 return nextState<AndIfBottomLayerDataspaceState>();
2029 }
2030 };
2031
2032 struct AndIfBottomLayerDataspaceState
2033 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2034 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2035 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2036 return nextState<AndBottomLayerCompositionTypeState>();
2037 }
2038 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2039 return andIfBottomLayerIs(kNonHdrDataspace);
2040 }
2041 };
2042
2043 struct AndBottomLayerCompositionTypeState
2044 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2045 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2046 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2047 return nextState<AndIfHasLegacySupportState>();
2048 }
2049 };
2050
2051 struct AndIfHasLegacySupportState
2052 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2053 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2054 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2055 .WillOnce(Return(legacySupport));
2056 return nextState<ThenExpectBestColorModeCallUsesState>();
2057 }
2058 };
2059
2060 struct ThenExpectBestColorModeCallUsesState
2061 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2062 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2063 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2064 getBestColorMode(dataspace, _, _, _, _));
2065 return nextState<ExecuteState>();
2066 }
2067 };
2068
2069 // Call this member function to start using the mini-DSL defined above.
2070 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2071};
2072
2073TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2074 // If all layers use BT2020_PQ, and there are no other special conditions,
2075 // BT2020_PQ is used.
2076 verify().ifTopLayerIs(BT2020_PQ)
2077 .andTopLayerIsREComposed(false)
2078 .andIfBottomLayerIs(BT2020_PQ)
2079 .andBottomLayerIsREComposed(false)
2080 .andIfLegacySupportFor(BT2020_PQ, false)
2081 .thenExpectBestColorModeCallUses(BT2020_PQ)
2082 .execute();
2083}
2084
2085TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2086 // BT2020_PQ is not used if there is only legacy support for it.
2087 verify().ifTopLayerIs(BT2020_PQ)
2088 .andTopLayerIsREComposed(false)
2089 .andIfBottomLayerIs(BT2020_PQ)
2090 .andBottomLayerIsREComposed(false)
2091 .andIfLegacySupportFor(BT2020_PQ, true)
2092 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2093 .execute();
2094}
2095
2096TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2097 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2098 verify().ifTopLayerIs(BT2020_PQ)
2099 .andTopLayerIsREComposed(false)
2100 .andIfBottomLayerIs(BT2020_PQ)
2101 .andBottomLayerIsREComposed(true)
2102 .andIfLegacySupportFor(BT2020_PQ, false)
2103 .thenExpectBestColorModeCallUses(BT2020_PQ)
2104 .execute();
2105}
2106
2107TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2108 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2109 verify().ifTopLayerIs(BT2020_PQ)
2110 .andTopLayerIsREComposed(true)
2111 .andIfBottomLayerIs(BT2020_PQ)
2112 .andBottomLayerIsREComposed(false)
2113 .andIfLegacySupportFor(BT2020_PQ, false)
2114 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2115 .execute();
2116}
2117
2118TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2119 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2120 // are no other special conditions.
2121 verify().ifTopLayerIs(BT2020_PQ)
2122 .andTopLayerIsREComposed(false)
2123 .andIfBottomLayerIs(BT2020_HLG)
2124 .andBottomLayerIsREComposed(false)
2125 .andIfLegacySupportFor(BT2020_PQ, false)
2126 .thenExpectBestColorModeCallUses(BT2020_PQ)
2127 .execute();
2128}
2129
2130TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2131 // BT2020_PQ is not used if there is only legacy support for it.
2132 verify().ifTopLayerIs(BT2020_PQ)
2133 .andTopLayerIsREComposed(false)
2134 .andIfBottomLayerIs(BT2020_HLG)
2135 .andBottomLayerIsREComposed(false)
2136 .andIfLegacySupportFor(BT2020_PQ, true)
2137 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2138 .execute();
2139}
2140
2141TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2142 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2143 verify().ifTopLayerIs(BT2020_PQ)
2144 .andTopLayerIsREComposed(false)
2145 .andIfBottomLayerIs(BT2020_HLG)
2146 .andBottomLayerIsREComposed(true)
2147 .andIfLegacySupportFor(BT2020_PQ, false)
2148 .thenExpectBestColorModeCallUses(BT2020_PQ)
2149 .execute();
2150}
2151
2152TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2153 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2154 verify().ifTopLayerIs(BT2020_PQ)
2155 .andTopLayerIsREComposed(true)
2156 .andIfBottomLayerIs(BT2020_HLG)
2157 .andBottomLayerIsREComposed(false)
2158 .andIfLegacySupportFor(BT2020_PQ, false)
2159 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2160 .execute();
2161}
2162
2163TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2164 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2165 // used if there are no other special conditions.
2166 verify().ifTopLayerIs(BT2020_HLG)
2167 .andTopLayerIsREComposed(false)
2168 .andIfBottomLayerIs(BT2020_PQ)
2169 .andBottomLayerIsREComposed(false)
2170 .andIfLegacySupportFor(BT2020_PQ, false)
2171 .thenExpectBestColorModeCallUses(BT2020_PQ)
2172 .execute();
2173}
2174
2175TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2176 // BT2020_PQ is not used if there is only legacy support for it.
2177 verify().ifTopLayerIs(BT2020_HLG)
2178 .andTopLayerIsREComposed(false)
2179 .andIfBottomLayerIs(BT2020_PQ)
2180 .andBottomLayerIsREComposed(false)
2181 .andIfLegacySupportFor(BT2020_PQ, true)
2182 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2183 .execute();
2184}
2185
2186TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2187 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2188 verify().ifTopLayerIs(BT2020_HLG)
2189 .andTopLayerIsREComposed(false)
2190 .andIfBottomLayerIs(BT2020_PQ)
2191 .andBottomLayerIsREComposed(true)
2192 .andIfLegacySupportFor(BT2020_PQ, false)
2193 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2194 .execute();
2195}
2196
2197TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2198 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2199 verify().ifTopLayerIs(BT2020_HLG)
2200 .andTopLayerIsREComposed(true)
2201 .andIfBottomLayerIs(BT2020_PQ)
2202 .andBottomLayerIsREComposed(false)
2203 .andIfLegacySupportFor(BT2020_PQ, false)
2204 .thenExpectBestColorModeCallUses(BT2020_PQ)
2205 .execute();
2206}
2207
2208TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2209 // If all layers use HLG then HLG is used if there are no other special
2210 // conditions.
2211 verify().ifTopLayerIs(BT2020_HLG)
2212 .andTopLayerIsREComposed(false)
2213 .andIfBottomLayerIs(BT2020_HLG)
2214 .andBottomLayerIsREComposed(false)
2215 .andIfLegacySupportFor(BT2020_HLG, false)
2216 .thenExpectBestColorModeCallUses(BT2020_HLG)
2217 .execute();
2218}
2219
2220TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2221 // BT2020_HLG is not used if there is legacy support for it.
2222 verify().ifTopLayerIs(BT2020_HLG)
2223 .andTopLayerIsREComposed(false)
2224 .andIfBottomLayerIs(BT2020_HLG)
2225 .andBottomLayerIsREComposed(false)
2226 .andIfLegacySupportFor(BT2020_HLG, true)
2227 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2228 .execute();
2229}
2230
2231TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2232 // BT2020_HLG is used even if the bottom layer is client composed.
2233 verify().ifTopLayerIs(BT2020_HLG)
2234 .andTopLayerIsREComposed(false)
2235 .andIfBottomLayerIs(BT2020_HLG)
2236 .andBottomLayerIsREComposed(true)
2237 .andIfLegacySupportFor(BT2020_HLG, false)
2238 .thenExpectBestColorModeCallUses(BT2020_HLG)
2239 .execute();
2240}
2241
2242TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2243 // BT2020_HLG is used even if the top layer is client composed.
2244 verify().ifTopLayerIs(BT2020_HLG)
2245 .andTopLayerIsREComposed(true)
2246 .andIfBottomLayerIs(BT2020_HLG)
2247 .andBottomLayerIsREComposed(false)
2248 .andIfLegacySupportFor(BT2020_HLG, false)
2249 .thenExpectBestColorModeCallUses(BT2020_HLG)
2250 .execute();
2251}
2252
2253TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2254 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2255 verify().ifTopLayerIs(BT2020_PQ)
2256 .andTopLayerIsREComposed(false)
2257 .andIfBottomLayerIsNotHdr()
2258 .andBottomLayerIsREComposed(false)
2259 .andIfLegacySupportFor(BT2020_PQ, false)
2260 .thenExpectBestColorModeCallUses(BT2020_PQ)
2261 .execute();
2262}
2263
2264TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2265 // If all layers use HLG then HLG is used if there are no other special
2266 // conditions.
2267 verify().ifTopLayerIs(BT2020_HLG)
2268 .andTopLayerIsREComposed(false)
2269 .andIfBottomLayerIsNotHdr()
2270 .andBottomLayerIsREComposed(true)
2271 .andIfLegacySupportFor(BT2020_HLG, false)
2272 .thenExpectBestColorModeCallUses(BT2020_HLG)
2273 .execute();
2274}
2275
2276struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2277 : public OutputUpdateColorProfileTest {
2278 // The various values for CompositionRefreshArgs::outputColorSetting affect
2279 // the chosen renderIntent, along with whether the preferred dataspace is an
2280 // HDR dataspace or not.
2281
2282 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2283 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2284 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2285 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002286 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002287 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2288 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2289 .WillRepeatedly(Return(false));
2290 }
2291
2292 // The tests here involve enough state and GMock setup that using a mini-DSL
2293 // makes the tests much more readable, and allows the test to focus more on
2294 // the intent than on some of the details.
2295
2296 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2297 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2298
2299 struct IfDataspaceChosenState
2300 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2301 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2302 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2303 return nextState<AndOutputColorSettingState>();
2304 }
2305 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2306 return ifDataspaceChosenIs(kNonHdrDataspace);
2307 }
2308 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2309 };
2310
2311 struct AndOutputColorSettingState
2312 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2313 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2314 getInstance()->mRefreshArgs.outputColorSetting = setting;
2315 return nextState<ThenExpectBestColorModeCallUsesState>();
2316 }
2317 };
2318
2319 struct ThenExpectBestColorModeCallUsesState
2320 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2321 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2322 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2323 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2324 _, _));
2325 return nextState<ExecuteState>();
2326 }
2327 };
2328
2329 // Tests call one of these two helper member functions to start using the
2330 // mini-DSL defined above.
2331 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2332};
2333
2334TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2335 Managed_NonHdr_Prefers_Colorimetric) {
2336 verify().ifDataspaceChosenIsNonHdr()
2337 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2338 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2339 .execute();
2340}
2341
2342TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2343 Managed_Hdr_Prefers_ToneMapColorimetric) {
2344 verify().ifDataspaceChosenIsHdr()
2345 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2346 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2347 .execute();
2348}
2349
2350TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2351 verify().ifDataspaceChosenIsNonHdr()
2352 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2353 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2354 .execute();
2355}
2356
2357TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2358 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2359 verify().ifDataspaceChosenIsHdr()
2360 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2361 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2362 .execute();
2363}
2364
2365TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2366 verify().ifDataspaceChosenIsNonHdr()
2367 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2368 .thenExpectBestColorModeCallUses(
2369 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2370 .execute();
2371}
2372
2373TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2374 verify().ifDataspaceChosenIsHdr()
2375 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2376 .thenExpectBestColorModeCallUses(
2377 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2378 .execute();
2379}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002380
2381/*
2382 * Output::beginFrame()
2383 */
2384
Lloyd Piquee5965952019-11-18 16:16:32 -08002385struct OutputBeginFrameTest : public ::testing::Test {
2386 using TestType = OutputBeginFrameTest;
2387
2388 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002389 // Sets up the helper functions called by the function under test to use
2390 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002391 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2392 };
2393
2394 OutputBeginFrameTest() {
2395 mOutput.setDisplayColorProfileForTest(
2396 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2397 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2398 }
2399
2400 struct IfGetDirtyRegionExpectationState
2401 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2402 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2403 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2404 .WillOnce(Return(dirtyRegion));
2405 return nextState<AndIfGetOutputLayerCountExpectationState>();
2406 }
2407 };
2408
2409 struct AndIfGetOutputLayerCountExpectationState
2410 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2411 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2412 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2413 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2414 }
2415 };
2416
2417 struct AndIfLastCompositionHadVisibleLayersState
2418 : public CallOrderStateMachineHelper<TestType,
2419 AndIfLastCompositionHadVisibleLayersState> {
2420 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2421 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2422 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2423 }
2424 };
2425
2426 struct ThenExpectRenderSurfaceBeginFrameCallState
2427 : public CallOrderStateMachineHelper<TestType,
2428 ThenExpectRenderSurfaceBeginFrameCallState> {
2429 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2430 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2431 return nextState<ExecuteState>();
2432 }
2433 };
2434
2435 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2436 [[nodiscard]] auto execute() {
2437 getInstance()->mOutput.beginFrame();
2438 return nextState<CheckPostconditionHadVisibleLayersState>();
2439 }
2440 };
2441
2442 struct CheckPostconditionHadVisibleLayersState
2443 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2444 void checkPostconditionHadVisibleLayers(bool expected) {
2445 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2446 }
2447 };
2448
2449 // Tests call one of these two helper member functions to start using the
2450 // mini-DSL defined above.
2451 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2452
2453 static const Region kEmptyRegion;
2454 static const Region kNotEmptyRegion;
2455
2456 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2457 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2458 StrictMock<OutputPartialMock> mOutput;
2459};
2460
2461const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2462const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2463
2464TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2465 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2466 .andIfGetOutputLayerCountReturns(1u)
2467 .andIfLastCompositionHadVisibleLayersIs(true)
2468 .thenExpectRenderSurfaceBeginFrameCall(true)
2469 .execute()
2470 .checkPostconditionHadVisibleLayers(true);
2471}
2472
2473TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2474 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2475 .andIfGetOutputLayerCountReturns(0u)
2476 .andIfLastCompositionHadVisibleLayersIs(true)
2477 .thenExpectRenderSurfaceBeginFrameCall(true)
2478 .execute()
2479 .checkPostconditionHadVisibleLayers(false);
2480}
2481
2482TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2483 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2484 .andIfGetOutputLayerCountReturns(1u)
2485 .andIfLastCompositionHadVisibleLayersIs(false)
2486 .thenExpectRenderSurfaceBeginFrameCall(true)
2487 .execute()
2488 .checkPostconditionHadVisibleLayers(true);
2489}
2490
2491TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2492 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2493 .andIfGetOutputLayerCountReturns(0u)
2494 .andIfLastCompositionHadVisibleLayersIs(false)
2495 .thenExpectRenderSurfaceBeginFrameCall(false)
2496 .execute()
2497 .checkPostconditionHadVisibleLayers(false);
2498}
2499
2500TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2501 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2502 .andIfGetOutputLayerCountReturns(1u)
2503 .andIfLastCompositionHadVisibleLayersIs(true)
2504 .thenExpectRenderSurfaceBeginFrameCall(false)
2505 .execute()
2506 .checkPostconditionHadVisibleLayers(true);
2507}
2508
2509TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2510 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2511 .andIfGetOutputLayerCountReturns(0u)
2512 .andIfLastCompositionHadVisibleLayersIs(true)
2513 .thenExpectRenderSurfaceBeginFrameCall(false)
2514 .execute()
2515 .checkPostconditionHadVisibleLayers(true);
2516}
2517
2518TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2519 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2520 .andIfGetOutputLayerCountReturns(1u)
2521 .andIfLastCompositionHadVisibleLayersIs(false)
2522 .thenExpectRenderSurfaceBeginFrameCall(false)
2523 .execute()
2524 .checkPostconditionHadVisibleLayers(false);
2525}
2526
2527TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2528 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2529 .andIfGetOutputLayerCountReturns(0u)
2530 .andIfLastCompositionHadVisibleLayersIs(false)
2531 .thenExpectRenderSurfaceBeginFrameCall(false)
2532 .execute()
2533 .checkPostconditionHadVisibleLayers(false);
2534}
2535
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002536/*
2537 * Output::devOptRepaintFlash()
2538 */
2539
Lloyd Piquedb462d82019-11-19 17:58:46 -08002540struct OutputDevOptRepaintFlashTest : public testing::Test {
2541 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002542 // Sets up the helper functions called by the function under test to use
2543 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002544 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002545 MOCK_METHOD2(composeSurfaces,
2546 std::optional<base::unique_fd>(
2547 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002548 MOCK_METHOD0(postFramebuffer, void());
2549 MOCK_METHOD0(prepareFrame, void());
2550 };
2551
2552 OutputDevOptRepaintFlashTest() {
2553 mOutput.setDisplayColorProfileForTest(
2554 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2555 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2556 }
2557
2558 static const Region kEmptyRegion;
2559 static const Region kNotEmptyRegion;
2560
2561 StrictMock<OutputPartialMock> mOutput;
2562 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2563 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2564 CompositionRefreshArgs mRefreshArgs;
2565};
2566
2567const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2568const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2569
2570TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2571 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2572 mRefreshArgs.repaintEverything = true;
2573 mOutput.mState.isEnabled = true;
2574
2575 mOutput.devOptRepaintFlash(mRefreshArgs);
2576}
2577
2578TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2579 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2580 mRefreshArgs.repaintEverything = true;
2581 mOutput.mState.isEnabled = false;
2582
2583 InSequence seq;
2584 EXPECT_CALL(mOutput, postFramebuffer());
2585 EXPECT_CALL(mOutput, prepareFrame());
2586
2587 mOutput.devOptRepaintFlash(mRefreshArgs);
2588}
2589
2590TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2591 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2592 mRefreshArgs.repaintEverything = true;
2593 mOutput.mState.isEnabled = true;
2594
2595 InSequence seq;
2596 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2597 EXPECT_CALL(mOutput, postFramebuffer());
2598 EXPECT_CALL(mOutput, prepareFrame());
2599
2600 mOutput.devOptRepaintFlash(mRefreshArgs);
2601}
2602
2603TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2604 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2605 mRefreshArgs.repaintEverything = false;
2606 mOutput.mState.isEnabled = true;
2607
2608 InSequence seq;
2609 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002610 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002611 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2612 EXPECT_CALL(mOutput, postFramebuffer());
2613 EXPECT_CALL(mOutput, prepareFrame());
2614
2615 mOutput.devOptRepaintFlash(mRefreshArgs);
2616}
2617
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002618/*
2619 * Output::finishFrame()
2620 */
2621
Lloyd Pique03561a62019-11-19 18:34:52 -08002622struct OutputFinishFrameTest : public testing::Test {
2623 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002624 // Sets up the helper functions called by the function under test to use
2625 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002626 MOCK_METHOD2(composeSurfaces,
2627 std::optional<base::unique_fd>(
2628 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002629 MOCK_METHOD0(postFramebuffer, void());
2630 };
2631
2632 OutputFinishFrameTest() {
2633 mOutput.setDisplayColorProfileForTest(
2634 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2635 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2636 }
2637
2638 StrictMock<OutputPartialMock> mOutput;
2639 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2640 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2641 CompositionRefreshArgs mRefreshArgs;
2642};
2643
2644TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2645 mOutput.mState.isEnabled = false;
2646
2647 mOutput.finishFrame(mRefreshArgs);
2648}
2649
2650TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2651 mOutput.mState.isEnabled = true;
2652
2653 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002654 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002655
2656 mOutput.finishFrame(mRefreshArgs);
2657}
2658
2659TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2660 mOutput.mState.isEnabled = true;
2661
2662 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002663 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002664 .WillOnce(Return(ByMove(base::unique_fd())));
2665 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2666
2667 mOutput.finishFrame(mRefreshArgs);
2668}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002669
2670/*
2671 * Output::postFramebuffer()
2672 */
2673
Lloyd Pique07178e32019-11-19 19:15:26 -08002674struct OutputPostFramebufferTest : public testing::Test {
2675 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002676 // Sets up the helper functions called by the function under test to use
2677 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002678 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2679 };
2680
2681 struct Layer {
2682 Layer() {
2683 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2684 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2685 }
2686
2687 StrictMock<mock::OutputLayer> outputLayer;
2688 StrictMock<mock::LayerFE> layerFE;
2689 StrictMock<HWC2::mock::Layer> hwc2Layer;
2690 };
2691
2692 OutputPostFramebufferTest() {
2693 mOutput.setDisplayColorProfileForTest(
2694 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2695 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2696
2697 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2698 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2699 .WillRepeatedly(Return(&mLayer1.outputLayer));
2700 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2701 .WillRepeatedly(Return(&mLayer2.outputLayer));
2702 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2703 .WillRepeatedly(Return(&mLayer3.outputLayer));
2704 }
2705
2706 StrictMock<OutputPartialMock> mOutput;
2707 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2708 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2709
2710 Layer mLayer1;
2711 Layer mLayer2;
2712 Layer mLayer3;
2713};
2714
2715TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2716 mOutput.mState.isEnabled = false;
2717
2718 mOutput.postFramebuffer();
2719}
2720
2721TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2722 mOutput.mState.isEnabled = true;
2723
2724 compositionengine::Output::FrameFences frameFences;
2725
2726 // This should happen even if there are no output layers.
2727 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2728
2729 // For this test in particular we want to make sure the call expectations
2730 // setup below are satisfied in the specific order.
2731 InSequence seq;
2732
2733 EXPECT_CALL(*mRenderSurface, flip());
2734 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2735 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2736
2737 mOutput.postFramebuffer();
2738}
2739
2740TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2741 // Simulate getting release fences from each layer, and ensure they are passed to the
2742 // front-end layer interface for each layer correctly.
2743
2744 mOutput.mState.isEnabled = true;
2745
2746 // Create three unique fence instances
2747 sp<Fence> layer1Fence = new Fence();
2748 sp<Fence> layer2Fence = new Fence();
2749 sp<Fence> layer3Fence = new Fence();
2750
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002751 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002752 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2753 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2754 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2755
2756 EXPECT_CALL(*mRenderSurface, flip());
2757 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2758 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2759
2760 // Compare the pointers values of each fence to make sure the correct ones
2761 // are passed. This happens to work with the current implementation, but
2762 // would not survive certain calls like Fence::merge() which would return a
2763 // new instance.
2764 EXPECT_CALL(mLayer1.layerFE,
2765 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2766 EXPECT_CALL(mLayer2.layerFE,
2767 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2768 EXPECT_CALL(mLayer3.layerFE,
2769 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2770
2771 mOutput.postFramebuffer();
2772}
2773
2774TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2775 mOutput.mState.isEnabled = true;
2776 mOutput.mState.usesClientComposition = true;
2777
2778 sp<Fence> clientTargetAcquireFence = new Fence();
2779 sp<Fence> layer1Fence = new Fence();
2780 sp<Fence> layer2Fence = new Fence();
2781 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002782 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002783 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2784 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2785 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2786 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2787
2788 EXPECT_CALL(*mRenderSurface, flip());
2789 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2790 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2791
2792 // Fence::merge is called, and since none of the fences are actually valid,
2793 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2794 // This is the best we can do without creating a real kernel fence object.
2795 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2796 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2797 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2798
2799 mOutput.postFramebuffer();
2800}
2801
2802TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2803 mOutput.mState.isEnabled = true;
2804 mOutput.mState.usesClientComposition = true;
2805
2806 // This should happen even if there are no (current) output layers.
2807 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2808
2809 // Load up the released layers with some mock instances
2810 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2811 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2812 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2813 Output::ReleasedLayers layers;
2814 layers.push_back(releasedLayer1);
2815 layers.push_back(releasedLayer2);
2816 layers.push_back(releasedLayer3);
2817 mOutput.setReleasedLayers(std::move(layers));
2818
2819 // Set up a fake present fence
2820 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002821 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002822 frameFences.presentFence = presentFence;
2823
2824 EXPECT_CALL(*mRenderSurface, flip());
2825 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2826 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2827
2828 // Each released layer should be given the presentFence.
2829 EXPECT_CALL(*releasedLayer1,
2830 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2831 EXPECT_CALL(*releasedLayer2,
2832 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2833 EXPECT_CALL(*releasedLayer3,
2834 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2835
2836 mOutput.postFramebuffer();
2837
2838 // After the call the list of released layers should have been cleared.
2839 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2840}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002841
2842/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002843 * Output::composeSurfaces()
2844 */
2845
2846struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002847 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002848
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002849 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002850 // Sets up the helper functions called by the function under test to use
2851 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002852 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002853 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002854 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002855 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002856 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002857 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2858 };
2859
2860 OutputComposeSurfacesTest() {
2861 mOutput.setDisplayColorProfileForTest(
2862 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2863 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002864 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002865
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002866 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2867 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002868 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002869 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002870 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002871 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002872 mOutput.mState.dataspace = kDefaultOutputDataspace;
2873 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2874 mOutput.mState.isSecure = false;
2875 mOutput.mState.needsFiltering = false;
2876 mOutput.mState.usesClientComposition = true;
2877 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002878 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002879 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002880
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002881 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002882 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002883 EXPECT_CALL(mCompositionEngine, getTimeStats())
2884 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002885 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2886 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002887 }
2888
Lloyd Pique6818fa52019-12-03 12:32:13 -08002889 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2890 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002891 getInstance()->mReadyFence =
2892 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002893 return nextState<FenceCheckState>();
2894 }
2895 };
2896
2897 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2898 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2899
2900 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2901 };
2902
2903 // Call this member function to start using the mini-DSL defined above.
2904 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2905
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002906 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2907 static constexpr uint32_t kDefaultOutputOrientationFlags =
2908 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002909 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2910 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2911 static constexpr float kDefaultMaxLuminance = 0.9f;
2912 static constexpr float kDefaultAvgLuminance = 0.7f;
2913 static constexpr float kDefaultMinLuminance = 0.1f;
2914
2915 static const Rect kDefaultOutputFrame;
2916 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002917 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002918 static const mat4 kDefaultColorTransformMat;
2919
2920 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002921 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002922 static const HdrCapabilities kHdrCapabilities;
2923
Lloyd Pique56eba802019-08-28 15:45:25 -07002924 StrictMock<mock::CompositionEngine> mCompositionEngine;
2925 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002926 // TODO: make this is a proper mock.
2927 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002928 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2929 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002930 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002931 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002932
2933 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002934};
2935
2936const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2937const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002938const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002939const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002940const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002941const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2942const HdrCapabilities OutputComposeSurfacesTest::
2943 kHdrCapabilities{{},
2944 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2945 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2946 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002947
Lloyd Piquea76ce462020-01-14 13:06:37 -08002948TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002949 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002950
Lloyd Piquee9eff972020-05-05 12:36:44 -07002951 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002952 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002953
Lloyd Piquea76ce462020-01-14 13:06:37 -08002954 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2955
Lloyd Pique6818fa52019-12-03 12:32:13 -08002956 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002957}
2958
Lloyd Piquee9eff972020-05-05 12:36:44 -07002959TEST_F(OutputComposeSurfacesTest,
2960 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2961 mOutput.mState.usesClientComposition = false;
2962 mOutput.mState.flipClientTarget = true;
2963
Lloyd Pique6818fa52019-12-03 12:32:13 -08002964 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002965 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002966
2967 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2968 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2969
2970 verify().execute().expectAFenceWasReturned();
2971}
2972
2973TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2974 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002975 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002976
2977 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2978
2979 verify().execute().expectNoFenceWasReturned();
2980}
2981
2982TEST_F(OutputComposeSurfacesTest,
2983 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2984 mOutput.mState.usesClientComposition = false;
2985 mOutput.mState.flipClientTarget = true;
2986
2987 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002988 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002989
Lloyd Pique6818fa52019-12-03 12:32:13 -08002990 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002991
Lloyd Pique6818fa52019-12-03 12:32:13 -08002992 verify().execute().expectNoFenceWasReturned();
2993}
Lloyd Pique56eba802019-08-28 15:45:25 -07002994
Lloyd Pique6818fa52019-12-03 12:32:13 -08002995TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2996 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2997 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2998 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002999 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003000 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003001 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003002 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3003 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003004
Lloyd Pique6818fa52019-12-03 12:32:13 -08003005 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003006 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003007 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003008
Lloyd Pique6818fa52019-12-03 12:32:13 -08003009 verify().execute().expectAFenceWasReturned();
3010}
Lloyd Pique56eba802019-08-28 15:45:25 -07003011
Lloyd Pique6818fa52019-12-03 12:32:13 -08003012TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003013 LayerFE::LayerSettings r1;
3014 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003015
3016 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3017 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3018
3019 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3020 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3021 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003022 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003023 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003024 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003025 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3026 .WillRepeatedly(
3027 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003028 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003029 clientCompositionLayers.emplace_back(r2);
3030 }));
3031
3032 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003033 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3034 .WillRepeatedly(Return(NO_ERROR));
3035
3036 verify().execute().expectAFenceWasReturned();
3037}
3038
3039TEST_F(OutputComposeSurfacesTest,
3040 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3041 LayerFE::LayerSettings r1;
3042 LayerFE::LayerSettings r2;
3043
3044 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3045 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3046 const constexpr uint32_t kInternalLayerStack = 1234;
3047 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3048
3049 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3050 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3051 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3052 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3053 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3054 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3055 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3056 .WillRepeatedly(
3057 Invoke([&](const Region&,
3058 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3059 clientCompositionLayers.emplace_back(r2);
3060 }));
3061
3062 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003063 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003064 .WillRepeatedly(Return(NO_ERROR));
3065
3066 verify().execute().expectAFenceWasReturned();
3067}
3068
Vishnu Nair9b079a22020-01-21 14:36:08 -08003069TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3070 mOutput.cacheClientCompositionRequests(0);
3071 LayerFE::LayerSettings r1;
3072 LayerFE::LayerSettings r2;
3073
3074 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3075 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3076
3077 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3078 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3079 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003080 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003081 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3082 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3083 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3084 .WillRepeatedly(Return());
3085
3086 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003087 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003088 .Times(2)
3089 .WillOnce(Return(NO_ERROR));
3090
3091 verify().execute().expectAFenceWasReturned();
3092 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3093
3094 verify().execute().expectAFenceWasReturned();
3095 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3096}
3097
3098TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3099 mOutput.cacheClientCompositionRequests(3);
3100 LayerFE::LayerSettings r1;
3101 LayerFE::LayerSettings r2;
3102
3103 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3104 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3105
3106 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3107 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3108 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003109 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003110 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3111 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3112 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3113 .WillRepeatedly(Return());
3114
3115 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003116 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003117 .WillOnce(Return(NO_ERROR));
3118 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3119
3120 verify().execute().expectAFenceWasReturned();
3121 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3122
3123 // We do not expect another call to draw layers.
3124 verify().execute().expectAFenceWasReturned();
3125 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3126}
3127
3128TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3129 LayerFE::LayerSettings r1;
3130 LayerFE::LayerSettings r2;
3131
3132 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3133 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3134
3135 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3136 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3137 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003138 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003139 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3140 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3141 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3142 .WillRepeatedly(Return());
3143
3144 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3145 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3146 .WillOnce(Return(mOutputBuffer))
3147 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003148 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003149 .WillRepeatedly(Return(NO_ERROR));
3150
3151 verify().execute().expectAFenceWasReturned();
3152 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3153
3154 verify().execute().expectAFenceWasReturned();
3155 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3156}
3157
3158TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3159 LayerFE::LayerSettings r1;
3160 LayerFE::LayerSettings r2;
3161 LayerFE::LayerSettings r3;
3162
3163 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3164 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3165 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3166
3167 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3168 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3169 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003170 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003171 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3172 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3173 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3174 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3175 .WillRepeatedly(Return());
3176
3177 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003178 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003179 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003180 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003181 .WillOnce(Return(NO_ERROR));
3182
3183 verify().execute().expectAFenceWasReturned();
3184 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3185
3186 verify().execute().expectAFenceWasReturned();
3187 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3188}
3189
Lloyd Pique6818fa52019-12-03 12:32:13 -08003190struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3191 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3192 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003193 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003194 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003195 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003196 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3197 .WillRepeatedly(Return());
3198 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3199 }
3200
3201 struct MixedCompositionState
3202 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3203 auto ifMixedCompositionIs(bool used) {
3204 getInstance()->mOutput.mState.usesDeviceComposition = used;
3205 return nextState<OutputUsesHdrState>();
3206 }
3207 };
3208
3209 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3210 auto andIfUsesHdr(bool used) {
3211 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3212 .WillOnce(Return(used));
3213 return nextState<SkipColorTransformState>();
3214 }
3215 };
3216
3217 struct SkipColorTransformState
3218 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3219 auto andIfSkipColorTransform(bool skip) {
3220 // May be called zero or one times.
3221 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3222 .WillRepeatedly(Return(skip));
3223 return nextState<ExpectDisplaySettingsState>();
3224 }
3225 };
3226
3227 struct ExpectDisplaySettingsState
3228 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3229 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003230 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003231 .WillOnce(Return(NO_ERROR));
3232 return nextState<ExecuteState>();
3233 }
3234 };
3235
3236 // Call this member function to start using the mini-DSL defined above.
3237 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3238};
3239
3240TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3241 verify().ifMixedCompositionIs(true)
3242 .andIfUsesHdr(true)
3243 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003244 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003245 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003246 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003247 .execute()
3248 .expectAFenceWasReturned();
3249}
3250
3251TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3252 verify().ifMixedCompositionIs(true)
3253 .andIfUsesHdr(false)
3254 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003255 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003256 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003257 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003258 .execute()
3259 .expectAFenceWasReturned();
3260}
3261
3262TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3263 verify().ifMixedCompositionIs(false)
3264 .andIfUsesHdr(true)
3265 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003266 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003267 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003268 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003269 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003270 .execute()
3271 .expectAFenceWasReturned();
3272}
3273
3274TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3275 verify().ifMixedCompositionIs(false)
3276 .andIfUsesHdr(false)
3277 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003278 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003279 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003280 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003281 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003282 .execute()
3283 .expectAFenceWasReturned();
3284}
3285
3286TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3287 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3288 verify().ifMixedCompositionIs(false)
3289 .andIfUsesHdr(true)
3290 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003291 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003292 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003293 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003294 .execute()
3295 .expectAFenceWasReturned();
3296}
3297
3298struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3299 struct Layer {
3300 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003301 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3302 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003303 }
3304
3305 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003306 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003307 LayerFECompositionState mLayerFEState;
3308 };
3309
3310 OutputComposeSurfacesTest_HandlesProtectedContent() {
3311 mLayer1.mLayerFEState.hasProtectedContent = false;
3312 mLayer2.mLayerFEState.hasProtectedContent = false;
3313
3314 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3315 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3316 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3317 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3318 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3319
3320 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3321
3322 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3323
3324 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003325 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003326 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3327 .WillRepeatedly(Return());
3328 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003329 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003330 .WillRepeatedly(Return(NO_ERROR));
3331 }
3332
3333 Layer mLayer1;
3334 Layer mLayer2;
3335};
3336
3337TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3338 mOutput.mState.isSecure = false;
3339 mLayer2.mLayerFEState.hasProtectedContent = true;
3340 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003341 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3342 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003343
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003344 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003345}
3346
3347TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3348 mOutput.mState.isSecure = true;
3349 mLayer2.mLayerFEState.hasProtectedContent = true;
3350 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3351
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003352 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353}
3354
3355TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3356 mOutput.mState.isSecure = true;
3357 mLayer2.mLayerFEState.hasProtectedContent = false;
3358 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3359 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3360 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3361 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3362 EXPECT_CALL(*mRenderSurface, setProtected(false));
3363
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003364 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003365}
3366
3367TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3368 mOutput.mState.isSecure = true;
3369 mLayer2.mLayerFEState.hasProtectedContent = true;
3370 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3371
3372 // For this test, we also check the call order of key functions.
3373 InSequence seq;
3374
3375 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3376 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3377 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3378 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3379 EXPECT_CALL(*mRenderSurface, setProtected(true));
3380 // Must happen after setting the protected content state.
3381 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003382 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003384 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003385}
3386
3387TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3388 mOutput.mState.isSecure = true;
3389 mLayer2.mLayerFEState.hasProtectedContent = true;
3390 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3391 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3392 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3393
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003394 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003395}
3396
3397TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3398 mOutput.mState.isSecure = true;
3399 mLayer2.mLayerFEState.hasProtectedContent = true;
3400 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3401 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3402 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3403 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3404
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003405 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406}
3407
3408TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3409 mOutput.mState.isSecure = true;
3410 mLayer2.mLayerFEState.hasProtectedContent = true;
3411 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3412 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3413 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3414 EXPECT_CALL(*mRenderSurface, setProtected(true));
3415
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003416 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003417}
3418
3419TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3420 mOutput.mState.isSecure = true;
3421 mLayer2.mLayerFEState.hasProtectedContent = true;
3422 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3423 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3424 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3425 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3426
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003427 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428}
3429
3430struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3431 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3432 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3433 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3434 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003435 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003436 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3437 .WillRepeatedly(Return());
3438 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3439 }
3440};
3441
3442TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3443 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3444
3445 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003446 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447
3448 // For this test, we also check the call order of key functions.
3449 InSequence seq;
3450
3451 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003452 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003454 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3455}
3456
3457struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3458 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3459 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3460 mLayer.layerFEState.backgroundBlurRadius = 10;
3461 mOutput.editState().isEnabled = true;
3462
Snild Dolkow9e217d62020-04-22 15:53:42 +02003463 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003464 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3465 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3466 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003467 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003468 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3469 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3470 .WillRepeatedly(Return(&mLayer.outputLayer));
3471 }
3472
3473 NonInjectedLayer mLayer;
3474 compositionengine::CompositionRefreshArgs mRefreshArgs;
3475};
3476
3477TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3478 mRefreshArgs.blursAreExpensive = true;
3479 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3480
3481 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3482 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3483}
3484
3485TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3486 mRefreshArgs.blursAreExpensive = false;
3487 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3488
3489 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3490 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003491}
3492
3493/*
3494 * Output::generateClientCompositionRequests()
3495 */
3496
3497struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003498 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003499 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003500 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003501 bool supportsProtectedContent, Region& clearRegion,
3502 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003503 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003504 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003505 }
3506 };
3507
Lloyd Piquea4863342019-12-04 18:45:02 -08003508 struct Layer {
3509 Layer() {
3510 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3511 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003512 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003513 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003514 }
3515
3516 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003517 StrictMock<mock::LayerFE> mLayerFE;
3518 LayerFECompositionState mLayerFEState;
3519 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003520 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003521 };
3522
Lloyd Pique56eba802019-08-28 15:45:25 -07003523 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003524 mOutput.mState.needsFiltering = false;
3525
Lloyd Pique56eba802019-08-28 15:45:25 -07003526 mOutput.setDisplayColorProfileForTest(
3527 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3528 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3529 }
3530
Lloyd Pique56eba802019-08-28 15:45:25 -07003531 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3532 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003533 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003534};
3535
Lloyd Piquea4863342019-12-04 18:45:02 -08003536struct GenerateClientCompositionRequestsTest_ThreeLayers
3537 : public GenerateClientCompositionRequestsTest {
3538 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003539 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3540 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3541 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003542 mOutput.mState.transform =
3543 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3544 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003545 mOutput.mState.needsFiltering = false;
3546 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003547
Lloyd Piquea4863342019-12-04 18:45:02 -08003548 for (size_t i = 0; i < mLayers.size(); i++) {
3549 mLayers[i].mOutputLayerState.clearClientTarget = false;
3550 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3551 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003552 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003553 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003554 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3555 mLayers[i].mLayerSettings.alpha = 1.0f;
3556 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003557
Lloyd Piquea4863342019-12-04 18:45:02 -08003558 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3559 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3560 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3561 .WillRepeatedly(Return(true));
3562 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3563 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003564
Lloyd Piquea4863342019-12-04 18:45:02 -08003565 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3566 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003567
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003568 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003569 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003570
Lloyd Piquea4863342019-12-04 18:45:02 -08003571 static const Rect kDisplayFrame;
3572 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003573 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003574
Lloyd Piquea4863342019-12-04 18:45:02 -08003575 std::array<Layer, 3> mLayers;
3576};
Lloyd Pique56eba802019-08-28 15:45:25 -07003577
Lloyd Piquea4863342019-12-04 18:45:02 -08003578const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3579const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003580const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3581 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003582
Lloyd Piquea4863342019-12-04 18:45:02 -08003583TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3584 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3585 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3586 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003587
Lloyd Piquea4863342019-12-04 18:45:02 -08003588 Region accumClearRegion(Rect(10, 11, 12, 13));
3589 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3590 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003591 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003592 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003593}
3594
Lloyd Piquea4863342019-12-04 18:45:02 -08003595TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3596 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3597 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3598 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3599
3600 Region accumClearRegion(Rect(10, 11, 12, 13));
3601 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3602 accumClearRegion, kDisplayDataspace);
3603 EXPECT_EQ(0u, requests.size());
3604 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3605}
3606
3607TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003608 LayerFE::LayerSettings mShadowSettings;
3609 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003610
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003611 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3612 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3613 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3614 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3615 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3616 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3617 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003618
3619 Region accumClearRegion(Rect(10, 11, 12, 13));
3620 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3621 accumClearRegion, kDisplayDataspace);
3622 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003623 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3624 EXPECT_EQ(mShadowSettings, requests[1]);
3625 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003626
3627 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3628
3629 // Check that a timestamp was set for the layers that generated requests
3630 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3631 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3632 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3633}
3634
3635TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3636 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3637 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3638 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3639 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3640
3641 mLayers[0].mOutputLayerState.clearClientTarget = false;
3642 mLayers[1].mOutputLayerState.clearClientTarget = false;
3643 mLayers[2].mOutputLayerState.clearClientTarget = false;
3644
3645 mLayers[0].mLayerFEState.isOpaque = true;
3646 mLayers[1].mLayerFEState.isOpaque = true;
3647 mLayers[2].mLayerFEState.isOpaque = true;
3648
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003649 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3650 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003651
3652 Region accumClearRegion(Rect(10, 11, 12, 13));
3653 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3654 accumClearRegion, kDisplayDataspace);
3655 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003656 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003657
3658 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3659}
3660
3661TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3662 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3663 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3664 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3665 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3666
3667 mLayers[0].mOutputLayerState.clearClientTarget = true;
3668 mLayers[1].mOutputLayerState.clearClientTarget = true;
3669 mLayers[2].mOutputLayerState.clearClientTarget = true;
3670
3671 mLayers[0].mLayerFEState.isOpaque = false;
3672 mLayers[1].mLayerFEState.isOpaque = false;
3673 mLayers[2].mLayerFEState.isOpaque = false;
3674
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003675 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3676 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003677
3678 Region accumClearRegion(Rect(10, 11, 12, 13));
3679 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3680 accumClearRegion, kDisplayDataspace);
3681 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003682 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003683
3684 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3685}
3686
3687TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003688 // If client composition is performed with some layers set to use device
3689 // composition, device layers after the first layer (device or client) will
3690 // clear the frame buffer if they are opaque and if that layer has a flag
3691 // set to do so. The first layer is skipped as the frame buffer is already
3692 // expected to be clear.
3693
Lloyd Piquea4863342019-12-04 18:45:02 -08003694 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3695 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3696 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003697
Lloyd Piquea4863342019-12-04 18:45:02 -08003698 mLayers[0].mOutputLayerState.clearClientTarget = true;
3699 mLayers[1].mOutputLayerState.clearClientTarget = true;
3700 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003701
Lloyd Piquea4863342019-12-04 18:45:02 -08003702 mLayers[0].mLayerFEState.isOpaque = true;
3703 mLayers[1].mLayerFEState.isOpaque = true;
3704 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003705 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003706 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003707
3708 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3709 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003710 false, /* needs filtering */
3711 false, /* secure */
3712 false, /* supports protected content */
3713 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003714 kDisplayViewport,
3715 kDisplayDataspace,
3716 false /* realContentIsVisible */,
3717 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003718 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003719 };
3720 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3721 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003722 false, /* needs filtering */
3723 false, /* secure */
3724 false, /* supports protected content */
3725 accumClearRegion,
3726 kDisplayViewport,
3727 kDisplayDataspace,
3728 true /* realContentIsVisible */,
3729 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003730 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003731 };
3732
3733 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3734 mBlackoutSettings.source.buffer.buffer = nullptr;
3735 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3736 mBlackoutSettings.alpha = 0.f;
3737 mBlackoutSettings.disableBlending = true;
3738
3739 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3740 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3741 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3742 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3743
Lloyd Piquea4863342019-12-04 18:45:02 -08003744 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3745 accumClearRegion, kDisplayDataspace);
3746 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003747
Lloyd Piquea4863342019-12-04 18:45:02 -08003748 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003749 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003750
Vishnu Nair9b079a22020-01-21 14:36:08 -08003751 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003752
Lloyd Piquea4863342019-12-04 18:45:02 -08003753 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3754}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003755
Lloyd Piquea4863342019-12-04 18:45:02 -08003756TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3757 clippedVisibleRegionUsedToGenerateRequest) {
3758 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3759 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3760 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003761
Lloyd Piquea4863342019-12-04 18:45:02 -08003762 Region accumClearRegion(Rect(10, 11, 12, 13));
3763
3764 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3765 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003766 false, /* needs filtering */
3767 false, /* secure */
3768 false, /* supports protected content */
3769 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003770 kDisplayViewport,
3771 kDisplayDataspace,
3772 true /* realContentIsVisible */,
3773 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003774 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003775 };
3776 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3777 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003778 false, /* needs filtering */
3779 false, /* secure */
3780 false, /* supports protected content */
3781 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003782 kDisplayViewport,
3783 kDisplayDataspace,
3784 true /* realContentIsVisible */,
3785 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003786 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003787 };
3788 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3789 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003790 false, /* needs filtering */
3791 false, /* secure */
3792 false, /* supports protected content */
3793 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003794 kDisplayViewport,
3795 kDisplayDataspace,
3796 true /* realContentIsVisible */,
3797 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003798 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003799 };
3800
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003801 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3802 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3803 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3804 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3805 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3806 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003807
3808 static_cast<void>(
3809 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3810 accumClearRegion, kDisplayDataspace));
3811}
3812
3813TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3814 perLayerNeedsFilteringUsedToGenerateRequests) {
3815 mOutput.mState.needsFiltering = false;
3816 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3817
3818 Region accumClearRegion(Rect(10, 11, 12, 13));
3819
3820 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3821 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003822 true, /* needs filtering */
3823 false, /* secure */
3824 false, /* supports protected content */
3825 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003826 kDisplayViewport,
3827 kDisplayDataspace,
3828 true /* realContentIsVisible */,
3829 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003830 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 };
3832 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3833 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003834 false, /* needs filtering */
3835 false, /* secure */
3836 false, /* supports protected content */
3837 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003838 kDisplayViewport,
3839 kDisplayDataspace,
3840 true /* realContentIsVisible */,
3841 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003842 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003843 };
3844 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3845 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003846 false, /* needs filtering */
3847 false, /* secure */
3848 false, /* supports protected content */
3849 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003850 kDisplayViewport,
3851 kDisplayDataspace,
3852 true /* realContentIsVisible */,
3853 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003854 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003855 };
3856
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003857 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3858 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3859 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3860 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3861 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3862 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003863
3864 static_cast<void>(
3865 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3866 accumClearRegion, kDisplayDataspace));
3867}
3868
3869TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3870 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3871 mOutput.mState.needsFiltering = true;
3872 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3873
3874 Region accumClearRegion(Rect(10, 11, 12, 13));
3875
3876 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3877 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003878 true, /* needs filtering */
3879 false, /* secure */
3880 false, /* supports protected content */
3881 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003882 kDisplayViewport,
3883 kDisplayDataspace,
3884 true /* realContentIsVisible */,
3885 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003886 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003887
Lloyd Piquea4863342019-12-04 18:45:02 -08003888 };
3889 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3890 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003891 true, /* needs filtering */
3892 false, /* secure */
3893 false, /* supports protected content */
3894 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003895 kDisplayViewport,
3896 kDisplayDataspace,
3897 true /* realContentIsVisible */,
3898 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003899 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003900 };
3901 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3902 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003903 true, /* needs filtering */
3904 false, /* secure */
3905 false, /* supports protected content */
3906 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003907 kDisplayViewport,
3908 kDisplayDataspace,
3909 true /* realContentIsVisible */,
3910 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003911 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003912 };
3913
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003914 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3915 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3916 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3918 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3919 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003920
3921 static_cast<void>(
3922 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3923 accumClearRegion, kDisplayDataspace));
3924}
3925
3926TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3927 wholeOutputSecurityUsedToGenerateRequests) {
3928 mOutput.mState.isSecure = true;
3929
3930 Region accumClearRegion(Rect(10, 11, 12, 13));
3931
3932 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3933 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003934 false, /* needs filtering */
3935 true, /* secure */
3936 false, /* supports protected content */
3937 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003938 kDisplayViewport,
3939 kDisplayDataspace,
3940 true /* realContentIsVisible */,
3941 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003942 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003943 };
3944 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3945 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003946 false, /* needs filtering */
3947 true, /* secure */
3948 false, /* supports protected content */
3949 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003950 kDisplayViewport,
3951 kDisplayDataspace,
3952 true /* realContentIsVisible */,
3953 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003954 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 };
3956 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3957 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003958 false, /* needs filtering */
3959 true, /* secure */
3960 false, /* supports protected content */
3961 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003962 kDisplayViewport,
3963 kDisplayDataspace,
3964 true /* realContentIsVisible */,
3965 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003966 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003967 };
3968
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003969 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3970 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3971 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3972 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3973 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3974 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003975
3976 static_cast<void>(
3977 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3978 accumClearRegion, kDisplayDataspace));
3979}
3980
3981TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3982 protectedContentSupportUsedToGenerateRequests) {
3983 Region accumClearRegion(Rect(10, 11, 12, 13));
3984
3985 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3986 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003987 false, /* needs filtering */
3988 false, /* secure */
3989 true, /* supports protected content */
3990 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 kDisplayViewport,
3992 kDisplayDataspace,
3993 true /* realContentIsVisible */,
3994 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003995 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003996 };
3997 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3998 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 false, /* needs filtering */
4000 false, /* secure */
4001 true, /* supports protected content */
4002 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004003 kDisplayViewport,
4004 kDisplayDataspace,
4005 true /* realContentIsVisible */,
4006 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004007 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004008 };
4009 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4010 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 false, /* needs filtering */
4012 false, /* secure */
4013 true, /* supports protected content */
4014 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015 kDisplayViewport,
4016 kDisplayDataspace,
4017 true /* realContentIsVisible */,
4018 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004019 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004020 };
4021
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004022 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
4023 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4024 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
4025 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4026 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
4027 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004028
4029 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4030 accumClearRegion,
4031 kDisplayDataspace));
4032}
4033
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004034TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004035 InjectedLayer layer1;
4036 InjectedLayer layer2;
4037 InjectedLayer layer3;
4038
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004039 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004040 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004041 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004042 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004043 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004044 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004045 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004046
Lloyd Piquede196652020-01-22 17:29:58 -08004047 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004048
Lloyd Piquede196652020-01-22 17:29:58 -08004049 injectOutputLayer(layer1);
4050 injectOutputLayer(layer2);
4051 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004052
4053 mOutput->editState().isEnabled = true;
4054
4055 CompositionRefreshArgs args;
4056 args.updatingGeometryThisFrame = false;
4057 args.devOptForceClientComposition = false;
4058 mOutput->updateAndWriteCompositionState(args);
4059}
4060
Lucas Dupinc3800b82020-10-02 16:24:48 -07004061TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4062 InjectedLayer layer1;
4063 InjectedLayer layer2;
4064 InjectedLayer layer3;
4065
4066 // Layer requesting blur, or below, should request client composition.
4067 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4068 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
4069 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4070 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
4071 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4072 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
4073
4074 BlurRegion region;
4075 layer2.layerFEState.blurRegions.push_back(region);
4076
4077 injectOutputLayer(layer1);
4078 injectOutputLayer(layer2);
4079 injectOutputLayer(layer3);
4080
4081 mOutput->editState().isEnabled = true;
4082
4083 CompositionRefreshArgs args;
4084 args.updatingGeometryThisFrame = false;
4085 args.devOptForceClientComposition = false;
4086 mOutput->updateAndWriteCompositionState(args);
4087}
4088
Lloyd Piquea4863342019-12-04 18:45:02 -08004089TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4090 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4091 // one layer on the left covering the left side of the output, and one layer
4092 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004093
4094 const Rect kPortraitFrame(0, 0, 1000, 2000);
4095 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004096 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004097 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004098 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004099
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004100 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4101 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4102 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004103 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4104 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004105 mOutput.mState.needsFiltering = false;
4106 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004107
Lloyd Piquea4863342019-12-04 18:45:02 -08004108 Layer leftLayer;
4109 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004110
Lloyd Piquea4863342019-12-04 18:45:02 -08004111 leftLayer.mOutputLayerState.clearClientTarget = false;
4112 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4113 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004114 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004115
Lloyd Piquea4863342019-12-04 18:45:02 -08004116 rightLayer.mOutputLayerState.clearClientTarget = false;
4117 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4118 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004119 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004120
4121 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4122 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4123 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4124 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4125 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4126
4127 Region accumClearRegion(Rect(10, 11, 12, 13));
4128
4129 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4130 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004131 false, /* needs filtering */
4132 true, /* secure */
4133 true, /* supports protected content */
4134 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004135 kPortraitViewport,
4136 kOutputDataspace,
4137 true /* realContentIsVisible */,
4138 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004139 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004140 };
4141
4142 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4143 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4145 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004146
4147 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4148 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004149 false, /* needs filtering */
4150 true, /* secure */
4151 true, /* supports protected content */
4152 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004153 kPortraitViewport,
4154 kOutputDataspace,
4155 true /* realContentIsVisible */,
4156 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004157 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004158 };
4159
4160 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4161 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004162 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4163 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004164
4165 constexpr bool supportsProtectedContent = true;
4166 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4167 accumClearRegion, kOutputDataspace);
4168 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004169 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4170 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004171}
4172
Vishnu Naira483b4a2019-12-12 15:07:52 -08004173TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4174 shadowRegionOnlyVisibleSkipsContentComposition) {
4175 const Rect kContentWithShadow(40, 40, 70, 90);
4176 const Rect kContent(50, 50, 60, 80);
4177 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4178 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4179
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004180 Region accumClearRegion(Rect(10, 11, 12, 13));
4181 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4182 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004183 false, /* needs filtering */
4184 false, /* secure */
4185 false, /* supports protected content */
4186 accumClearRegion,
4187 kDisplayViewport,
4188 kDisplayDataspace,
4189 false /* realContentIsVisible */,
4190 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004191 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004192 };
4193
Vishnu Nair9b079a22020-01-21 14:36:08 -08004194 LayerFE::LayerSettings mShadowSettings;
4195 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004196
4197 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4198 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4199
4200 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4201 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004202 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4203 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004204
Vishnu Naira483b4a2019-12-12 15:07:52 -08004205 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4206 accumClearRegion, kDisplayDataspace);
4207 ASSERT_EQ(1u, requests.size());
4208
Vishnu Nair9b079a22020-01-21 14:36:08 -08004209 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004210}
4211
4212TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4213 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4214 const Rect kContentWithShadow(40, 40, 70, 90);
4215 const Rect kContent(50, 50, 60, 80);
4216 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4217 const Region kPartialContentWithPartialShadowRegion =
4218 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4219
Vishnu Nair9b079a22020-01-21 14:36:08 -08004220 LayerFE::LayerSettings mShadowSettings;
4221 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004222
4223 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4224 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4225
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004226 Region accumClearRegion(Rect(10, 11, 12, 13));
4227 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4228 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004229 false, /* needs filtering */
4230 false, /* secure */
4231 false, /* supports protected content */
4232 accumClearRegion,
4233 kDisplayViewport,
4234 kDisplayDataspace,
4235 true /* realContentIsVisible */,
4236 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004237 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004238 };
4239
Vishnu Naira483b4a2019-12-12 15:07:52 -08004240 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4241 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004242 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4243 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4244 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004245
Vishnu Naira483b4a2019-12-12 15:07:52 -08004246 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4247 accumClearRegion, kDisplayDataspace);
4248 ASSERT_EQ(2u, requests.size());
4249
Vishnu Nair9b079a22020-01-21 14:36:08 -08004250 EXPECT_EQ(mShadowSettings, requests[0]);
4251 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004252}
4253
Lloyd Pique32cbe282018-10-19 13:09:22 -07004254} // namespace
4255} // namespace android::compositionengine