blob: ac8fc88f96d9382cb96c279d98599fb08a26c330 [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));
2955
Lloyd Piquea76ce462020-01-14 13:06:37 -08002956 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2957
Lloyd Pique6818fa52019-12-03 12:32:13 -08002958 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002959}
2960
Lloyd Piquee9eff972020-05-05 12:36:44 -07002961TEST_F(OutputComposeSurfacesTest,
2962 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2963 mOutput.mState.usesClientComposition = false;
2964 mOutput.mState.flipClientTarget = true;
2965
Lloyd Pique6818fa52019-12-03 12:32:13 -08002966 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002967
2968 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2969 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2970
2971 verify().execute().expectAFenceWasReturned();
2972}
2973
2974TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2975 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2976
2977 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2978
2979 verify().execute().expectNoFenceWasReturned();
2980}
2981
2982TEST_F(OutputComposeSurfacesTest,
2983 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2984 mOutput.mState.usesClientComposition = false;
2985 mOutput.mState.flipClientTarget = true;
2986
2987 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002988
Lloyd Pique6818fa52019-12-03 12:32:13 -08002989 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002990
Lloyd Pique6818fa52019-12-03 12:32:13 -08002991 verify().execute().expectNoFenceWasReturned();
2992}
Lloyd Pique56eba802019-08-28 15:45:25 -07002993
Lloyd Pique6818fa52019-12-03 12:32:13 -08002994TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2995 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2996 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2997 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2998 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002999 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003000 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3001 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003002
Lloyd Pique6818fa52019-12-03 12:32:13 -08003003 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3004 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
3005 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003006
Lloyd Pique6818fa52019-12-03 12:32:13 -08003007 verify().execute().expectAFenceWasReturned();
3008}
Lloyd Pique56eba802019-08-28 15:45:25 -07003009
Lloyd Pique6818fa52019-12-03 12:32:13 -08003010TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003011 LayerFE::LayerSettings r1;
3012 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003013
3014 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3015 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3016
3017 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3018 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3019 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3020 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003021 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003022 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3023 .WillRepeatedly(
3024 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003025 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003026 clientCompositionLayers.emplace_back(r2);
3027 }));
3028
3029 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003030 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003031 .WillRepeatedly(Return(NO_ERROR));
3032
3033 verify().execute().expectAFenceWasReturned();
3034}
3035
Vishnu Nair9b079a22020-01-21 14:36:08 -08003036TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3037 mOutput.cacheClientCompositionRequests(0);
3038 LayerFE::LayerSettings r1;
3039 LayerFE::LayerSettings r2;
3040
3041 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3042 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3043
3044 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3045 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3046 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3047 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3048 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3049 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3050 .WillRepeatedly(Return());
3051
3052 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3053 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3054 .Times(2)
3055 .WillOnce(Return(NO_ERROR));
3056
3057 verify().execute().expectAFenceWasReturned();
3058 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3059
3060 verify().execute().expectAFenceWasReturned();
3061 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3062}
3063
3064TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3065 mOutput.cacheClientCompositionRequests(3);
3066 LayerFE::LayerSettings r1;
3067 LayerFE::LayerSettings r2;
3068
3069 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3070 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3071
3072 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3073 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3074 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3075 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3076 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3077 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3078 .WillRepeatedly(Return());
3079
3080 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3081 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3082 .WillOnce(Return(NO_ERROR));
3083 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3084
3085 verify().execute().expectAFenceWasReturned();
3086 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3087
3088 // We do not expect another call to draw layers.
3089 verify().execute().expectAFenceWasReturned();
3090 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3091}
3092
3093TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3094 LayerFE::LayerSettings r1;
3095 LayerFE::LayerSettings r2;
3096
3097 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3098 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3099
3100 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3101 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3102 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3103 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3104 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3105 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3106 .WillRepeatedly(Return());
3107
3108 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3109 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3110 .WillOnce(Return(mOutputBuffer))
3111 .WillOnce(Return(otherOutputBuffer));
3112 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3113 .WillRepeatedly(Return(NO_ERROR));
3114
3115 verify().execute().expectAFenceWasReturned();
3116 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3117
3118 verify().execute().expectAFenceWasReturned();
3119 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3120}
3121
3122TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3123 LayerFE::LayerSettings r1;
3124 LayerFE::LayerSettings r2;
3125 LayerFE::LayerSettings r3;
3126
3127 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3128 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3129 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3130
3131 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3132 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3133 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3134 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3135 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3136 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3137 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3138 .WillRepeatedly(Return());
3139
3140 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3141 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3142 .WillOnce(Return(NO_ERROR));
3143 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3144 .WillOnce(Return(NO_ERROR));
3145
3146 verify().execute().expectAFenceWasReturned();
3147 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3148
3149 verify().execute().expectAFenceWasReturned();
3150 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3151}
3152
Lloyd Pique6818fa52019-12-03 12:32:13 -08003153struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3154 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3155 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3156 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003157 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003158 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3159 .WillRepeatedly(Return());
3160 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3161 }
3162
3163 struct MixedCompositionState
3164 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3165 auto ifMixedCompositionIs(bool used) {
3166 getInstance()->mOutput.mState.usesDeviceComposition = used;
3167 return nextState<OutputUsesHdrState>();
3168 }
3169 };
3170
3171 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3172 auto andIfUsesHdr(bool used) {
3173 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3174 .WillOnce(Return(used));
3175 return nextState<SkipColorTransformState>();
3176 }
3177 };
3178
3179 struct SkipColorTransformState
3180 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3181 auto andIfSkipColorTransform(bool skip) {
3182 // May be called zero or one times.
3183 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3184 .WillRepeatedly(Return(skip));
3185 return nextState<ExpectDisplaySettingsState>();
3186 }
3187 };
3188
3189 struct ExpectDisplaySettingsState
3190 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3191 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3192 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3193 .WillOnce(Return(NO_ERROR));
3194 return nextState<ExecuteState>();
3195 }
3196 };
3197
3198 // Call this member function to start using the mini-DSL defined above.
3199 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3200};
3201
3202TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3203 verify().ifMixedCompositionIs(true)
3204 .andIfUsesHdr(true)
3205 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003206 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003207 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003208 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003209 .execute()
3210 .expectAFenceWasReturned();
3211}
3212
3213TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3214 verify().ifMixedCompositionIs(true)
3215 .andIfUsesHdr(false)
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, forHdrOnlyClientComposition) {
3225 verify().ifMixedCompositionIs(false)
3226 .andIfUsesHdr(true)
3227 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003228 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003229 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003230 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003231 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003232 .execute()
3233 .expectAFenceWasReturned();
3234}
3235
3236TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3237 verify().ifMixedCompositionIs(false)
3238 .andIfUsesHdr(false)
3239 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003240 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003241 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003242 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003243 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003244 .execute()
3245 .expectAFenceWasReturned();
3246}
3247
3248TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3249 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3250 verify().ifMixedCompositionIs(false)
3251 .andIfUsesHdr(true)
3252 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003253 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003254 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003255 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003256 .execute()
3257 .expectAFenceWasReturned();
3258}
3259
3260struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3261 struct Layer {
3262 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003263 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3264 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003265 }
3266
3267 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003268 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003269 LayerFECompositionState mLayerFEState;
3270 };
3271
3272 OutputComposeSurfacesTest_HandlesProtectedContent() {
3273 mLayer1.mLayerFEState.hasProtectedContent = false;
3274 mLayer2.mLayerFEState.hasProtectedContent = false;
3275
3276 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3277 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3278 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3279 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3280 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3281
3282 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3283
3284 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3285
3286 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003287 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003288 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3289 .WillRepeatedly(Return());
3290 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3291 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3292 .WillRepeatedly(Return(NO_ERROR));
3293 }
3294
3295 Layer mLayer1;
3296 Layer mLayer2;
3297};
3298
3299TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3300 mOutput.mState.isSecure = false;
3301 mLayer2.mLayerFEState.hasProtectedContent = true;
3302 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3303
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003304 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003305}
3306
3307TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3308 mOutput.mState.isSecure = true;
3309 mLayer2.mLayerFEState.hasProtectedContent = true;
3310 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3311
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003312 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003313}
3314
3315TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3316 mOutput.mState.isSecure = true;
3317 mLayer2.mLayerFEState.hasProtectedContent = false;
3318 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3319 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3320 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3321 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3322 EXPECT_CALL(*mRenderSurface, setProtected(false));
3323
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003324 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003325}
3326
3327TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3328 mOutput.mState.isSecure = true;
3329 mLayer2.mLayerFEState.hasProtectedContent = true;
3330 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3331
3332 // For this test, we also check the call order of key functions.
3333 InSequence seq;
3334
3335 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3336 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3337 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3338 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3339 EXPECT_CALL(*mRenderSurface, setProtected(true));
3340 // Must happen after setting the protected content state.
3341 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3342 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3343
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003344 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003345}
3346
3347TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3348 mOutput.mState.isSecure = true;
3349 mLayer2.mLayerFEState.hasProtectedContent = true;
3350 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3351 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3352 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3353
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003354 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003355}
3356
3357TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3358 mOutput.mState.isSecure = true;
3359 mLayer2.mLayerFEState.hasProtectedContent = true;
3360 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3361 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3362 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3363 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3364
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003365 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003366}
3367
3368TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3369 mOutput.mState.isSecure = true;
3370 mLayer2.mLayerFEState.hasProtectedContent = true;
3371 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3372 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3373 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3374 EXPECT_CALL(*mRenderSurface, setProtected(true));
3375
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003376 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003377}
3378
3379TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3380 mOutput.mState.isSecure = true;
3381 mLayer2.mLayerFEState.hasProtectedContent = true;
3382 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3383 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3384 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3385 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3386
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003387 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003388}
3389
3390struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3391 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3392 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3393 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3394 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3395 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3396 .WillRepeatedly(Return());
3397 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3398 }
3399};
3400
3401TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3402 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3403
3404 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003405 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406
3407 // For this test, we also check the call order of key functions.
3408 InSequence seq;
3409
3410 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3411 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003413 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3414}
3415
3416struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3417 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3418 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3419 mLayer.layerFEState.backgroundBlurRadius = 10;
3420 mOutput.editState().isEnabled = true;
3421
Snild Dolkow9e217d62020-04-22 15:53:42 +02003422 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003423 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3424 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3425 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3426 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3427 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3428 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3429 .WillRepeatedly(Return(&mLayer.outputLayer));
3430 }
3431
3432 NonInjectedLayer mLayer;
3433 compositionengine::CompositionRefreshArgs mRefreshArgs;
3434};
3435
3436TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3437 mRefreshArgs.blursAreExpensive = true;
3438 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3439
3440 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3441 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3442}
3443
3444TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3445 mRefreshArgs.blursAreExpensive = false;
3446 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3447
3448 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3449 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003450}
3451
3452/*
3453 * Output::generateClientCompositionRequests()
3454 */
3455
3456struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003457 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003458 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003459 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003460 bool supportsProtectedContent, Region& clearRegion,
3461 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003462 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003463 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003464 }
3465 };
3466
Lloyd Piquea4863342019-12-04 18:45:02 -08003467 struct Layer {
3468 Layer() {
3469 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3470 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003471 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003472 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003473 }
3474
3475 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003476 StrictMock<mock::LayerFE> mLayerFE;
3477 LayerFECompositionState mLayerFEState;
3478 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003479 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003480 };
3481
Lloyd Pique56eba802019-08-28 15:45:25 -07003482 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003483 mOutput.mState.needsFiltering = false;
3484
Lloyd Pique56eba802019-08-28 15:45:25 -07003485 mOutput.setDisplayColorProfileForTest(
3486 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3487 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3488 }
3489
Lloyd Pique56eba802019-08-28 15:45:25 -07003490 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3491 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003492 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003493};
3494
Lloyd Piquea4863342019-12-04 18:45:02 -08003495struct GenerateClientCompositionRequestsTest_ThreeLayers
3496 : public GenerateClientCompositionRequestsTest {
3497 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003498 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3499 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3500 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003501 mOutput.mState.transform =
3502 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3503 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003504 mOutput.mState.needsFiltering = false;
3505 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003506
Lloyd Piquea4863342019-12-04 18:45:02 -08003507 for (size_t i = 0; i < mLayers.size(); i++) {
3508 mLayers[i].mOutputLayerState.clearClientTarget = false;
3509 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3510 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003511 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003512 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003513 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3514 mLayers[i].mLayerSettings.alpha = 1.0f;
3515 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003516
Lloyd Piquea4863342019-12-04 18:45:02 -08003517 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3518 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3519 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3520 .WillRepeatedly(Return(true));
3521 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3522 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003523
Lloyd Piquea4863342019-12-04 18:45:02 -08003524 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3525 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003526
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003527 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003528 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003529
Lloyd Piquea4863342019-12-04 18:45:02 -08003530 static const Rect kDisplayFrame;
3531 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003532 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003533
Lloyd Piquea4863342019-12-04 18:45:02 -08003534 std::array<Layer, 3> mLayers;
3535};
Lloyd Pique56eba802019-08-28 15:45:25 -07003536
Lloyd Piquea4863342019-12-04 18:45:02 -08003537const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3538const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003539const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3540 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003541
Lloyd Piquea4863342019-12-04 18:45:02 -08003542TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3543 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3544 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3545 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003546
Lloyd Piquea4863342019-12-04 18:45:02 -08003547 Region accumClearRegion(Rect(10, 11, 12, 13));
3548 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3549 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003550 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003551 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003552}
3553
Lloyd Piquea4863342019-12-04 18:45:02 -08003554TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3555 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3556 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3557 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3558
3559 Region accumClearRegion(Rect(10, 11, 12, 13));
3560 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3561 accumClearRegion, kDisplayDataspace);
3562 EXPECT_EQ(0u, requests.size());
3563 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3564}
3565
3566TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003567 LayerFE::LayerSettings mShadowSettings;
3568 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003569
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003570 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3571 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3572 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3573 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3574 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3575 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3576 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003577
3578 Region accumClearRegion(Rect(10, 11, 12, 13));
3579 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3580 accumClearRegion, kDisplayDataspace);
3581 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003582 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3583 EXPECT_EQ(mShadowSettings, requests[1]);
3584 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003585
3586 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3587
3588 // Check that a timestamp was set for the layers that generated requests
3589 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3590 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3591 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3592}
3593
3594TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3595 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3596 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3597 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3598 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3599
3600 mLayers[0].mOutputLayerState.clearClientTarget = false;
3601 mLayers[1].mOutputLayerState.clearClientTarget = false;
3602 mLayers[2].mOutputLayerState.clearClientTarget = false;
3603
3604 mLayers[0].mLayerFEState.isOpaque = true;
3605 mLayers[1].mLayerFEState.isOpaque = true;
3606 mLayers[2].mLayerFEState.isOpaque = true;
3607
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003608 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3609 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003610
3611 Region accumClearRegion(Rect(10, 11, 12, 13));
3612 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3613 accumClearRegion, kDisplayDataspace);
3614 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003615 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003616
3617 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3618}
3619
3620TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3621 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3622 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3623 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3624 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3625
3626 mLayers[0].mOutputLayerState.clearClientTarget = true;
3627 mLayers[1].mOutputLayerState.clearClientTarget = true;
3628 mLayers[2].mOutputLayerState.clearClientTarget = true;
3629
3630 mLayers[0].mLayerFEState.isOpaque = false;
3631 mLayers[1].mLayerFEState.isOpaque = false;
3632 mLayers[2].mLayerFEState.isOpaque = false;
3633
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003634 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3635 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003636
3637 Region accumClearRegion(Rect(10, 11, 12, 13));
3638 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3639 accumClearRegion, kDisplayDataspace);
3640 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003641 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003642
3643 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3644}
3645
3646TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003647 // If client composition is performed with some layers set to use device
3648 // composition, device layers after the first layer (device or client) will
3649 // clear the frame buffer if they are opaque and if that layer has a flag
3650 // set to do so. The first layer is skipped as the frame buffer is already
3651 // expected to be clear.
3652
Lloyd Piquea4863342019-12-04 18:45:02 -08003653 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3654 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3655 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003656
Lloyd Piquea4863342019-12-04 18:45:02 -08003657 mLayers[0].mOutputLayerState.clearClientTarget = true;
3658 mLayers[1].mOutputLayerState.clearClientTarget = true;
3659 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003660
Lloyd Piquea4863342019-12-04 18:45:02 -08003661 mLayers[0].mLayerFEState.isOpaque = true;
3662 mLayers[1].mLayerFEState.isOpaque = true;
3663 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003664 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003665 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003666
3667 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3668 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003669 false, /* needs filtering */
3670 false, /* secure */
3671 false, /* supports protected content */
3672 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003673 kDisplayViewport,
3674 kDisplayDataspace,
3675 false /* realContentIsVisible */,
3676 true /* clearContent */,
3677 };
3678 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3679 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003680 false, /* needs filtering */
3681 false, /* secure */
3682 false, /* supports protected content */
3683 accumClearRegion,
3684 kDisplayViewport,
3685 kDisplayDataspace,
3686 true /* realContentIsVisible */,
3687 false /* clearContent */,
3688 };
3689
3690 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3691 mBlackoutSettings.source.buffer.buffer = nullptr;
3692 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3693 mBlackoutSettings.alpha = 0.f;
3694 mBlackoutSettings.disableBlending = true;
3695
3696 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3697 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3698 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3699 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3700
Lloyd Piquea4863342019-12-04 18:45:02 -08003701 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3702 accumClearRegion, kDisplayDataspace);
3703 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003704
Lloyd Piquea4863342019-12-04 18:45:02 -08003705 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003706 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003707
Vishnu Nair9b079a22020-01-21 14:36:08 -08003708 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003709
Lloyd Piquea4863342019-12-04 18:45:02 -08003710 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3711}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003712
Lloyd Piquea4863342019-12-04 18:45:02 -08003713TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3714 clippedVisibleRegionUsedToGenerateRequest) {
3715 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3716 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3717 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 Region accumClearRegion(Rect(10, 11, 12, 13));
3720
3721 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3722 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 false, /* needs filtering */
3724 false, /* secure */
3725 false, /* supports protected content */
3726 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003727 kDisplayViewport,
3728 kDisplayDataspace,
3729 true /* realContentIsVisible */,
3730 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003731 };
3732 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3733 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003734 false, /* needs filtering */
3735 false, /* secure */
3736 false, /* supports protected content */
3737 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003738 kDisplayViewport,
3739 kDisplayDataspace,
3740 true /* realContentIsVisible */,
3741 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 };
3743 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3744 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003745 false, /* needs filtering */
3746 false, /* secure */
3747 false, /* supports protected content */
3748 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003749 kDisplayViewport,
3750 kDisplayDataspace,
3751 true /* realContentIsVisible */,
3752 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003753 };
3754
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003755 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3756 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3757 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3758 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3759 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3760 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003761
3762 static_cast<void>(
3763 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3764 accumClearRegion, kDisplayDataspace));
3765}
3766
3767TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3768 perLayerNeedsFilteringUsedToGenerateRequests) {
3769 mOutput.mState.needsFiltering = false;
3770 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3771
3772 Region accumClearRegion(Rect(10, 11, 12, 13));
3773
3774 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3775 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003776 true, /* needs filtering */
3777 false, /* secure */
3778 false, /* supports protected content */
3779 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003780 kDisplayViewport,
3781 kDisplayDataspace,
3782 true /* realContentIsVisible */,
3783 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003784 };
3785 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3786 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003787 false, /* needs filtering */
3788 false, /* secure */
3789 false, /* supports protected content */
3790 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003791 kDisplayViewport,
3792 kDisplayDataspace,
3793 true /* realContentIsVisible */,
3794 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003795 };
3796 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3797 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003798 false, /* needs filtering */
3799 false, /* secure */
3800 false, /* supports protected content */
3801 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003802 kDisplayViewport,
3803 kDisplayDataspace,
3804 true /* realContentIsVisible */,
3805 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003806 };
3807
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003808 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3809 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3810 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3811 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3812 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3813 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003814
3815 static_cast<void>(
3816 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3817 accumClearRegion, kDisplayDataspace));
3818}
3819
3820TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3821 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3822 mOutput.mState.needsFiltering = true;
3823 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3824
3825 Region accumClearRegion(Rect(10, 11, 12, 13));
3826
3827 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3828 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003829 true, /* needs filtering */
3830 false, /* secure */
3831 false, /* supports protected content */
3832 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003833 kDisplayViewport,
3834 kDisplayDataspace,
3835 true /* realContentIsVisible */,
3836 false /* clearContent */,
3837
Lloyd Piquea4863342019-12-04 18:45:02 -08003838 };
3839 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3840 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003841 true, /* needs filtering */
3842 false, /* secure */
3843 false, /* supports protected content */
3844 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003845 kDisplayViewport,
3846 kDisplayDataspace,
3847 true /* realContentIsVisible */,
3848 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 };
3850 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3851 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003852 true, /* needs filtering */
3853 false, /* secure */
3854 false, /* supports protected content */
3855 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003856 kDisplayViewport,
3857 kDisplayDataspace,
3858 true /* realContentIsVisible */,
3859 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003860 };
3861
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003862 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3863 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3864 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3865 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3866 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3867 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003868
3869 static_cast<void>(
3870 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3871 accumClearRegion, kDisplayDataspace));
3872}
3873
3874TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3875 wholeOutputSecurityUsedToGenerateRequests) {
3876 mOutput.mState.isSecure = true;
3877
3878 Region accumClearRegion(Rect(10, 11, 12, 13));
3879
3880 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3881 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003882 false, /* needs filtering */
3883 true, /* secure */
3884 false, /* supports protected content */
3885 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003886 kDisplayViewport,
3887 kDisplayDataspace,
3888 true /* realContentIsVisible */,
3889 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 };
3891 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3892 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003893 false, /* needs filtering */
3894 true, /* secure */
3895 false, /* supports protected content */
3896 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003897 kDisplayViewport,
3898 kDisplayDataspace,
3899 true /* realContentIsVisible */,
3900 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003901 };
3902 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3903 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003904 false, /* needs filtering */
3905 true, /* secure */
3906 false, /* supports protected content */
3907 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003908 kDisplayViewport,
3909 kDisplayDataspace,
3910 true /* realContentIsVisible */,
3911 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003912 };
3913
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003914 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3915 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3916 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3918 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3919 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003920
3921 static_cast<void>(
3922 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3923 accumClearRegion, kDisplayDataspace));
3924}
3925
3926TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3927 protectedContentSupportUsedToGenerateRequests) {
3928 Region accumClearRegion(Rect(10, 11, 12, 13));
3929
3930 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3931 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 false, /* needs filtering */
3933 false, /* secure */
3934 true, /* supports protected content */
3935 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003936 kDisplayViewport,
3937 kDisplayDataspace,
3938 true /* realContentIsVisible */,
3939 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003940 };
3941 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3942 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003943 false, /* needs filtering */
3944 false, /* secure */
3945 true, /* supports protected content */
3946 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003947 kDisplayViewport,
3948 kDisplayDataspace,
3949 true /* realContentIsVisible */,
3950 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003951 };
3952 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3953 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003954 false, /* needs filtering */
3955 false, /* secure */
3956 true, /* supports protected content */
3957 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003958 kDisplayViewport,
3959 kDisplayDataspace,
3960 true /* realContentIsVisible */,
3961 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003962 };
3963
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003964 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3965 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3966 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3967 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3968 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3969 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003970
3971 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3972 accumClearRegion,
3973 kDisplayDataspace));
3974}
3975
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003976TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003977 InjectedLayer layer1;
3978 InjectedLayer layer2;
3979 InjectedLayer layer3;
3980
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003981 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003982 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003983 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003984 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003985 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003986 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003987 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003988
Lloyd Piquede196652020-01-22 17:29:58 -08003989 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003990
Lloyd Piquede196652020-01-22 17:29:58 -08003991 injectOutputLayer(layer1);
3992 injectOutputLayer(layer2);
3993 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003994
3995 mOutput->editState().isEnabled = true;
3996
3997 CompositionRefreshArgs args;
3998 args.updatingGeometryThisFrame = false;
3999 args.devOptForceClientComposition = false;
4000 mOutput->updateAndWriteCompositionState(args);
4001}
4002
Lloyd Piquea4863342019-12-04 18:45:02 -08004003TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4004 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4005 // one layer on the left covering the left side of the output, and one layer
4006 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004007
4008 const Rect kPortraitFrame(0, 0, 1000, 2000);
4009 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004010 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004011 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004012 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004013
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004014 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4015 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4016 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004017 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4018 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004019 mOutput.mState.needsFiltering = false;
4020 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004021
Lloyd Piquea4863342019-12-04 18:45:02 -08004022 Layer leftLayer;
4023 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004024
Lloyd Piquea4863342019-12-04 18:45:02 -08004025 leftLayer.mOutputLayerState.clearClientTarget = false;
4026 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4027 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004028 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004029
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 rightLayer.mOutputLayerState.clearClientTarget = false;
4031 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4032 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004033 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004034
4035 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4036 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4037 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4038 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4039 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4040
4041 Region accumClearRegion(Rect(10, 11, 12, 13));
4042
4043 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4044 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004045 false, /* needs filtering */
4046 true, /* secure */
4047 true, /* supports protected content */
4048 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 kPortraitViewport,
4050 kOutputDataspace,
4051 true /* realContentIsVisible */,
4052 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004053 };
4054
4055 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4056 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004057 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4058 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004059
4060 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4061 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004062 false, /* needs filtering */
4063 true, /* secure */
4064 true, /* supports protected content */
4065 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004066 kPortraitViewport,
4067 kOutputDataspace,
4068 true /* realContentIsVisible */,
4069 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004070 };
4071
4072 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4073 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004074 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4075 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004076
4077 constexpr bool supportsProtectedContent = true;
4078 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4079 accumClearRegion, kOutputDataspace);
4080 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004081 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4082 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004083}
4084
Vishnu Naira483b4a2019-12-12 15:07:52 -08004085TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4086 shadowRegionOnlyVisibleSkipsContentComposition) {
4087 const Rect kContentWithShadow(40, 40, 70, 90);
4088 const Rect kContent(50, 50, 60, 80);
4089 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4090 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4091
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004092 Region accumClearRegion(Rect(10, 11, 12, 13));
4093 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4094 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004095 false, /* needs filtering */
4096 false, /* secure */
4097 false, /* supports protected content */
4098 accumClearRegion,
4099 kDisplayViewport,
4100 kDisplayDataspace,
4101 false /* realContentIsVisible */,
4102 false /* clearContent */,
4103 };
4104
Vishnu Nair9b079a22020-01-21 14:36:08 -08004105 LayerFE::LayerSettings mShadowSettings;
4106 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004107
4108 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4109 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4110
4111 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4112 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004113 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4114 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004115
Vishnu Naira483b4a2019-12-12 15:07:52 -08004116 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4117 accumClearRegion, kDisplayDataspace);
4118 ASSERT_EQ(1u, requests.size());
4119
Vishnu Nair9b079a22020-01-21 14:36:08 -08004120 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004121}
4122
4123TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4124 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4125 const Rect kContentWithShadow(40, 40, 70, 90);
4126 const Rect kContent(50, 50, 60, 80);
4127 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4128 const Region kPartialContentWithPartialShadowRegion =
4129 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4130
Vishnu Nair9b079a22020-01-21 14:36:08 -08004131 LayerFE::LayerSettings mShadowSettings;
4132 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004133
4134 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4135 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4136
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 Region accumClearRegion(Rect(10, 11, 12, 13));
4138 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4139 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004140 false, /* needs filtering */
4141 false, /* secure */
4142 false, /* supports protected content */
4143 accumClearRegion,
4144 kDisplayViewport,
4145 kDisplayDataspace,
4146 true /* realContentIsVisible */,
4147 false /* clearContent */,
4148 };
4149
Vishnu Naira483b4a2019-12-12 15:07:52 -08004150 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4151 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004152 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4153 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4154 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004155
Vishnu Naira483b4a2019-12-12 15:07:52 -08004156 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4157 accumClearRegion, kDisplayDataspace);
4158 ASSERT_EQ(2u, requests.size());
4159
Vishnu Nair9b079a22020-01-21 14:36:08 -08004160 EXPECT_EQ(mShadowSettings, requests[0]);
4161 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004162}
4163
Lloyd Pique32cbe282018-10-19 13:09:22 -07004164} // namespace
4165} // namespace android::compositionengine