blob: 1452192785677c8a9c26fef7f97cf95b49770e1f [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);
341 EXPECT_EQ(Rect(0, 0, 900, 450), state.orientedDisplaySpace.content);
342 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200343
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200344 EXPECT_EQ(displayRect, state.displaySpace.bounds);
345 EXPECT_EQ(Rect(0, 0, 450, 900), state.displaySpace.content);
346 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200347
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200348 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
349 EXPECT_EQ(Rect(0, 0, 450, 900), state.framebufferSpace.content);
350 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
351
352 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
353
354 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700355}
356
Lloyd Pique66d68602019-02-13 14:23:31 -0800357/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700358 * Output::setLayerStackFilter()
359 */
360
361TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700362 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700363 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700364
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700365 EXPECT_TRUE(mOutput->getState().layerStackInternal);
366 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700367
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700368 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700369}
370
Lloyd Pique66d68602019-02-13 14:23:31 -0800371/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372 * Output::setColorTransform
373 */
374
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800375TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700376 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700377
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800378 // If no colorTransformMatrix is set the update should be skipped.
379 CompositionRefreshArgs refreshArgs;
380 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700381
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700382 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700383
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800384 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700385 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800386
387 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700388 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800389}
Lloyd Piqueef958122019-02-05 18:00:12 -0800390
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800391TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700392 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800394 // Attempting to set the same colorTransformMatrix that is already set should
395 // also skip the update.
396 CompositionRefreshArgs refreshArgs;
397 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700398
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700399 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700400
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800401 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700402 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800403
404 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700405 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800406}
407
408TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700409 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800410
411 // Setting a different colorTransformMatrix should perform the update.
412 CompositionRefreshArgs refreshArgs;
413 refreshArgs.colorTransformMatrix = kIdentity;
414
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700415 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800416
417 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700418 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800419
420 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700421 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800422}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700423
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800424TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700425 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700426
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800427 // Setting a different colorTransformMatrix should perform the update.
428 CompositionRefreshArgs refreshArgs;
429 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700430
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700431 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800432
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800433 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435
436 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700437 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800438}
439
440TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800442
443 // Setting a different colorTransformMatrix should perform the update.
444 CompositionRefreshArgs refreshArgs;
445 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
446
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800448
449 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451
452 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700454}
455
Lloyd Pique66d68602019-02-13 14:23:31 -0800456/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800457 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458 */
459
Lloyd Pique17ca7422019-11-14 14:24:10 -0800460using OutputSetColorProfileTest = OutputTest;
461
462TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800463 using ColorProfile = Output::ColorProfile;
464
Lloyd Piquef5275482019-01-29 18:42:42 -0800465 EXPECT_CALL(*mDisplayColorProfile,
466 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
467 ui::Dataspace::UNKNOWN))
468 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800469 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700470
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
472 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
473 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700474
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700475 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
476 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
477 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
478 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800479
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800481}
482
Lloyd Pique17ca7422019-11-14 14:24:10 -0800483TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800484 using ColorProfile = Output::ColorProfile;
485
Lloyd Piquef5275482019-01-29 18:42:42 -0800486 EXPECT_CALL(*mDisplayColorProfile,
487 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
488 ui::Dataspace::UNKNOWN))
489 .WillOnce(Return(ui::Dataspace::UNKNOWN));
490
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700491 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
492 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
493 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
494 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
497 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
498 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800499
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700501}
502
Lloyd Pique66d68602019-02-13 14:23:31 -0800503/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700504 * Output::setRenderSurface()
505 */
506
507TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
508 const ui::Size newDisplaySize{640, 480};
509
510 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
511 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
512
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700513 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700514
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200515 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700516}
517
Lloyd Pique66d68602019-02-13 14:23:31 -0800518/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000519 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700520 */
521
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000522TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
523 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200524 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700526
527 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700529
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000530 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700531 }
532}
533
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000534TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
535 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200536 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700538
539 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700540 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700541
542 // The dirtyRegion should be clipped to the display bounds.
543 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
544 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700545}
546
Lloyd Pique66d68602019-02-13 14:23:31 -0800547/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800548 * Output::belongsInOutput()
549 */
550
551TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
552 const uint32_t layerStack1 = 123u;
553 const uint32_t layerStack2 = 456u;
554
555 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700556 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800557
Lloyd Piquec6687342019-03-07 21:34:57 -0800558 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
560 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800561
Lloyd Piqueef36b002019-01-23 17:52:04 -0800562 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700563 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
564 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
565 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
566 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800567
568 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700569 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800570
571 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700572 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
573 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
574 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
575 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800576}
577
Lloyd Piquede196652020-01-22 17:29:58 -0800578TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
579 NonInjectedLayer layer;
580 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800581
Lloyd Piquede196652020-01-22 17:29:58 -0800582 // If the layer has no composition state, it does not belong to any output.
583 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
584 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
585}
586
587TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
588 NonInjectedLayer layer;
589 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800590
591 const uint32_t layerStack1 = 123u;
592 const uint32_t layerStack2 = 456u;
593
594 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700595 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800596
Lloyd Pique66c20c42019-03-07 21:44:02 -0800597 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800598 layer.layerFEState.layerStackId = std::nullopt;
599 layer.layerFEState.internalOnly = false;
600 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800601
Lloyd Piquede196652020-01-22 17:29:58 -0800602 layer.layerFEState.layerStackId = std::nullopt;
603 layer.layerFEState.internalOnly = true;
604 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800605
606 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800607 layer.layerFEState.layerStackId = layerStack1;
608 layer.layerFEState.internalOnly = false;
609 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800610
Lloyd Piquede196652020-01-22 17:29:58 -0800611 layer.layerFEState.layerStackId = layerStack1;
612 layer.layerFEState.internalOnly = true;
613 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800614
Lloyd Piquede196652020-01-22 17:29:58 -0800615 layer.layerFEState.layerStackId = layerStack2;
616 layer.layerFEState.internalOnly = true;
617 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800618
Lloyd Piquede196652020-01-22 17:29:58 -0800619 layer.layerFEState.layerStackId = layerStack2;
620 layer.layerFEState.internalOnly = false;
621 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800622
623 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700624 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800625
Lloyd Pique66c20c42019-03-07 21:44:02 -0800626 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800627 layer.layerFEState.layerStackId = layerStack1;
628 layer.layerFEState.internalOnly = false;
629 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800630
Lloyd Piquede196652020-01-22 17:29:58 -0800631 layer.layerFEState.layerStackId = layerStack1;
632 layer.layerFEState.internalOnly = true;
633 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800634
Lloyd Piquede196652020-01-22 17:29:58 -0800635 layer.layerFEState.layerStackId = layerStack2;
636 layer.layerFEState.internalOnly = true;
637 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Lloyd Piquede196652020-01-22 17:29:58 -0800639 layer.layerFEState.layerStackId = layerStack2;
640 layer.layerFEState.internalOnly = false;
641 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800642}
643
Lloyd Pique66d68602019-02-13 14:23:31 -0800644/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800645 * Output::getOutputLayerForLayer()
646 */
647
648TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800649 InjectedLayer layer1;
650 InjectedLayer layer2;
651 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800652
Lloyd Piquede196652020-01-22 17:29:58 -0800653 injectOutputLayer(layer1);
654 injectNullOutputLayer();
655 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800656
657 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800658 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
659 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800660
661 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800662 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
663 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
664 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800665
666 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800667 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
668 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
669 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800670}
671
Lloyd Pique66d68602019-02-13 14:23:31 -0800672/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800673 * Output::setReleasedLayers()
674 */
675
676using OutputSetReleasedLayersTest = OutputTest;
677
678TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
679 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
680 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
681 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
682
683 Output::ReleasedLayers layers;
684 layers.push_back(layer1FE);
685 layers.push_back(layer2FE);
686 layers.push_back(layer3FE);
687
688 mOutput->setReleasedLayers(std::move(layers));
689
690 const auto& setLayers = mOutput->getReleasedLayersForTest();
691 ASSERT_EQ(3u, setLayers.size());
692 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
693 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
694 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
695}
696
697/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800698 * Output::updateLayerStateFromFE()
699 */
700
Lloyd Piquede196652020-01-22 17:29:58 -0800701using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800702
703TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
704 CompositionRefreshArgs refreshArgs;
705
706 mOutput->updateLayerStateFromFE(refreshArgs);
707}
708
Lloyd Piquede196652020-01-22 17:29:58 -0800709TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
710 InjectedLayer layer1;
711 InjectedLayer layer2;
712 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800713
Lloyd Piquede196652020-01-22 17:29:58 -0800714 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
715 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
716 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
717
718 injectOutputLayer(layer1);
719 injectOutputLayer(layer2);
720 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800721
722 CompositionRefreshArgs refreshArgs;
723 refreshArgs.updatingGeometryThisFrame = false;
724
725 mOutput->updateLayerStateFromFE(refreshArgs);
726}
727
Lloyd Piquede196652020-01-22 17:29:58 -0800728TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
729 InjectedLayer layer1;
730 InjectedLayer layer2;
731 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800732
Lloyd Piquede196652020-01-22 17:29:58 -0800733 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
734 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
735 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
736
737 injectOutputLayer(layer1);
738 injectOutputLayer(layer2);
739 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800740
741 CompositionRefreshArgs refreshArgs;
742 refreshArgs.updatingGeometryThisFrame = true;
743
744 mOutput->updateLayerStateFromFE(refreshArgs);
745}
746
747/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800748 * Output::updateAndWriteCompositionState()
749 */
750
Lloyd Piquede196652020-01-22 17:29:58 -0800751using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800752
753TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
754 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800755
756 CompositionRefreshArgs args;
757 mOutput->updateAndWriteCompositionState(args);
758}
759
Lloyd Piqueef63b612019-11-14 13:19:56 -0800760TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800761 InjectedLayer layer1;
762 InjectedLayer layer2;
763 InjectedLayer layer3;
764
Lloyd Piqueef63b612019-11-14 13:19:56 -0800765 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800766
Lloyd Piquede196652020-01-22 17:29:58 -0800767 injectOutputLayer(layer1);
768 injectOutputLayer(layer2);
769 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800770
771 CompositionRefreshArgs args;
772 mOutput->updateAndWriteCompositionState(args);
773}
774
775TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800779
Snild Dolkow9e217d62020-04-22 15:53:42 +0200780 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800781 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200782 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800783 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200784 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800785 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
786
787 injectOutputLayer(layer1);
788 injectOutputLayer(layer2);
789 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800790
791 mOutput->editState().isEnabled = true;
792
793 CompositionRefreshArgs args;
794 args.updatingGeometryThisFrame = false;
795 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200796 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800797 mOutput->updateAndWriteCompositionState(args);
798}
799
800TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800801 InjectedLayer layer1;
802 InjectedLayer layer2;
803 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800804
Snild Dolkow9e217d62020-04-22 15:53:42 +0200805 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800806 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200807 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800808 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200809 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800810 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
811
812 injectOutputLayer(layer1);
813 injectOutputLayer(layer2);
814 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800815
816 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800817
818 CompositionRefreshArgs args;
819 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820 args.devOptForceClientComposition = false;
821 mOutput->updateAndWriteCompositionState(args);
822}
823
824TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800825 InjectedLayer layer1;
826 InjectedLayer layer2;
827 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800828
Snild Dolkow9e217d62020-04-22 15:53:42 +0200829 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800830 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800832 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200833 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800834 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
835
836 injectOutputLayer(layer1);
837 injectOutputLayer(layer2);
838 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800839
840 mOutput->editState().isEnabled = true;
841
842 CompositionRefreshArgs args;
843 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800844 args.devOptForceClientComposition = true;
845 mOutput->updateAndWriteCompositionState(args);
846}
847
848/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800849 * Output::prepareFrame()
850 */
851
852struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800853 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800854 // Sets up the helper functions called by the function under test to use
855 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800856 MOCK_METHOD0(chooseCompositionStrategy, void());
857 };
858
859 OutputPrepareFrameTest() {
860 mOutput.setDisplayColorProfileForTest(
861 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
862 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
863 }
864
865 StrictMock<mock::CompositionEngine> mCompositionEngine;
866 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
867 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700868 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800869};
870
871TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
872 mOutput.editState().isEnabled = false;
873
874 mOutput.prepareFrame();
875}
876
877TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
878 mOutput.editState().isEnabled = true;
879 mOutput.editState().usesClientComposition = false;
880 mOutput.editState().usesDeviceComposition = true;
881
882 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
883 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
884
885 mOutput.prepareFrame();
886}
887
888// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
889// base chooseCompositionStrategy() is invoked.
890TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700891 mOutput->editState().isEnabled = true;
892 mOutput->editState().usesClientComposition = false;
893 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800894
895 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
896
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700897 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800898
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700899 EXPECT_TRUE(mOutput->getState().usesClientComposition);
900 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800901}
902
Lloyd Pique56eba802019-08-28 15:45:25 -0700903/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800904 * Output::prepare()
905 */
906
907struct OutputPrepareTest : public testing::Test {
908 struct OutputPartialMock : public OutputPartialMockBase {
909 // Sets up the helper functions called by the function under test to use
910 // mock implementations.
911 MOCK_METHOD2(rebuildLayerStacks,
912 void(const compositionengine::CompositionRefreshArgs&,
913 compositionengine::LayerFESet&));
914 };
915
916 StrictMock<OutputPartialMock> mOutput;
917 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800918 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800919};
920
921TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
922 InSequence seq;
923 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
924
925 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
926}
927
928/*
929 * Output::rebuildLayerStacks()
930 */
931
932struct OutputRebuildLayerStacksTest : public testing::Test {
933 struct OutputPartialMock : public OutputPartialMockBase {
934 // Sets up the helper functions called by the function under test to use
935 // mock implementations.
936 MOCK_METHOD2(collectVisibleLayers,
937 void(const compositionengine::CompositionRefreshArgs&,
938 compositionengine::Output::CoverageState&));
939 };
940
941 OutputRebuildLayerStacksTest() {
942 mOutput.mState.isEnabled = true;
943 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200944 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800945
946 mRefreshArgs.updatingOutputGeometryThisFrame = true;
947
948 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
949
950 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
951 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
952 }
953
954 void setTestCoverageValues(const CompositionRefreshArgs&,
955 compositionengine::Output::CoverageState& state) {
956 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
957 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
958 state.dirtyRegion = mCoverageDirtyRegionToSet;
959 }
960
961 static const ui::Transform kIdentityTransform;
962 static const ui::Transform kRotate90Transform;
963 static const Rect kOutputBounds;
964
965 StrictMock<OutputPartialMock> mOutput;
966 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800967 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800968 Region mCoverageAboveCoveredLayersToSet;
969 Region mCoverageAboveOpaqueLayersToSet;
970 Region mCoverageDirtyRegionToSet;
971};
972
973const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
974const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
975const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
976
977TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
978 mOutput.mState.isEnabled = false;
979
980 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
981}
982
983TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
984 mRefreshArgs.updatingOutputGeometryThisFrame = false;
985
986 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
987}
988
989TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
990 mOutput.mState.transform = kIdentityTransform;
991
992 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
993
994 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
995
996 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
997}
998
999TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1000 mOutput.mState.transform = kIdentityTransform;
1001
1002 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1003
1004 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1005
1006 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1007}
1008
1009TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1010 mOutput.mState.transform = kRotate90Transform;
1011
1012 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1013
1014 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1015
1016 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1017}
1018
1019TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1020 mOutput.mState.transform = kRotate90Transform;
1021
1022 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1023
1024 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1025
1026 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1027}
1028
1029TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1030 mOutput.mState.transform = kIdentityTransform;
1031 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1032
1033 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1034
1035 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1036
1037 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1038}
1039
1040TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1041 mOutput.mState.transform = kRotate90Transform;
1042 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1043
1044 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1045
1046 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1047
1048 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1049}
1050
1051/*
1052 * Output::collectVisibleLayers()
1053 */
1054
Lloyd Pique1ef93222019-11-21 16:41:53 -08001055struct OutputCollectVisibleLayersTest : public testing::Test {
1056 struct OutputPartialMock : public OutputPartialMockBase {
1057 // Sets up the helper functions called by the function under test to use
1058 // mock implementations.
1059 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001060 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001061 compositionengine::Output::CoverageState&));
1062 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1063 MOCK_METHOD0(finalizePendingOutputLayers, void());
1064 };
1065
1066 struct Layer {
1067 Layer() {
1068 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1069 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1070 }
1071
1072 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001073 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001074 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001075 };
1076
1077 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001078 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001079 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1080 .WillRepeatedly(Return(&mLayer1.outputLayer));
1081 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1082 .WillRepeatedly(Return(&mLayer2.outputLayer));
1083 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1084 .WillRepeatedly(Return(&mLayer3.outputLayer));
1085
Lloyd Piquede196652020-01-22 17:29:58 -08001086 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1087 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1088 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001089 }
1090
1091 StrictMock<OutputPartialMock> mOutput;
1092 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001093 LayerFESet mGeomSnapshots;
1094 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001095 Layer mLayer1;
1096 Layer mLayer2;
1097 Layer mLayer3;
1098};
1099
1100TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1101 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001102 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001103
1104 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1105 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1106
1107 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1108}
1109
1110TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1111 // Enforce a call order sequence for this test.
1112 InSequence seq;
1113
1114 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001115 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1116 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1117 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001118
1119 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1120 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1121
1122 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1123
1124 // Ensure all output layers have been assigned a simple/flattened z-order.
1125 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1126 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1127 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1128}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001129
1130/*
1131 * Output::ensureOutputLayerIfVisible()
1132 */
1133
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001134struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1135 struct OutputPartialMock : public OutputPartialMockBase {
1136 // Sets up the helper functions called by the function under test to use
1137 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001138 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001139 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001140 MOCK_METHOD2(ensureOutputLayer,
1141 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001142 };
1143
1144 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001145 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1146 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001147 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001148 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001149 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001150
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001151 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1152 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1154
Lloyd Piquede196652020-01-22 17:29:58 -08001155 mLayer.layerFEState.isVisible = true;
1156 mLayer.layerFEState.isOpaque = true;
1157 mLayer.layerFEState.contentDirty = true;
1158 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1159 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1160 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001161
Lloyd Piquede196652020-01-22 17:29:58 -08001162 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1163 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001164
Lloyd Piquede196652020-01-22 17:29:58 -08001165 mGeomSnapshots.insert(mLayer.layerFE);
1166 }
1167
1168 void ensureOutputLayerIfVisible() {
1169 sp<LayerFE> layerFE(mLayer.layerFE);
1170 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001171 }
1172
1173 static const Region kEmptyRegion;
1174 static const Region kFullBoundsNoRotation;
1175 static const Region kRightHalfBoundsNoRotation;
1176 static const Region kLowerHalfBoundsNoRotation;
1177 static const Region kFullBounds90Rotation;
1178
1179 StrictMock<OutputPartialMock> mOutput;
1180 LayerFESet mGeomSnapshots;
1181 Output::CoverageState mCoverageState{mGeomSnapshots};
1182
Lloyd Piquede196652020-01-22 17:29:58 -08001183 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184};
1185
1186const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1187const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1188 Region(Rect(0, 0, 100, 200));
1189const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1190 Region(Rect(0, 100, 100, 200));
1191const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1192 Region(Rect(50, 0, 100, 200));
1193const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1194 Region(Rect(0, 0, 200, 100));
1195
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001196TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001197 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1198 EXPECT_CALL(*mLayer.layerFE,
1199 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001200
1201 mGeomSnapshots.clear();
1202
Lloyd Piquede196652020-01-22 17:29:58 -08001203 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001204}
1205
1206TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1207 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001208 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001209
Lloyd Piquede196652020-01-22 17:29:58 -08001210 ensureOutputLayerIfVisible();
1211}
1212
1213TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1214 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1215
1216 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001217}
1218
1219TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001220 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001221
Lloyd Piquede196652020-01-22 17:29:58 -08001222 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001223}
1224
1225TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001226 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227
Lloyd Piquede196652020-01-22 17:29:58 -08001228 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229}
1230
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001231TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001232 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001233
Lloyd Piquede196652020-01-22 17:29:58 -08001234 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001235}
1236
1237TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1238 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001239 mLayer.layerFEState.isOpaque = true;
1240 mLayer.layerFEState.contentDirty = true;
1241 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001242
1243 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001244 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1245 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246
Lloyd Piquede196652020-01-22 17:29:58 -08001247 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001248
1249 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1250 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1251 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1252
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1254 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1255 RegionEq(kFullBoundsNoRotation));
1256 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1257 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258}
1259
1260TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1261 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001262 mLayer.layerFEState.isOpaque = true;
1263 mLayer.layerFEState.contentDirty = true;
1264 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265
Lloyd Piquede196652020-01-22 17:29:58 -08001266 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1267 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001268
Lloyd Piquede196652020-01-22 17:29:58 -08001269 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270
1271 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1272 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1273 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1276 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1277 RegionEq(kFullBoundsNoRotation));
1278 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1279 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280}
1281
1282TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1283 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001284 mLayer.layerFEState.isOpaque = false;
1285 mLayer.layerFEState.contentDirty = true;
1286 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001287
1288 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001289 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1290 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291
Lloyd Piquede196652020-01-22 17:29:58 -08001292 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001293
1294 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1295 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1296 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1297
Lloyd Piquede196652020-01-22 17:29:58 -08001298 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1299 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001300 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001301 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1302 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001303}
1304
1305TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1306 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001307 mLayer.layerFEState.isOpaque = false;
1308 mLayer.layerFEState.contentDirty = true;
1309 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310
Lloyd Piquede196652020-01-22 17:29:58 -08001311 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1312 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313
Lloyd Piquede196652020-01-22 17:29:58 -08001314 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315
1316 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1317 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1318 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1319
Lloyd Piquede196652020-01-22 17:29:58 -08001320 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1321 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001322 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001323 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1324 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001325}
1326
1327TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1328 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001329 mLayer.layerFEState.isOpaque = true;
1330 mLayer.layerFEState.contentDirty = false;
1331 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332
1333 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1335 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
Lloyd Piquede196652020-01-22 17:29:58 -08001337 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338
1339 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1340 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1341 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1344 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1345 RegionEq(kFullBoundsNoRotation));
1346 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1347 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1351 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001352 mLayer.layerFEState.isOpaque = true;
1353 mLayer.layerFEState.contentDirty = false;
1354 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1357 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360
1361 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1362 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1366 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1367 RegionEq(kFullBoundsNoRotation));
1368 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1369 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370}
1371
1372TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1373 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001374 mLayer.layerFEState.isOpaque = true;
1375 mLayer.layerFEState.contentDirty = true;
1376 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1377 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1378 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1379 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380
1381 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001382 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1383 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384
Lloyd Piquede196652020-01-22 17:29:58 -08001385 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001386
1387 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1390
Lloyd Piquede196652020-01-22 17:29:58 -08001391 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1392 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1393 RegionEq(kFullBoundsNoRotation));
1394 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1395 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001396}
1397
1398TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1399 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001400 mLayer.layerFEState.isOpaque = true;
1401 mLayer.layerFEState.contentDirty = true;
1402 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1403 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1404 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1405 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001406
Lloyd Piquede196652020-01-22 17:29:58 -08001407 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1408 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409
Lloyd Piquede196652020-01-22 17:29:58 -08001410 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001411
1412 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1413 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1414 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1415
Lloyd Piquede196652020-01-22 17:29:58 -08001416 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1417 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1418 RegionEq(kFullBoundsNoRotation));
1419 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1420 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001421}
1422
1423TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1424 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001425 mLayer.layerFEState.isOpaque = true;
1426 mLayer.layerFEState.contentDirty = true;
1427 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001429 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1431
1432 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001433 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1434 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
Lloyd Piquede196652020-01-22 17:29:58 -08001436 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437
1438 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1439 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1440 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1443 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1444 RegionEq(kFullBoundsNoRotation));
1445 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1446 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447}
1448
1449TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1450 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001451 mLayer.layerFEState.isOpaque = true;
1452 mLayer.layerFEState.contentDirty = true;
1453 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001454
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001455 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001456 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1457
Lloyd Piquede196652020-01-22 17:29:58 -08001458 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1459 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
Lloyd Piquede196652020-01-22 17:29:58 -08001461 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001462
1463 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1464 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1465 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1466
Lloyd Piquede196652020-01-22 17:29:58 -08001467 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1468 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1469 RegionEq(kFullBoundsNoRotation));
1470 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1471 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001472}
1473
1474TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1475 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1476 ui::Transform arbitraryTransform;
1477 arbitraryTransform.set(1, 1, -1, 1);
1478 arbitraryTransform.set(0, 100);
1479
Lloyd Piquede196652020-01-22 17:29:58 -08001480 mLayer.layerFEState.isOpaque = true;
1481 mLayer.layerFEState.contentDirty = true;
1482 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1483 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001484
1485 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001486 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1487 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
Lloyd Piquede196652020-01-22 17:29:58 -08001489 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490
1491 const Region kRegion = Region(Rect(0, 0, 300, 300));
1492 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1493
1494 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1495 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1496 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1497
Lloyd Piquede196652020-01-22 17:29:58 -08001498 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1499 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1500 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1501 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502}
1503
1504TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001505 mLayer.layerFEState.isOpaque = false;
1506 mLayer.layerFEState.contentDirty = true;
1507 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508
1509 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1510 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1511 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1514 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
1518 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1519 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1520 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1521 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1522 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1523 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1524
1525 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1526 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1527 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001532 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1533 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1534 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001536
Vishnu Naira483b4a2019-12-12 15:07:52 -08001537TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1538 ui::Transform translate;
1539 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001540 mLayer.layerFEState.geomLayerTransform = translate;
1541 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001542
1543 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1544 // half of the layer including the casting shadow is covered and opaque
1545 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1546 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1549 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001552
1553 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1554 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1555 // add starting opaque region to the opaque half of the casting layer bounds
1556 const Region kExpectedAboveOpaqueRegion =
1557 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1558 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1559 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1560 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1561 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1562 const Region kExpectedLayerShadowRegion =
1563 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1564
1565 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1566 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1567 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1568
Lloyd Piquede196652020-01-22 17:29:58 -08001569 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1570 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001571 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001572 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1573 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001574 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001575 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001576 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1577}
1578
1579TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1580 ui::Transform translate;
1581 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001582 mLayer.layerFEState.geomLayerTransform = translate;
1583 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001584
1585 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1586 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1587 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1588 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1591 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001592
Lloyd Piquede196652020-01-22 17:29:58 -08001593 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001594
1595 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1596 const Region kExpectedLayerShadowRegion =
1597 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1600 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001601 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1602}
1603
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001604TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001605 ui::Transform translate;
1606 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001607 mLayer.layerFEState.geomLayerTransform = translate;
1608 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001609
1610 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1611 // Casting layer and its shadows are covered by an opaque region
1612 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1613 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1614
Lloyd Piquede196652020-01-22 17:29:58 -08001615 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001616}
1617
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001618/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001619 * Output::present()
1620 */
1621
1622struct OutputPresentTest : public testing::Test {
1623 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001624 // Sets up the helper functions called by the function under test to use
1625 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001626 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1627 MOCK_METHOD1(updateAndWriteCompositionState,
1628 void(const compositionengine::CompositionRefreshArgs&));
1629 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1630 MOCK_METHOD0(beginFrame, void());
1631 MOCK_METHOD0(prepareFrame, void());
1632 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1633 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1634 MOCK_METHOD0(postFramebuffer, void());
1635 };
1636
1637 StrictMock<OutputPartialMock> mOutput;
1638};
1639
1640TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1641 CompositionRefreshArgs args;
1642
1643 InSequence seq;
1644 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1645 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1646 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1647 EXPECT_CALL(mOutput, beginFrame());
1648 EXPECT_CALL(mOutput, prepareFrame());
1649 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1650 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1651 EXPECT_CALL(mOutput, postFramebuffer());
1652
1653 mOutput.present(args);
1654}
1655
1656/*
1657 * Output::updateColorProfile()
1658 */
1659
Lloyd Pique17ca7422019-11-14 14:24:10 -08001660struct OutputUpdateColorProfileTest : public testing::Test {
1661 using TestType = OutputUpdateColorProfileTest;
1662
1663 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001664 // Sets up the helper functions called by the function under test to use
1665 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001666 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1667 };
1668
1669 struct Layer {
1670 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001671 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001672 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001673 }
1674
1675 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001676 StrictMock<mock::LayerFE> mLayerFE;
1677 LayerFECompositionState mLayerFEState;
1678 };
1679
1680 OutputUpdateColorProfileTest() {
1681 mOutput.setDisplayColorProfileForTest(
1682 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1683 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1684
1685 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1686 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1687 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1688 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1689 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1690 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1691 }
1692
1693 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1694 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1695 };
1696
1697 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1698 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1699 StrictMock<OutputPartialMock> mOutput;
1700
1701 Layer mLayer1;
1702 Layer mLayer2;
1703 Layer mLayer3;
1704
1705 CompositionRefreshArgs mRefreshArgs;
1706};
1707
1708// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1709// to make it easier to write unit tests.
1710
1711TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1712 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1713 // a simple default color profile without looking at anything else.
1714
Lloyd Pique0a456232020-01-16 17:51:13 -08001715 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001716 EXPECT_CALL(mOutput,
1717 setColorProfile(ColorProfileEq(
1718 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1719 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1720
1721 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1722 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1723
1724 mOutput.updateColorProfile(mRefreshArgs);
1725}
1726
1727struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1728 : public OutputUpdateColorProfileTest {
1729 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001730 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001731 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1732 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1733 }
1734
1735 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1736 : public CallOrderStateMachineHelper<
1737 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1738 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1739 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1740 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1741 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1742 _))
1743 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1744 SetArgPointee<4>(renderIntent)));
1745 EXPECT_CALL(getInstance()->mOutput,
1746 setColorProfile(
1747 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1748 ui::Dataspace::UNKNOWN})));
1749 return nextState<ExecuteState>();
1750 }
1751 };
1752
1753 // Call this member function to start using the mini-DSL defined above.
1754 [[nodiscard]] auto verify() {
1755 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1756 }
1757};
1758
1759TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1760 Native_Unknown_Colorimetric_Set) {
1761 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1762 ui::Dataspace::UNKNOWN,
1763 ui::RenderIntent::COLORIMETRIC)
1764 .execute();
1765}
1766
1767TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1768 DisplayP3_DisplayP3_Enhance_Set) {
1769 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1770 ui::Dataspace::DISPLAY_P3,
1771 ui::RenderIntent::ENHANCE)
1772 .execute();
1773}
1774
1775struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1776 : public OutputUpdateColorProfileTest {
1777 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001778 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001779 EXPECT_CALL(*mDisplayColorProfile,
1780 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1781 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1782 SetArgPointee<3>(ui::ColorMode::NATIVE),
1783 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1784 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1785 }
1786
1787 struct IfColorSpaceAgnosticDataspaceSetToState
1788 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1789 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1790 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1791 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1792 }
1793 };
1794
1795 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1796 : public CallOrderStateMachineHelper<
1797 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1798 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1799 ui::Dataspace dataspace) {
1800 EXPECT_CALL(getInstance()->mOutput,
1801 setColorProfile(ColorProfileEq(
1802 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1803 ui::RenderIntent::COLORIMETRIC, dataspace})));
1804 return nextState<ExecuteState>();
1805 }
1806 };
1807
1808 // Call this member function to start using the mini-DSL defined above.
1809 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1810};
1811
1812TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1813 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1814 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1815 .execute();
1816}
1817
1818TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1819 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1820 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1821 .execute();
1822}
1823
1824struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1825 : public OutputUpdateColorProfileTest {
1826 // Internally the implementation looks through the dataspaces of all the
1827 // visible layers. The topmost one that also has an actual dataspace
1828 // preference set is used to drive subsequent choices.
1829
1830 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1831 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1832 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1833
Lloyd Pique0a456232020-01-16 17:51:13 -08001834 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001835 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1836 }
1837
1838 struct IfTopLayerDataspaceState
1839 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1840 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1841 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1842 return nextState<AndIfMiddleLayerDataspaceState>();
1843 }
1844 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1845 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1846 }
1847 };
1848
1849 struct AndIfMiddleLayerDataspaceState
1850 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1851 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1852 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1853 return nextState<AndIfBottomLayerDataspaceState>();
1854 }
1855 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1856 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1857 }
1858 };
1859
1860 struct AndIfBottomLayerDataspaceState
1861 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1862 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1863 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1864 return nextState<ThenExpectBestColorModeCallUsesState>();
1865 }
1866 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1867 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1868 }
1869 };
1870
1871 struct ThenExpectBestColorModeCallUsesState
1872 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1873 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1874 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1875 getBestColorMode(dataspace, _, _, _, _));
1876 return nextState<ExecuteState>();
1877 }
1878 };
1879
1880 // Call this member function to start using the mini-DSL defined above.
1881 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1882};
1883
1884TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1885 noStrongLayerPrefenceUses_V0_SRGB) {
1886 // If none of the layers indicate a preference, then V0_SRGB is the
1887 // preferred choice (subject to additional checks).
1888 verify().ifTopLayerHasNoPreference()
1889 .andIfMiddleLayerHasNoPreference()
1890 .andIfBottomLayerHasNoPreference()
1891 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1892 .execute();
1893}
1894
1895TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1896 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1897 // If only the topmost layer has a preference, then that is what is chosen.
1898 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1899 .andIfMiddleLayerHasNoPreference()
1900 .andIfBottomLayerHasNoPreference()
1901 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1902 .execute();
1903}
1904
1905TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1906 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1907 // If only the middle layer has a preference, that that is what is chosen.
1908 verify().ifTopLayerHasNoPreference()
1909 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1910 .andIfBottomLayerHasNoPreference()
1911 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1912 .execute();
1913}
1914
1915TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1916 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1917 // If only the middle layer has a preference, that that is what is chosen.
1918 verify().ifTopLayerHasNoPreference()
1919 .andIfMiddleLayerHasNoPreference()
1920 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1921 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1922 .execute();
1923}
1924
1925TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1926 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1927 // If multiple layers have a preference, the topmost value is what is used.
1928 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1929 .andIfMiddleLayerHasNoPreference()
1930 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1931 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1932 .execute();
1933}
1934
1935TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1936 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1937 // If multiple layers have a preference, the topmost value is what is used.
1938 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1939 .andIfMiddleLayerHasNoPreference()
1940 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1941 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1942 .execute();
1943}
1944
1945struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1946 : public OutputUpdateColorProfileTest {
1947 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1948 // values, it overrides the layer dataspace choice.
1949
1950 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1951 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1952 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1953
1954 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1955
Lloyd Pique0a456232020-01-16 17:51:13 -08001956 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001957 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1958 }
1959
1960 struct IfForceOutputColorModeState
1961 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1962 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1963 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1964 return nextState<ThenExpectBestColorModeCallUsesState>();
1965 }
1966 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1967 };
1968
1969 struct ThenExpectBestColorModeCallUsesState
1970 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1971 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1972 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1973 getBestColorMode(dataspace, _, _, _, _));
1974 return nextState<ExecuteState>();
1975 }
1976 };
1977
1978 // Call this member function to start using the mini-DSL defined above.
1979 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1980};
1981
1982TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1983 // By default the layer state is used to set the preferred dataspace
1984 verify().ifNoOverride()
1985 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1986 .execute();
1987}
1988
1989TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1990 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1991 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1992 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1993 .execute();
1994}
1995
1996TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1997 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1998 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1999 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2000 .execute();
2001}
2002
2003// HDR output requires all layers to be compatible with the chosen HDR
2004// dataspace, along with there being proper support.
2005struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2006 OutputUpdateColorProfileTest_Hdr() {
2007 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2008 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002009 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002010 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2011 }
2012
2013 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2014 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2015 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2016 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2017
2018 struct IfTopLayerDataspaceState
2019 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2020 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2021 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2022 return nextState<AndTopLayerCompositionTypeState>();
2023 }
2024 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2025 };
2026
2027 struct AndTopLayerCompositionTypeState
2028 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2029 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2030 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2031 return nextState<AndIfBottomLayerDataspaceState>();
2032 }
2033 };
2034
2035 struct AndIfBottomLayerDataspaceState
2036 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2037 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2038 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2039 return nextState<AndBottomLayerCompositionTypeState>();
2040 }
2041 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2042 return andIfBottomLayerIs(kNonHdrDataspace);
2043 }
2044 };
2045
2046 struct AndBottomLayerCompositionTypeState
2047 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2048 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2049 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2050 return nextState<AndIfHasLegacySupportState>();
2051 }
2052 };
2053
2054 struct AndIfHasLegacySupportState
2055 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2056 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2057 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2058 .WillOnce(Return(legacySupport));
2059 return nextState<ThenExpectBestColorModeCallUsesState>();
2060 }
2061 };
2062
2063 struct ThenExpectBestColorModeCallUsesState
2064 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2065 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2066 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2067 getBestColorMode(dataspace, _, _, _, _));
2068 return nextState<ExecuteState>();
2069 }
2070 };
2071
2072 // Call this member function to start using the mini-DSL defined above.
2073 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2074};
2075
2076TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2077 // If all layers use BT2020_PQ, and there are no other special conditions,
2078 // BT2020_PQ is used.
2079 verify().ifTopLayerIs(BT2020_PQ)
2080 .andTopLayerIsREComposed(false)
2081 .andIfBottomLayerIs(BT2020_PQ)
2082 .andBottomLayerIsREComposed(false)
2083 .andIfLegacySupportFor(BT2020_PQ, false)
2084 .thenExpectBestColorModeCallUses(BT2020_PQ)
2085 .execute();
2086}
2087
2088TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2089 // BT2020_PQ is not used if there is only legacy support for it.
2090 verify().ifTopLayerIs(BT2020_PQ)
2091 .andTopLayerIsREComposed(false)
2092 .andIfBottomLayerIs(BT2020_PQ)
2093 .andBottomLayerIsREComposed(false)
2094 .andIfLegacySupportFor(BT2020_PQ, true)
2095 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2096 .execute();
2097}
2098
2099TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2100 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2101 verify().ifTopLayerIs(BT2020_PQ)
2102 .andTopLayerIsREComposed(false)
2103 .andIfBottomLayerIs(BT2020_PQ)
2104 .andBottomLayerIsREComposed(true)
2105 .andIfLegacySupportFor(BT2020_PQ, false)
2106 .thenExpectBestColorModeCallUses(BT2020_PQ)
2107 .execute();
2108}
2109
2110TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2111 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2112 verify().ifTopLayerIs(BT2020_PQ)
2113 .andTopLayerIsREComposed(true)
2114 .andIfBottomLayerIs(BT2020_PQ)
2115 .andBottomLayerIsREComposed(false)
2116 .andIfLegacySupportFor(BT2020_PQ, false)
2117 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2118 .execute();
2119}
2120
2121TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2122 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2123 // are no other special conditions.
2124 verify().ifTopLayerIs(BT2020_PQ)
2125 .andTopLayerIsREComposed(false)
2126 .andIfBottomLayerIs(BT2020_HLG)
2127 .andBottomLayerIsREComposed(false)
2128 .andIfLegacySupportFor(BT2020_PQ, false)
2129 .thenExpectBestColorModeCallUses(BT2020_PQ)
2130 .execute();
2131}
2132
2133TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2134 // BT2020_PQ is not used if there is only legacy support for it.
2135 verify().ifTopLayerIs(BT2020_PQ)
2136 .andTopLayerIsREComposed(false)
2137 .andIfBottomLayerIs(BT2020_HLG)
2138 .andBottomLayerIsREComposed(false)
2139 .andIfLegacySupportFor(BT2020_PQ, true)
2140 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2141 .execute();
2142}
2143
2144TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2145 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2146 verify().ifTopLayerIs(BT2020_PQ)
2147 .andTopLayerIsREComposed(false)
2148 .andIfBottomLayerIs(BT2020_HLG)
2149 .andBottomLayerIsREComposed(true)
2150 .andIfLegacySupportFor(BT2020_PQ, false)
2151 .thenExpectBestColorModeCallUses(BT2020_PQ)
2152 .execute();
2153}
2154
2155TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2156 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2157 verify().ifTopLayerIs(BT2020_PQ)
2158 .andTopLayerIsREComposed(true)
2159 .andIfBottomLayerIs(BT2020_HLG)
2160 .andBottomLayerIsREComposed(false)
2161 .andIfLegacySupportFor(BT2020_PQ, false)
2162 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2163 .execute();
2164}
2165
2166TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2167 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2168 // used if there are no other special conditions.
2169 verify().ifTopLayerIs(BT2020_HLG)
2170 .andTopLayerIsREComposed(false)
2171 .andIfBottomLayerIs(BT2020_PQ)
2172 .andBottomLayerIsREComposed(false)
2173 .andIfLegacySupportFor(BT2020_PQ, false)
2174 .thenExpectBestColorModeCallUses(BT2020_PQ)
2175 .execute();
2176}
2177
2178TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2179 // BT2020_PQ is not used if there is only legacy support for it.
2180 verify().ifTopLayerIs(BT2020_HLG)
2181 .andTopLayerIsREComposed(false)
2182 .andIfBottomLayerIs(BT2020_PQ)
2183 .andBottomLayerIsREComposed(false)
2184 .andIfLegacySupportFor(BT2020_PQ, true)
2185 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2186 .execute();
2187}
2188
2189TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2190 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2191 verify().ifTopLayerIs(BT2020_HLG)
2192 .andTopLayerIsREComposed(false)
2193 .andIfBottomLayerIs(BT2020_PQ)
2194 .andBottomLayerIsREComposed(true)
2195 .andIfLegacySupportFor(BT2020_PQ, false)
2196 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2197 .execute();
2198}
2199
2200TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2201 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2202 verify().ifTopLayerIs(BT2020_HLG)
2203 .andTopLayerIsREComposed(true)
2204 .andIfBottomLayerIs(BT2020_PQ)
2205 .andBottomLayerIsREComposed(false)
2206 .andIfLegacySupportFor(BT2020_PQ, false)
2207 .thenExpectBestColorModeCallUses(BT2020_PQ)
2208 .execute();
2209}
2210
2211TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2212 // If all layers use HLG then HLG is used if there are no other special
2213 // conditions.
2214 verify().ifTopLayerIs(BT2020_HLG)
2215 .andTopLayerIsREComposed(false)
2216 .andIfBottomLayerIs(BT2020_HLG)
2217 .andBottomLayerIsREComposed(false)
2218 .andIfLegacySupportFor(BT2020_HLG, false)
2219 .thenExpectBestColorModeCallUses(BT2020_HLG)
2220 .execute();
2221}
2222
2223TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2224 // BT2020_HLG is not used if there is legacy support for it.
2225 verify().ifTopLayerIs(BT2020_HLG)
2226 .andTopLayerIsREComposed(false)
2227 .andIfBottomLayerIs(BT2020_HLG)
2228 .andBottomLayerIsREComposed(false)
2229 .andIfLegacySupportFor(BT2020_HLG, true)
2230 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2231 .execute();
2232}
2233
2234TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2235 // BT2020_HLG is used even if the bottom layer is client composed.
2236 verify().ifTopLayerIs(BT2020_HLG)
2237 .andTopLayerIsREComposed(false)
2238 .andIfBottomLayerIs(BT2020_HLG)
2239 .andBottomLayerIsREComposed(true)
2240 .andIfLegacySupportFor(BT2020_HLG, false)
2241 .thenExpectBestColorModeCallUses(BT2020_HLG)
2242 .execute();
2243}
2244
2245TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2246 // BT2020_HLG is used even if the top layer is client composed.
2247 verify().ifTopLayerIs(BT2020_HLG)
2248 .andTopLayerIsREComposed(true)
2249 .andIfBottomLayerIs(BT2020_HLG)
2250 .andBottomLayerIsREComposed(false)
2251 .andIfLegacySupportFor(BT2020_HLG, false)
2252 .thenExpectBestColorModeCallUses(BT2020_HLG)
2253 .execute();
2254}
2255
2256TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2257 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2258 verify().ifTopLayerIs(BT2020_PQ)
2259 .andTopLayerIsREComposed(false)
2260 .andIfBottomLayerIsNotHdr()
2261 .andBottomLayerIsREComposed(false)
2262 .andIfLegacySupportFor(BT2020_PQ, false)
2263 .thenExpectBestColorModeCallUses(BT2020_PQ)
2264 .execute();
2265}
2266
2267TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2268 // If all layers use HLG then HLG is used if there are no other special
2269 // conditions.
2270 verify().ifTopLayerIs(BT2020_HLG)
2271 .andTopLayerIsREComposed(false)
2272 .andIfBottomLayerIsNotHdr()
2273 .andBottomLayerIsREComposed(true)
2274 .andIfLegacySupportFor(BT2020_HLG, false)
2275 .thenExpectBestColorModeCallUses(BT2020_HLG)
2276 .execute();
2277}
2278
2279struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2280 : public OutputUpdateColorProfileTest {
2281 // The various values for CompositionRefreshArgs::outputColorSetting affect
2282 // the chosen renderIntent, along with whether the preferred dataspace is an
2283 // HDR dataspace or not.
2284
2285 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2286 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2287 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2288 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002289 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002290 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2291 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2292 .WillRepeatedly(Return(false));
2293 }
2294
2295 // The tests here involve enough state and GMock setup that using a mini-DSL
2296 // makes the tests much more readable, and allows the test to focus more on
2297 // the intent than on some of the details.
2298
2299 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2300 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2301
2302 struct IfDataspaceChosenState
2303 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2304 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2305 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2306 return nextState<AndOutputColorSettingState>();
2307 }
2308 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2309 return ifDataspaceChosenIs(kNonHdrDataspace);
2310 }
2311 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2312 };
2313
2314 struct AndOutputColorSettingState
2315 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2316 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2317 getInstance()->mRefreshArgs.outputColorSetting = setting;
2318 return nextState<ThenExpectBestColorModeCallUsesState>();
2319 }
2320 };
2321
2322 struct ThenExpectBestColorModeCallUsesState
2323 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2324 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2325 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2326 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2327 _, _));
2328 return nextState<ExecuteState>();
2329 }
2330 };
2331
2332 // Tests call one of these two helper member functions to start using the
2333 // mini-DSL defined above.
2334 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2335};
2336
2337TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2338 Managed_NonHdr_Prefers_Colorimetric) {
2339 verify().ifDataspaceChosenIsNonHdr()
2340 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2341 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2342 .execute();
2343}
2344
2345TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2346 Managed_Hdr_Prefers_ToneMapColorimetric) {
2347 verify().ifDataspaceChosenIsHdr()
2348 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2349 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2350 .execute();
2351}
2352
2353TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2354 verify().ifDataspaceChosenIsNonHdr()
2355 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2356 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2361 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2362 verify().ifDataspaceChosenIsHdr()
2363 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2364 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2365 .execute();
2366}
2367
2368TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2369 verify().ifDataspaceChosenIsNonHdr()
2370 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2371 .thenExpectBestColorModeCallUses(
2372 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2373 .execute();
2374}
2375
2376TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2377 verify().ifDataspaceChosenIsHdr()
2378 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2379 .thenExpectBestColorModeCallUses(
2380 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2381 .execute();
2382}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002383
2384/*
2385 * Output::beginFrame()
2386 */
2387
Lloyd Piquee5965952019-11-18 16:16:32 -08002388struct OutputBeginFrameTest : public ::testing::Test {
2389 using TestType = OutputBeginFrameTest;
2390
2391 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002392 // Sets up the helper functions called by the function under test to use
2393 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002394 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2395 };
2396
2397 OutputBeginFrameTest() {
2398 mOutput.setDisplayColorProfileForTest(
2399 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2400 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2401 }
2402
2403 struct IfGetDirtyRegionExpectationState
2404 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2405 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2406 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2407 .WillOnce(Return(dirtyRegion));
2408 return nextState<AndIfGetOutputLayerCountExpectationState>();
2409 }
2410 };
2411
2412 struct AndIfGetOutputLayerCountExpectationState
2413 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2414 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2415 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2416 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2417 }
2418 };
2419
2420 struct AndIfLastCompositionHadVisibleLayersState
2421 : public CallOrderStateMachineHelper<TestType,
2422 AndIfLastCompositionHadVisibleLayersState> {
2423 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2424 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2425 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2426 }
2427 };
2428
2429 struct ThenExpectRenderSurfaceBeginFrameCallState
2430 : public CallOrderStateMachineHelper<TestType,
2431 ThenExpectRenderSurfaceBeginFrameCallState> {
2432 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2433 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2434 return nextState<ExecuteState>();
2435 }
2436 };
2437
2438 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2439 [[nodiscard]] auto execute() {
2440 getInstance()->mOutput.beginFrame();
2441 return nextState<CheckPostconditionHadVisibleLayersState>();
2442 }
2443 };
2444
2445 struct CheckPostconditionHadVisibleLayersState
2446 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2447 void checkPostconditionHadVisibleLayers(bool expected) {
2448 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2449 }
2450 };
2451
2452 // Tests call one of these two helper member functions to start using the
2453 // mini-DSL defined above.
2454 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2455
2456 static const Region kEmptyRegion;
2457 static const Region kNotEmptyRegion;
2458
2459 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2460 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2461 StrictMock<OutputPartialMock> mOutput;
2462};
2463
2464const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2465const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2466
2467TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2468 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2469 .andIfGetOutputLayerCountReturns(1u)
2470 .andIfLastCompositionHadVisibleLayersIs(true)
2471 .thenExpectRenderSurfaceBeginFrameCall(true)
2472 .execute()
2473 .checkPostconditionHadVisibleLayers(true);
2474}
2475
2476TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2477 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2478 .andIfGetOutputLayerCountReturns(0u)
2479 .andIfLastCompositionHadVisibleLayersIs(true)
2480 .thenExpectRenderSurfaceBeginFrameCall(true)
2481 .execute()
2482 .checkPostconditionHadVisibleLayers(false);
2483}
2484
2485TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2486 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2487 .andIfGetOutputLayerCountReturns(1u)
2488 .andIfLastCompositionHadVisibleLayersIs(false)
2489 .thenExpectRenderSurfaceBeginFrameCall(true)
2490 .execute()
2491 .checkPostconditionHadVisibleLayers(true);
2492}
2493
2494TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2495 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2496 .andIfGetOutputLayerCountReturns(0u)
2497 .andIfLastCompositionHadVisibleLayersIs(false)
2498 .thenExpectRenderSurfaceBeginFrameCall(false)
2499 .execute()
2500 .checkPostconditionHadVisibleLayers(false);
2501}
2502
2503TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2504 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2505 .andIfGetOutputLayerCountReturns(1u)
2506 .andIfLastCompositionHadVisibleLayersIs(true)
2507 .thenExpectRenderSurfaceBeginFrameCall(false)
2508 .execute()
2509 .checkPostconditionHadVisibleLayers(true);
2510}
2511
2512TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2513 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2514 .andIfGetOutputLayerCountReturns(0u)
2515 .andIfLastCompositionHadVisibleLayersIs(true)
2516 .thenExpectRenderSurfaceBeginFrameCall(false)
2517 .execute()
2518 .checkPostconditionHadVisibleLayers(true);
2519}
2520
2521TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2522 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2523 .andIfGetOutputLayerCountReturns(1u)
2524 .andIfLastCompositionHadVisibleLayersIs(false)
2525 .thenExpectRenderSurfaceBeginFrameCall(false)
2526 .execute()
2527 .checkPostconditionHadVisibleLayers(false);
2528}
2529
2530TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2531 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2532 .andIfGetOutputLayerCountReturns(0u)
2533 .andIfLastCompositionHadVisibleLayersIs(false)
2534 .thenExpectRenderSurfaceBeginFrameCall(false)
2535 .execute()
2536 .checkPostconditionHadVisibleLayers(false);
2537}
2538
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002539/*
2540 * Output::devOptRepaintFlash()
2541 */
2542
Lloyd Piquedb462d82019-11-19 17:58:46 -08002543struct OutputDevOptRepaintFlashTest : public testing::Test {
2544 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002545 // Sets up the helper functions called by the function under test to use
2546 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002547 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002548 MOCK_METHOD2(composeSurfaces,
2549 std::optional<base::unique_fd>(
2550 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002551 MOCK_METHOD0(postFramebuffer, void());
2552 MOCK_METHOD0(prepareFrame, void());
2553 };
2554
2555 OutputDevOptRepaintFlashTest() {
2556 mOutput.setDisplayColorProfileForTest(
2557 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2558 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2559 }
2560
2561 static const Region kEmptyRegion;
2562 static const Region kNotEmptyRegion;
2563
2564 StrictMock<OutputPartialMock> mOutput;
2565 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2566 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2567 CompositionRefreshArgs mRefreshArgs;
2568};
2569
2570const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2571const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2572
2573TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2574 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2575 mRefreshArgs.repaintEverything = true;
2576 mOutput.mState.isEnabled = true;
2577
2578 mOutput.devOptRepaintFlash(mRefreshArgs);
2579}
2580
2581TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2582 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2583 mRefreshArgs.repaintEverything = true;
2584 mOutput.mState.isEnabled = false;
2585
2586 InSequence seq;
2587 EXPECT_CALL(mOutput, postFramebuffer());
2588 EXPECT_CALL(mOutput, prepareFrame());
2589
2590 mOutput.devOptRepaintFlash(mRefreshArgs);
2591}
2592
2593TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2594 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2595 mRefreshArgs.repaintEverything = true;
2596 mOutput.mState.isEnabled = true;
2597
2598 InSequence seq;
2599 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2600 EXPECT_CALL(mOutput, postFramebuffer());
2601 EXPECT_CALL(mOutput, prepareFrame());
2602
2603 mOutput.devOptRepaintFlash(mRefreshArgs);
2604}
2605
2606TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2607 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2608 mRefreshArgs.repaintEverything = false;
2609 mOutput.mState.isEnabled = true;
2610
2611 InSequence seq;
2612 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002613 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002614 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2615 EXPECT_CALL(mOutput, postFramebuffer());
2616 EXPECT_CALL(mOutput, prepareFrame());
2617
2618 mOutput.devOptRepaintFlash(mRefreshArgs);
2619}
2620
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002621/*
2622 * Output::finishFrame()
2623 */
2624
Lloyd Pique03561a62019-11-19 18:34:52 -08002625struct OutputFinishFrameTest : public testing::Test {
2626 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002627 // Sets up the helper functions called by the function under test to use
2628 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002629 MOCK_METHOD2(composeSurfaces,
2630 std::optional<base::unique_fd>(
2631 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002632 MOCK_METHOD0(postFramebuffer, void());
2633 };
2634
2635 OutputFinishFrameTest() {
2636 mOutput.setDisplayColorProfileForTest(
2637 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2638 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2639 }
2640
2641 StrictMock<OutputPartialMock> mOutput;
2642 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2643 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2644 CompositionRefreshArgs mRefreshArgs;
2645};
2646
2647TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2648 mOutput.mState.isEnabled = false;
2649
2650 mOutput.finishFrame(mRefreshArgs);
2651}
2652
2653TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2654 mOutput.mState.isEnabled = true;
2655
2656 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002657 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002658
2659 mOutput.finishFrame(mRefreshArgs);
2660}
2661
2662TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2663 mOutput.mState.isEnabled = true;
2664
2665 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002666 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002667 .WillOnce(Return(ByMove(base::unique_fd())));
2668 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2669
2670 mOutput.finishFrame(mRefreshArgs);
2671}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002672
2673/*
2674 * Output::postFramebuffer()
2675 */
2676
Lloyd Pique07178e32019-11-19 19:15:26 -08002677struct OutputPostFramebufferTest : public testing::Test {
2678 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002679 // Sets up the helper functions called by the function under test to use
2680 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002681 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2682 };
2683
2684 struct Layer {
2685 Layer() {
2686 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2687 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2688 }
2689
2690 StrictMock<mock::OutputLayer> outputLayer;
2691 StrictMock<mock::LayerFE> layerFE;
2692 StrictMock<HWC2::mock::Layer> hwc2Layer;
2693 };
2694
2695 OutputPostFramebufferTest() {
2696 mOutput.setDisplayColorProfileForTest(
2697 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2698 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2699
2700 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2701 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2702 .WillRepeatedly(Return(&mLayer1.outputLayer));
2703 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2704 .WillRepeatedly(Return(&mLayer2.outputLayer));
2705 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2706 .WillRepeatedly(Return(&mLayer3.outputLayer));
2707 }
2708
2709 StrictMock<OutputPartialMock> mOutput;
2710 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2711 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2712
2713 Layer mLayer1;
2714 Layer mLayer2;
2715 Layer mLayer3;
2716};
2717
2718TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2719 mOutput.mState.isEnabled = false;
2720
2721 mOutput.postFramebuffer();
2722}
2723
2724TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2725 mOutput.mState.isEnabled = true;
2726
2727 compositionengine::Output::FrameFences frameFences;
2728
2729 // This should happen even if there are no output layers.
2730 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2731
2732 // For this test in particular we want to make sure the call expectations
2733 // setup below are satisfied in the specific order.
2734 InSequence seq;
2735
2736 EXPECT_CALL(*mRenderSurface, flip());
2737 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2738 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2739
2740 mOutput.postFramebuffer();
2741}
2742
2743TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2744 // Simulate getting release fences from each layer, and ensure they are passed to the
2745 // front-end layer interface for each layer correctly.
2746
2747 mOutput.mState.isEnabled = true;
2748
2749 // Create three unique fence instances
2750 sp<Fence> layer1Fence = new Fence();
2751 sp<Fence> layer2Fence = new Fence();
2752 sp<Fence> layer3Fence = new Fence();
2753
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002754 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002755 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2756 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2757 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2758
2759 EXPECT_CALL(*mRenderSurface, flip());
2760 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2761 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2762
2763 // Compare the pointers values of each fence to make sure the correct ones
2764 // are passed. This happens to work with the current implementation, but
2765 // would not survive certain calls like Fence::merge() which would return a
2766 // new instance.
2767 EXPECT_CALL(mLayer1.layerFE,
2768 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2769 EXPECT_CALL(mLayer2.layerFE,
2770 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2771 EXPECT_CALL(mLayer3.layerFE,
2772 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2773
2774 mOutput.postFramebuffer();
2775}
2776
2777TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2778 mOutput.mState.isEnabled = true;
2779 mOutput.mState.usesClientComposition = true;
2780
2781 sp<Fence> clientTargetAcquireFence = new Fence();
2782 sp<Fence> layer1Fence = new Fence();
2783 sp<Fence> layer2Fence = new Fence();
2784 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002785 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002786 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2787 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2788 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2789 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2790
2791 EXPECT_CALL(*mRenderSurface, flip());
2792 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2793 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2794
2795 // Fence::merge is called, and since none of the fences are actually valid,
2796 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2797 // This is the best we can do without creating a real kernel fence object.
2798 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2799 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2800 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2801
2802 mOutput.postFramebuffer();
2803}
2804
2805TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2806 mOutput.mState.isEnabled = true;
2807 mOutput.mState.usesClientComposition = true;
2808
2809 // This should happen even if there are no (current) output layers.
2810 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2811
2812 // Load up the released layers with some mock instances
2813 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2814 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2815 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2816 Output::ReleasedLayers layers;
2817 layers.push_back(releasedLayer1);
2818 layers.push_back(releasedLayer2);
2819 layers.push_back(releasedLayer3);
2820 mOutput.setReleasedLayers(std::move(layers));
2821
2822 // Set up a fake present fence
2823 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002824 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002825 frameFences.presentFence = presentFence;
2826
2827 EXPECT_CALL(*mRenderSurface, flip());
2828 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2829 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2830
2831 // Each released layer should be given the presentFence.
2832 EXPECT_CALL(*releasedLayer1,
2833 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2834 EXPECT_CALL(*releasedLayer2,
2835 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2836 EXPECT_CALL(*releasedLayer3,
2837 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2838
2839 mOutput.postFramebuffer();
2840
2841 // After the call the list of released layers should have been cleared.
2842 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2843}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002844
2845/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002846 * Output::composeSurfaces()
2847 */
2848
2849struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002850 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002851
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002852 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002853 // Sets up the helper functions called by the function under test to use
2854 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002855 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002856 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002857 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002858 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002859 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002860 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2861 };
2862
2863 OutputComposeSurfacesTest() {
2864 mOutput.setDisplayColorProfileForTest(
2865 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2866 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002867 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002868
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002869 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2870 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002871 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002872 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002873 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002874 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002875 mOutput.mState.dataspace = kDefaultOutputDataspace;
2876 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2877 mOutput.mState.isSecure = false;
2878 mOutput.mState.needsFiltering = false;
2879 mOutput.mState.usesClientComposition = true;
2880 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002881 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002882 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002883
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002884 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002885 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002886 EXPECT_CALL(mCompositionEngine, getTimeStats())
2887 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002888 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2889 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002890 }
2891
Lloyd Pique6818fa52019-12-03 12:32:13 -08002892 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2893 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002894 getInstance()->mReadyFence =
2895 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002896 return nextState<FenceCheckState>();
2897 }
2898 };
2899
2900 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2901 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2902
2903 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2904 };
2905
2906 // Call this member function to start using the mini-DSL defined above.
2907 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2908
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002909 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2910 static constexpr uint32_t kDefaultOutputOrientationFlags =
2911 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002912 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2913 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2914 static constexpr float kDefaultMaxLuminance = 0.9f;
2915 static constexpr float kDefaultAvgLuminance = 0.7f;
2916 static constexpr float kDefaultMinLuminance = 0.1f;
2917
2918 static const Rect kDefaultOutputFrame;
2919 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002920 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002921 static const mat4 kDefaultColorTransformMat;
2922
2923 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002924 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002925 static const HdrCapabilities kHdrCapabilities;
2926
Lloyd Pique56eba802019-08-28 15:45:25 -07002927 StrictMock<mock::CompositionEngine> mCompositionEngine;
2928 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002929 // TODO: make this is a proper mock.
2930 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002931 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2932 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002933 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002934 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002935
2936 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002937};
2938
2939const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2940const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002941const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002942const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002943const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002944const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2945const HdrCapabilities OutputComposeSurfacesTest::
2946 kHdrCapabilities{{},
2947 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2948 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2949 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002950
Lloyd Piquea76ce462020-01-14 13:06:37 -08002951TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002952 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002953
Lloyd Piquee9eff972020-05-05 12:36:44 -07002954 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002955 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002956
Lloyd Piquea76ce462020-01-14 13:06:37 -08002957 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2958
Lloyd Pique6818fa52019-12-03 12:32:13 -08002959 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002960}
2961
Lloyd Piquee9eff972020-05-05 12:36:44 -07002962TEST_F(OutputComposeSurfacesTest,
2963 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2964 mOutput.mState.usesClientComposition = false;
2965 mOutput.mState.flipClientTarget = true;
2966
Lloyd Pique6818fa52019-12-03 12:32:13 -08002967 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002968 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002969
2970 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2971 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2972
2973 verify().execute().expectAFenceWasReturned();
2974}
2975
2976TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2977 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002978 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002979
2980 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2981
2982 verify().execute().expectNoFenceWasReturned();
2983}
2984
2985TEST_F(OutputComposeSurfacesTest,
2986 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2987 mOutput.mState.usesClientComposition = false;
2988 mOutput.mState.flipClientTarget = true;
2989
2990 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002991 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002992
Lloyd Pique6818fa52019-12-03 12:32:13 -08002993 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002994
Lloyd Pique6818fa52019-12-03 12:32:13 -08002995 verify().execute().expectNoFenceWasReturned();
2996}
Lloyd Pique56eba802019-08-28 15:45:25 -07002997
Lloyd Pique6818fa52019-12-03 12:32:13 -08002998TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2999 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3000 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3001 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003002 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003003 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003004 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003005 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3006 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003007
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3009 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
3010 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003011
Lloyd Pique6818fa52019-12-03 12:32:13 -08003012 verify().execute().expectAFenceWasReturned();
3013}
Lloyd Pique56eba802019-08-28 15:45:25 -07003014
Lloyd Pique6818fa52019-12-03 12:32:13 -08003015TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003016 LayerFE::LayerSettings r1;
3017 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003018
3019 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3020 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3021
3022 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3023 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3024 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003025 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003026 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003027 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003028 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3029 .WillRepeatedly(
3030 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003031 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003032 clientCompositionLayers.emplace_back(r2);
3033 }));
3034
3035 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003036 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003037 .WillRepeatedly(Return(NO_ERROR));
3038
3039 verify().execute().expectAFenceWasReturned();
3040}
3041
Vishnu Nair9b079a22020-01-21 14:36:08 -08003042TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3043 mOutput.cacheClientCompositionRequests(0);
3044 LayerFE::LayerSettings r1;
3045 LayerFE::LayerSettings r2;
3046
3047 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3048 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3049
3050 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3051 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3052 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003053 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003054 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3055 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3056 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3057 .WillRepeatedly(Return());
3058
3059 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3060 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3061 .Times(2)
3062 .WillOnce(Return(NO_ERROR));
3063
3064 verify().execute().expectAFenceWasReturned();
3065 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3066
3067 verify().execute().expectAFenceWasReturned();
3068 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3069}
3070
3071TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3072 mOutput.cacheClientCompositionRequests(3);
3073 LayerFE::LayerSettings r1;
3074 LayerFE::LayerSettings r2;
3075
3076 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3077 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3078
3079 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3080 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3081 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003082 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003083 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3084 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3085 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3086 .WillRepeatedly(Return());
3087
3088 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3089 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3090 .WillOnce(Return(NO_ERROR));
3091 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3092
3093 verify().execute().expectAFenceWasReturned();
3094 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3095
3096 // We do not expect another call to draw layers.
3097 verify().execute().expectAFenceWasReturned();
3098 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3099}
3100
3101TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3102 LayerFE::LayerSettings r1;
3103 LayerFE::LayerSettings r2;
3104
3105 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3106 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3107
3108 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3109 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3110 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003111 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003112 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3113 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3114 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3115 .WillRepeatedly(Return());
3116
3117 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3118 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3119 .WillOnce(Return(mOutputBuffer))
3120 .WillOnce(Return(otherOutputBuffer));
3121 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3122 .WillRepeatedly(Return(NO_ERROR));
3123
3124 verify().execute().expectAFenceWasReturned();
3125 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3126
3127 verify().execute().expectAFenceWasReturned();
3128 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3129}
3130
3131TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3132 LayerFE::LayerSettings r1;
3133 LayerFE::LayerSettings r2;
3134 LayerFE::LayerSettings r3;
3135
3136 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3137 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3138 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3139
3140 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3141 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3142 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003143 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003144 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3145 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3146 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3147 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3148 .WillRepeatedly(Return());
3149
3150 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3151 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3152 .WillOnce(Return(NO_ERROR));
3153 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3154 .WillOnce(Return(NO_ERROR));
3155
3156 verify().execute().expectAFenceWasReturned();
3157 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3158
3159 verify().execute().expectAFenceWasReturned();
3160 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3161}
3162
Lloyd Pique6818fa52019-12-03 12:32:13 -08003163struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3164 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3165 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003166 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003167 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003168 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003169 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3170 .WillRepeatedly(Return());
3171 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3172 }
3173
3174 struct MixedCompositionState
3175 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3176 auto ifMixedCompositionIs(bool used) {
3177 getInstance()->mOutput.mState.usesDeviceComposition = used;
3178 return nextState<OutputUsesHdrState>();
3179 }
3180 };
3181
3182 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3183 auto andIfUsesHdr(bool used) {
3184 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3185 .WillOnce(Return(used));
3186 return nextState<SkipColorTransformState>();
3187 }
3188 };
3189
3190 struct SkipColorTransformState
3191 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3192 auto andIfSkipColorTransform(bool skip) {
3193 // May be called zero or one times.
3194 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3195 .WillRepeatedly(Return(skip));
3196 return nextState<ExpectDisplaySettingsState>();
3197 }
3198 };
3199
3200 struct ExpectDisplaySettingsState
3201 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3202 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3203 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3204 .WillOnce(Return(NO_ERROR));
3205 return nextState<ExecuteState>();
3206 }
3207 };
3208
3209 // Call this member function to start using the mini-DSL defined above.
3210 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3211};
3212
3213TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3214 verify().ifMixedCompositionIs(true)
3215 .andIfUsesHdr(true)
3216 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003217 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003218 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003219 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003220 .execute()
3221 .expectAFenceWasReturned();
3222}
3223
3224TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3225 verify().ifMixedCompositionIs(true)
3226 .andIfUsesHdr(false)
3227 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003228 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003229 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003230 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003231 .execute()
3232 .expectAFenceWasReturned();
3233}
3234
3235TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3236 verify().ifMixedCompositionIs(false)
3237 .andIfUsesHdr(true)
3238 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003239 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003240 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003241 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003242 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003243 .execute()
3244 .expectAFenceWasReturned();
3245}
3246
3247TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3248 verify().ifMixedCompositionIs(false)
3249 .andIfUsesHdr(false)
3250 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003251 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003252 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003253 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003254 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003255 .execute()
3256 .expectAFenceWasReturned();
3257}
3258
3259TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3260 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3261 verify().ifMixedCompositionIs(false)
3262 .andIfUsesHdr(true)
3263 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003264 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003265 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003266 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003267 .execute()
3268 .expectAFenceWasReturned();
3269}
3270
3271struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3272 struct Layer {
3273 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003274 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3275 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003276 }
3277
3278 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003279 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003280 LayerFECompositionState mLayerFEState;
3281 };
3282
3283 OutputComposeSurfacesTest_HandlesProtectedContent() {
3284 mLayer1.mLayerFEState.hasProtectedContent = false;
3285 mLayer2.mLayerFEState.hasProtectedContent = false;
3286
3287 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3288 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3289 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3290 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3291 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3292
3293 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3294
3295 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3296
3297 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003298 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003299 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3300 .WillRepeatedly(Return());
3301 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3302 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3303 .WillRepeatedly(Return(NO_ERROR));
3304 }
3305
3306 Layer mLayer1;
3307 Layer mLayer2;
3308};
3309
3310TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3311 mOutput.mState.isSecure = false;
3312 mLayer2.mLayerFEState.hasProtectedContent = true;
3313 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003314 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3315 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003316
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003317 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003318}
3319
3320TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3321 mOutput.mState.isSecure = true;
3322 mLayer2.mLayerFEState.hasProtectedContent = true;
3323 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3324
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003325 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003326}
3327
3328TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3329 mOutput.mState.isSecure = true;
3330 mLayer2.mLayerFEState.hasProtectedContent = false;
3331 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3332 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3333 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3334 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3335 EXPECT_CALL(*mRenderSurface, setProtected(false));
3336
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003337 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003338}
3339
3340TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3341 mOutput.mState.isSecure = true;
3342 mLayer2.mLayerFEState.hasProtectedContent = true;
3343 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3344
3345 // For this test, we also check the call order of key functions.
3346 InSequence seq;
3347
3348 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3349 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3350 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3351 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3352 EXPECT_CALL(*mRenderSurface, setProtected(true));
3353 // Must happen after setting the protected content state.
3354 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3355 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3356
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003357 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003358}
3359
3360TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3361 mOutput.mState.isSecure = true;
3362 mLayer2.mLayerFEState.hasProtectedContent = true;
3363 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3364 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3365 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3366
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003367 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003368}
3369
3370TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3371 mOutput.mState.isSecure = true;
3372 mLayer2.mLayerFEState.hasProtectedContent = true;
3373 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3374 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3375 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3376 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3377
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003378 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003379}
3380
3381TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3382 mOutput.mState.isSecure = true;
3383 mLayer2.mLayerFEState.hasProtectedContent = true;
3384 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3385 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3386 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3387 EXPECT_CALL(*mRenderSurface, setProtected(true));
3388
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003389 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003390}
3391
3392TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3393 mOutput.mState.isSecure = true;
3394 mLayer2.mLayerFEState.hasProtectedContent = true;
3395 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3396 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3397 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3398 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3399
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003400 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003401}
3402
3403struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3404 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3405 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3406 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3407 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003408 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003409 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3410 .WillRepeatedly(Return());
3411 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3412 }
3413};
3414
3415TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3416 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3417
3418 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003419 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003420
3421 // For this test, we also check the call order of key functions.
3422 InSequence seq;
3423
3424 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3425 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003426
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003427 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3428}
3429
3430struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3431 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3432 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3433 mLayer.layerFEState.backgroundBlurRadius = 10;
3434 mOutput.editState().isEnabled = true;
3435
Snild Dolkow9e217d62020-04-22 15:53:42 +02003436 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003437 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3438 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3439 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3440 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3441 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3442 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3443 .WillRepeatedly(Return(&mLayer.outputLayer));
3444 }
3445
3446 NonInjectedLayer mLayer;
3447 compositionengine::CompositionRefreshArgs mRefreshArgs;
3448};
3449
3450TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3451 mRefreshArgs.blursAreExpensive = true;
3452 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3453
3454 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3455 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3456}
3457
3458TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3459 mRefreshArgs.blursAreExpensive = false;
3460 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3461
3462 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3463 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003464}
3465
3466/*
3467 * Output::generateClientCompositionRequests()
3468 */
3469
3470struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003471 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003472 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003473 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003474 bool supportsProtectedContent, Region& clearRegion,
3475 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003476 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003477 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003478 }
3479 };
3480
Lloyd Piquea4863342019-12-04 18:45:02 -08003481 struct Layer {
3482 Layer() {
3483 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3484 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003485 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003486 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003487 }
3488
3489 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003490 StrictMock<mock::LayerFE> mLayerFE;
3491 LayerFECompositionState mLayerFEState;
3492 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003493 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003494 };
3495
Lloyd Pique56eba802019-08-28 15:45:25 -07003496 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003497 mOutput.mState.needsFiltering = false;
3498
Lloyd Pique56eba802019-08-28 15:45:25 -07003499 mOutput.setDisplayColorProfileForTest(
3500 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3501 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3502 }
3503
Lloyd Pique56eba802019-08-28 15:45:25 -07003504 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3505 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003506 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003507};
3508
Lloyd Piquea4863342019-12-04 18:45:02 -08003509struct GenerateClientCompositionRequestsTest_ThreeLayers
3510 : public GenerateClientCompositionRequestsTest {
3511 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003512 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3513 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3514 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003515 mOutput.mState.transform =
3516 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3517 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003518 mOutput.mState.needsFiltering = false;
3519 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003520
Lloyd Piquea4863342019-12-04 18:45:02 -08003521 for (size_t i = 0; i < mLayers.size(); i++) {
3522 mLayers[i].mOutputLayerState.clearClientTarget = false;
3523 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3524 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003525 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003526 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003527 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3528 mLayers[i].mLayerSettings.alpha = 1.0f;
3529 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003530
Lloyd Piquea4863342019-12-04 18:45:02 -08003531 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3532 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3533 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3534 .WillRepeatedly(Return(true));
3535 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3536 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003537
Lloyd Piquea4863342019-12-04 18:45:02 -08003538 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3539 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003540
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003541 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003542 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003543
Lloyd Piquea4863342019-12-04 18:45:02 -08003544 static const Rect kDisplayFrame;
3545 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003546 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003547
Lloyd Piquea4863342019-12-04 18:45:02 -08003548 std::array<Layer, 3> mLayers;
3549};
Lloyd Pique56eba802019-08-28 15:45:25 -07003550
Lloyd Piquea4863342019-12-04 18:45:02 -08003551const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3552const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003553const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3554 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003555
Lloyd Piquea4863342019-12-04 18:45:02 -08003556TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3557 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3558 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3559 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003560
Lloyd Piquea4863342019-12-04 18:45:02 -08003561 Region accumClearRegion(Rect(10, 11, 12, 13));
3562 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3563 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003564 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003565 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003566}
3567
Lloyd Piquea4863342019-12-04 18:45:02 -08003568TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3569 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3570 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3571 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3572
3573 Region accumClearRegion(Rect(10, 11, 12, 13));
3574 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3575 accumClearRegion, kDisplayDataspace);
3576 EXPECT_EQ(0u, requests.size());
3577 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3578}
3579
3580TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003581 LayerFE::LayerSettings mShadowSettings;
3582 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003583
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003584 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3585 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3586 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3587 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3588 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3589 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3590 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003591
3592 Region accumClearRegion(Rect(10, 11, 12, 13));
3593 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3594 accumClearRegion, kDisplayDataspace);
3595 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003596 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3597 EXPECT_EQ(mShadowSettings, requests[1]);
3598 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003599
3600 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3601
3602 // Check that a timestamp was set for the layers that generated requests
3603 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3604 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3605 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3606}
3607
3608TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3609 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3610 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3611 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3612 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3613
3614 mLayers[0].mOutputLayerState.clearClientTarget = false;
3615 mLayers[1].mOutputLayerState.clearClientTarget = false;
3616 mLayers[2].mOutputLayerState.clearClientTarget = false;
3617
3618 mLayers[0].mLayerFEState.isOpaque = true;
3619 mLayers[1].mLayerFEState.isOpaque = true;
3620 mLayers[2].mLayerFEState.isOpaque = true;
3621
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003622 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3623 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003624
3625 Region accumClearRegion(Rect(10, 11, 12, 13));
3626 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3627 accumClearRegion, kDisplayDataspace);
3628 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003629 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003630
3631 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3632}
3633
3634TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3635 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3636 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3637 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3638 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3639
3640 mLayers[0].mOutputLayerState.clearClientTarget = true;
3641 mLayers[1].mOutputLayerState.clearClientTarget = true;
3642 mLayers[2].mOutputLayerState.clearClientTarget = true;
3643
3644 mLayers[0].mLayerFEState.isOpaque = false;
3645 mLayers[1].mLayerFEState.isOpaque = false;
3646 mLayers[2].mLayerFEState.isOpaque = false;
3647
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003648 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3649 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003650
3651 Region accumClearRegion(Rect(10, 11, 12, 13));
3652 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3653 accumClearRegion, kDisplayDataspace);
3654 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003655 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003656
3657 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3658}
3659
3660TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003661 // If client composition is performed with some layers set to use device
3662 // composition, device layers after the first layer (device or client) will
3663 // clear the frame buffer if they are opaque and if that layer has a flag
3664 // set to do so. The first layer is skipped as the frame buffer is already
3665 // expected to be clear.
3666
Lloyd Piquea4863342019-12-04 18:45:02 -08003667 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3668 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3669 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003670
Lloyd Piquea4863342019-12-04 18:45:02 -08003671 mLayers[0].mOutputLayerState.clearClientTarget = true;
3672 mLayers[1].mOutputLayerState.clearClientTarget = true;
3673 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003674
Lloyd Piquea4863342019-12-04 18:45:02 -08003675 mLayers[0].mLayerFEState.isOpaque = true;
3676 mLayers[1].mLayerFEState.isOpaque = true;
3677 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003678 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003679 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003680
3681 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3682 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003683 false, /* needs filtering */
3684 false, /* secure */
3685 false, /* supports protected content */
3686 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003687 kDisplayViewport,
3688 kDisplayDataspace,
3689 false /* realContentIsVisible */,
3690 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003691 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003692 };
3693 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3694 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003695 false, /* needs filtering */
3696 false, /* secure */
3697 false, /* supports protected content */
3698 accumClearRegion,
3699 kDisplayViewport,
3700 kDisplayDataspace,
3701 true /* realContentIsVisible */,
3702 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003703 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003704 };
3705
3706 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3707 mBlackoutSettings.source.buffer.buffer = nullptr;
3708 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3709 mBlackoutSettings.alpha = 0.f;
3710 mBlackoutSettings.disableBlending = true;
3711
3712 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3713 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3714 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3715 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3716
Lloyd Piquea4863342019-12-04 18:45:02 -08003717 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3718 accumClearRegion, kDisplayDataspace);
3719 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003720
Lloyd Piquea4863342019-12-04 18:45:02 -08003721 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003722 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003723
Vishnu Nair9b079a22020-01-21 14:36:08 -08003724 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003725
Lloyd Piquea4863342019-12-04 18:45:02 -08003726 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3727}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003728
Lloyd Piquea4863342019-12-04 18:45:02 -08003729TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3730 clippedVisibleRegionUsedToGenerateRequest) {
3731 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3732 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3733 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003734
Lloyd Piquea4863342019-12-04 18:45:02 -08003735 Region accumClearRegion(Rect(10, 11, 12, 13));
3736
3737 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3738 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003739 false, /* needs filtering */
3740 false, /* secure */
3741 false, /* supports protected content */
3742 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003743 kDisplayViewport,
3744 kDisplayDataspace,
3745 true /* realContentIsVisible */,
3746 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003747 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003748 };
3749 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3750 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003751 false, /* needs filtering */
3752 false, /* secure */
3753 false, /* supports protected content */
3754 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003755 kDisplayViewport,
3756 kDisplayDataspace,
3757 true /* realContentIsVisible */,
3758 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003759 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003760 };
3761 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3762 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003763 false, /* needs filtering */
3764 false, /* secure */
3765 false, /* supports protected content */
3766 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003767 kDisplayViewport,
3768 kDisplayDataspace,
3769 true /* realContentIsVisible */,
3770 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003771 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003772 };
3773
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003774 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3775 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3776 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3777 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3778 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3779 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003780
3781 static_cast<void>(
3782 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3783 accumClearRegion, kDisplayDataspace));
3784}
3785
3786TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3787 perLayerNeedsFilteringUsedToGenerateRequests) {
3788 mOutput.mState.needsFiltering = false;
3789 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3790
3791 Region accumClearRegion(Rect(10, 11, 12, 13));
3792
3793 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3794 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003795 true, /* needs filtering */
3796 false, /* secure */
3797 false, /* supports protected content */
3798 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003799 kDisplayViewport,
3800 kDisplayDataspace,
3801 true /* realContentIsVisible */,
3802 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003803 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003804 };
3805 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3806 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003807 false, /* needs filtering */
3808 false, /* secure */
3809 false, /* supports protected content */
3810 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003811 kDisplayViewport,
3812 kDisplayDataspace,
3813 true /* realContentIsVisible */,
3814 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003815 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003816 };
3817 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3818 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003819 false, /* needs filtering */
3820 false, /* secure */
3821 false, /* supports protected content */
3822 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003823 kDisplayViewport,
3824 kDisplayDataspace,
3825 true /* realContentIsVisible */,
3826 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003827 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003828 };
3829
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003830 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3831 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3832 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3833 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3834 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3835 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003836
3837 static_cast<void>(
3838 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3839 accumClearRegion, kDisplayDataspace));
3840}
3841
3842TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3843 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3844 mOutput.mState.needsFiltering = true;
3845 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3846
3847 Region accumClearRegion(Rect(10, 11, 12, 13));
3848
3849 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3850 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003851 true, /* needs filtering */
3852 false, /* secure */
3853 false, /* supports protected content */
3854 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003855 kDisplayViewport,
3856 kDisplayDataspace,
3857 true /* realContentIsVisible */,
3858 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003859 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003860
Lloyd Piquea4863342019-12-04 18:45:02 -08003861 };
3862 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3863 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003864 true, /* needs filtering */
3865 false, /* secure */
3866 false, /* supports protected content */
3867 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003868 kDisplayViewport,
3869 kDisplayDataspace,
3870 true /* realContentIsVisible */,
3871 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003872 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003873 };
3874 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3875 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003876 true, /* needs filtering */
3877 false, /* secure */
3878 false, /* supports protected content */
3879 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003880 kDisplayViewport,
3881 kDisplayDataspace,
3882 true /* realContentIsVisible */,
3883 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003884 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003885 };
3886
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003887 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3888 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3889 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3890 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3891 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3892 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003893
3894 static_cast<void>(
3895 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3896 accumClearRegion, kDisplayDataspace));
3897}
3898
3899TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3900 wholeOutputSecurityUsedToGenerateRequests) {
3901 mOutput.mState.isSecure = true;
3902
3903 Region accumClearRegion(Rect(10, 11, 12, 13));
3904
3905 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3906 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003907 false, /* needs filtering */
3908 true, /* secure */
3909 false, /* supports protected content */
3910 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003911 kDisplayViewport,
3912 kDisplayDataspace,
3913 true /* realContentIsVisible */,
3914 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003915 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003916 };
3917 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3918 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003919 false, /* needs filtering */
3920 true, /* secure */
3921 false, /* supports protected content */
3922 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003923 kDisplayViewport,
3924 kDisplayDataspace,
3925 true /* realContentIsVisible */,
3926 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003927 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003928 };
3929 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3930 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 false, /* needs filtering */
3932 true, /* secure */
3933 false, /* supports protected content */
3934 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003935 kDisplayViewport,
3936 kDisplayDataspace,
3937 true /* realContentIsVisible */,
3938 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003939 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003940 };
3941
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003942 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3943 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3944 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3945 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3946 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3947 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003948
3949 static_cast<void>(
3950 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3951 accumClearRegion, kDisplayDataspace));
3952}
3953
3954TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3955 protectedContentSupportUsedToGenerateRequests) {
3956 Region accumClearRegion(Rect(10, 11, 12, 13));
3957
3958 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3959 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 false, /* needs filtering */
3961 false, /* secure */
3962 true, /* supports protected content */
3963 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003964 kDisplayViewport,
3965 kDisplayDataspace,
3966 true /* realContentIsVisible */,
3967 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003968 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003969 };
3970 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3971 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003972 false, /* needs filtering */
3973 false, /* secure */
3974 true, /* supports protected content */
3975 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003976 kDisplayViewport,
3977 kDisplayDataspace,
3978 true /* realContentIsVisible */,
3979 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003980 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003981 };
3982 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3983 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003984 false, /* needs filtering */
3985 false, /* secure */
3986 true, /* supports protected content */
3987 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003988 kDisplayViewport,
3989 kDisplayDataspace,
3990 true /* realContentIsVisible */,
3991 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003992 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003993 };
3994
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003995 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3996 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3997 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3998 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3999 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
4000 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004001
4002 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4003 accumClearRegion,
4004 kDisplayDataspace));
4005}
4006
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004007TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004008 InjectedLayer layer1;
4009 InjectedLayer layer2;
4010 InjectedLayer layer3;
4011
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004012 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004013 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004014 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004015 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004016 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004017 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004018 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004019
Lloyd Piquede196652020-01-22 17:29:58 -08004020 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004021
Lloyd Piquede196652020-01-22 17:29:58 -08004022 injectOutputLayer(layer1);
4023 injectOutputLayer(layer2);
4024 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004025
4026 mOutput->editState().isEnabled = true;
4027
4028 CompositionRefreshArgs args;
4029 args.updatingGeometryThisFrame = false;
4030 args.devOptForceClientComposition = false;
4031 mOutput->updateAndWriteCompositionState(args);
4032}
4033
Lucas Dupinc3800b82020-10-02 16:24:48 -07004034TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4035 InjectedLayer layer1;
4036 InjectedLayer layer2;
4037 InjectedLayer layer3;
4038
4039 // Layer requesting blur, or below, should request client composition.
4040 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4041 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
4042 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4043 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
4044 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4045 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
4046
4047 BlurRegion region;
4048 layer2.layerFEState.blurRegions.push_back(region);
4049
4050 injectOutputLayer(layer1);
4051 injectOutputLayer(layer2);
4052 injectOutputLayer(layer3);
4053
4054 mOutput->editState().isEnabled = true;
4055
4056 CompositionRefreshArgs args;
4057 args.updatingGeometryThisFrame = false;
4058 args.devOptForceClientComposition = false;
4059 mOutput->updateAndWriteCompositionState(args);
4060}
4061
Lloyd Piquea4863342019-12-04 18:45:02 -08004062TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4063 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4064 // one layer on the left covering the left side of the output, and one layer
4065 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004066
4067 const Rect kPortraitFrame(0, 0, 1000, 2000);
4068 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004069 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004070 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004071 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004072
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004073 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4074 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4075 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004076 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4077 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004078 mOutput.mState.needsFiltering = false;
4079 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004080
Lloyd Piquea4863342019-12-04 18:45:02 -08004081 Layer leftLayer;
4082 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004083
Lloyd Piquea4863342019-12-04 18:45:02 -08004084 leftLayer.mOutputLayerState.clearClientTarget = false;
4085 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4086 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004087 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004088
Lloyd Piquea4863342019-12-04 18:45:02 -08004089 rightLayer.mOutputLayerState.clearClientTarget = false;
4090 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4091 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004092 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004093
4094 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4095 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4096 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4097 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4098 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4099
4100 Region accumClearRegion(Rect(10, 11, 12, 13));
4101
4102 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4103 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004104 false, /* needs filtering */
4105 true, /* secure */
4106 true, /* supports protected content */
4107 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004108 kPortraitViewport,
4109 kOutputDataspace,
4110 true /* realContentIsVisible */,
4111 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004112 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004113 };
4114
4115 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4116 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004117 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4118 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004119
4120 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4121 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004122 false, /* needs filtering */
4123 true, /* secure */
4124 true, /* supports protected content */
4125 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004126 kPortraitViewport,
4127 kOutputDataspace,
4128 true /* realContentIsVisible */,
4129 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004130 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004131 };
4132
4133 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4134 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004135 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4136 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004137
4138 constexpr bool supportsProtectedContent = true;
4139 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4140 accumClearRegion, kOutputDataspace);
4141 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004142 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4143 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004144}
4145
Vishnu Naira483b4a2019-12-12 15:07:52 -08004146TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4147 shadowRegionOnlyVisibleSkipsContentComposition) {
4148 const Rect kContentWithShadow(40, 40, 70, 90);
4149 const Rect kContent(50, 50, 60, 80);
4150 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4151 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4152
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004153 Region accumClearRegion(Rect(10, 11, 12, 13));
4154 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4155 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004156 false, /* needs filtering */
4157 false, /* secure */
4158 false, /* supports protected content */
4159 accumClearRegion,
4160 kDisplayViewport,
4161 kDisplayDataspace,
4162 false /* realContentIsVisible */,
4163 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004164 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004165 };
4166
Vishnu Nair9b079a22020-01-21 14:36:08 -08004167 LayerFE::LayerSettings mShadowSettings;
4168 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004169
4170 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4171 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4172
4173 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4174 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004175 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4176 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004177
Vishnu Naira483b4a2019-12-12 15:07:52 -08004178 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4179 accumClearRegion, kDisplayDataspace);
4180 ASSERT_EQ(1u, requests.size());
4181
Vishnu Nair9b079a22020-01-21 14:36:08 -08004182 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004183}
4184
4185TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4186 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4187 const Rect kContentWithShadow(40, 40, 70, 90);
4188 const Rect kContent(50, 50, 60, 80);
4189 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4190 const Region kPartialContentWithPartialShadowRegion =
4191 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4192
Vishnu Nair9b079a22020-01-21 14:36:08 -08004193 LayerFE::LayerSettings mShadowSettings;
4194 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004195
4196 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4197 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4198
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004199 Region accumClearRegion(Rect(10, 11, 12, 13));
4200 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4201 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004202 false, /* needs filtering */
4203 false, /* secure */
4204 false, /* supports protected content */
4205 accumClearRegion,
4206 kDisplayViewport,
4207 kDisplayDataspace,
4208 true /* realContentIsVisible */,
4209 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004210 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004211 };
4212
Vishnu Naira483b4a2019-12-12 15:07:52 -08004213 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4214 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004215 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4216 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4217 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004218
Vishnu Naira483b4a2019-12-12 15:07:52 -08004219 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4220 accumClearRegion, kDisplayDataspace);
4221 ASSERT_EQ(2u, requests.size());
4222
Vishnu Nair9b079a22020-01-21 14:36:08 -08004223 EXPECT_EQ(mShadowSettings, requests[0]);
4224 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004225}
4226
Lloyd Pique32cbe282018-10-19 13:09:22 -07004227} // namespace
4228} // namespace android::compositionengine