blob: 1e10365233b365cca9d80d20753c573cce0054a1 [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));
271}
272
273TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
274 const Rect displayRect{0, 0, 1000, 2000};
275 const Rect framebufferRect{0, 0, 500, 1000};
276 mOutput->editState().displaySpace.bounds = displayRect;
277 mOutput->editState().framebufferSpace.bounds = framebufferRect;
278
279 const ui::Rotation orientation = ui::ROTATION_90;
280 const Rect frame{50, 60, 100, 100};
281 const Rect viewport{10, 20, 30, 40};
282
283 mOutput->setProjection(orientation, viewport, frame);
284
285 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
286 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
287 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
288
289 const auto state = mOutput->getState();
290 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
291 EXPECT_EQ(viewport, state.layerStackSpace.content);
292 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
293
294 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
295 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
296 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
297
298 EXPECT_EQ(displayRect, state.displaySpace.bounds);
299 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
300 EXPECT_EQ(orientation, state.displaySpace.orientation);
301
302 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
303 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
304 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
305
306 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307}
308
Lloyd Pique66d68602019-02-13 14:23:31 -0800309/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200310 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700311 */
312
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200313TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
314 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
315 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
316 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
317 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
318 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
319 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
320 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
321 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
322 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
323 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700324
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200325 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700326
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200327 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700328
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200329 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700330
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200331 const auto state = mOutput->getState();
332
333 const Rect displayRect(newDisplaySize);
334 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
335 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
336 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200337
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200338 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
339 EXPECT_EQ(Rect(0, 0, 900, 450), state.orientedDisplaySpace.content);
340 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200342 EXPECT_EQ(displayRect, state.displaySpace.bounds);
343 EXPECT_EQ(Rect(0, 0, 450, 900), state.displaySpace.content);
344 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200346 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
347 EXPECT_EQ(Rect(0, 0, 450, 900), state.framebufferSpace.content);
348 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
349
350 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
351
352 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700353}
354
Lloyd Pique66d68602019-02-13 14:23:31 -0800355/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700356 * Output::setLayerStackFilter()
357 */
358
359TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700360 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700361 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700362
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700363 EXPECT_TRUE(mOutput->getState().layerStackInternal);
364 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700365
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700366 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700367}
368
Lloyd Pique66d68602019-02-13 14:23:31 -0800369/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700370 * Output::setColorTransform
371 */
372
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800373TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700374 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800376 // If no colorTransformMatrix is set the update should be skipped.
377 CompositionRefreshArgs refreshArgs;
378 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700379
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700380 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700381
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800382 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700383 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800384
385 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700386 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800387}
Lloyd Piqueef958122019-02-05 18:00:12 -0800388
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800389TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700391
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800392 // Attempting to set the same colorTransformMatrix that is already set should
393 // also skip the update.
394 CompositionRefreshArgs refreshArgs;
395 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700396
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700397 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700398
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800399 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700400 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800401
402 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700403 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800404}
405
406TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700407 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800408
409 // Setting a different colorTransformMatrix should perform the update.
410 CompositionRefreshArgs refreshArgs;
411 refreshArgs.colorTransformMatrix = kIdentity;
412
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700413 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800414
415 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700416 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800417
418 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700419 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800420}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700421
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800422TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700423 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700424
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800425 // Setting a different colorTransformMatrix should perform the update.
426 CompositionRefreshArgs refreshArgs;
427 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700428
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700429 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800430
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800431 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800433
434 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436}
437
438TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700439 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440
441 // Setting a different colorTransformMatrix should perform the update.
442 CompositionRefreshArgs refreshArgs;
443 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
444
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700445 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800446
447 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700448 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449
450 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700452}
453
Lloyd Pique66d68602019-02-13 14:23:31 -0800454/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800455 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456 */
457
Lloyd Pique17ca7422019-11-14 14:24:10 -0800458using OutputSetColorProfileTest = OutputTest;
459
460TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800461 using ColorProfile = Output::ColorProfile;
462
Lloyd Piquef5275482019-01-29 18:42:42 -0800463 EXPECT_CALL(*mDisplayColorProfile,
464 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
465 ui::Dataspace::UNKNOWN))
466 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800467 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700468
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700469 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
470 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
471 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700472
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
474 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
475 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
476 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800477
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800479}
480
Lloyd Pique17ca7422019-11-14 14:24:10 -0800481TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800482 using ColorProfile = Output::ColorProfile;
483
Lloyd Piquef5275482019-01-29 18:42:42 -0800484 EXPECT_CALL(*mDisplayColorProfile,
485 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
486 ui::Dataspace::UNKNOWN))
487 .WillOnce(Return(ui::Dataspace::UNKNOWN));
488
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700489 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
490 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
491 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
492 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800493
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700494 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
495 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
496 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800497
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700499}
500
Lloyd Pique66d68602019-02-13 14:23:31 -0800501/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700502 * Output::setRenderSurface()
503 */
504
505TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
506 const ui::Size newDisplaySize{640, 480};
507
508 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
509 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
510
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700511 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700512
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200513 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700514}
515
Lloyd Pique66d68602019-02-13 14:23:31 -0800516/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000517 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700518 */
519
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000520TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
521 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200522 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700523 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700524
525 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700527
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000528 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700529 }
530}
531
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000532TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
533 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200534 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700535 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536
537 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700538 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539
540 // The dirtyRegion should be clipped to the display bounds.
541 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
542 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700543}
544
Lloyd Pique66d68602019-02-13 14:23:31 -0800545/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800546 * Output::belongsInOutput()
547 */
548
549TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
550 const uint32_t layerStack1 = 123u;
551 const uint32_t layerStack2 = 456u;
552
553 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700554 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800555
Lloyd Piquec6687342019-03-07 21:34:57 -0800556 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700557 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
558 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800559
Lloyd Piqueef36b002019-01-23 17:52:04 -0800560 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
562 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
563 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
564 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800565
566 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700567 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800568
569 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700570 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
571 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
572 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
573 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800574}
575
Lloyd Piquede196652020-01-22 17:29:58 -0800576TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
577 NonInjectedLayer layer;
578 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800579
Lloyd Piquede196652020-01-22 17:29:58 -0800580 // If the layer has no composition state, it does not belong to any output.
581 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
582 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
583}
584
585TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
586 NonInjectedLayer layer;
587 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800588
589 const uint32_t layerStack1 = 123u;
590 const uint32_t layerStack2 = 456u;
591
592 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700593 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800594
Lloyd Pique66c20c42019-03-07 21:44:02 -0800595 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800596 layer.layerFEState.layerStackId = std::nullopt;
597 layer.layerFEState.internalOnly = false;
598 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800599
Lloyd Piquede196652020-01-22 17:29:58 -0800600 layer.layerFEState.layerStackId = std::nullopt;
601 layer.layerFEState.internalOnly = true;
602 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800603
604 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800605 layer.layerFEState.layerStackId = layerStack1;
606 layer.layerFEState.internalOnly = false;
607 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800608
Lloyd Piquede196652020-01-22 17:29:58 -0800609 layer.layerFEState.layerStackId = layerStack1;
610 layer.layerFEState.internalOnly = true;
611 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800612
Lloyd Piquede196652020-01-22 17:29:58 -0800613 layer.layerFEState.layerStackId = layerStack2;
614 layer.layerFEState.internalOnly = true;
615 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800616
Lloyd Piquede196652020-01-22 17:29:58 -0800617 layer.layerFEState.layerStackId = layerStack2;
618 layer.layerFEState.internalOnly = false;
619 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800620
621 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700622 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800623
Lloyd Pique66c20c42019-03-07 21:44:02 -0800624 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800625 layer.layerFEState.layerStackId = layerStack1;
626 layer.layerFEState.internalOnly = false;
627 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800628
Lloyd Piquede196652020-01-22 17:29:58 -0800629 layer.layerFEState.layerStackId = layerStack1;
630 layer.layerFEState.internalOnly = true;
631 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800632
Lloyd Piquede196652020-01-22 17:29:58 -0800633 layer.layerFEState.layerStackId = layerStack2;
634 layer.layerFEState.internalOnly = true;
635 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800636
Lloyd Piquede196652020-01-22 17:29:58 -0800637 layer.layerFEState.layerStackId = layerStack2;
638 layer.layerFEState.internalOnly = false;
639 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800640}
641
Lloyd Pique66d68602019-02-13 14:23:31 -0800642/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800643 * Output::getOutputLayerForLayer()
644 */
645
646TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800647 InjectedLayer layer1;
648 InjectedLayer layer2;
649 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800650
Lloyd Piquede196652020-01-22 17:29:58 -0800651 injectOutputLayer(layer1);
652 injectNullOutputLayer();
653 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800654
655 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800656 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
657 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800658
659 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800660 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
661 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
662 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800663
664 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800665 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
666 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
667 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800668}
669
Lloyd Pique66d68602019-02-13 14:23:31 -0800670/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800671 * Output::setReleasedLayers()
672 */
673
674using OutputSetReleasedLayersTest = OutputTest;
675
676TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
677 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
678 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
679 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
680
681 Output::ReleasedLayers layers;
682 layers.push_back(layer1FE);
683 layers.push_back(layer2FE);
684 layers.push_back(layer3FE);
685
686 mOutput->setReleasedLayers(std::move(layers));
687
688 const auto& setLayers = mOutput->getReleasedLayersForTest();
689 ASSERT_EQ(3u, setLayers.size());
690 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
691 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
692 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
693}
694
695/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800696 * Output::updateLayerStateFromFE()
697 */
698
Lloyd Piquede196652020-01-22 17:29:58 -0800699using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800700
701TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
702 CompositionRefreshArgs refreshArgs;
703
704 mOutput->updateLayerStateFromFE(refreshArgs);
705}
706
Lloyd Piquede196652020-01-22 17:29:58 -0800707TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
708 InjectedLayer layer1;
709 InjectedLayer layer2;
710 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800711
Lloyd Piquede196652020-01-22 17:29:58 -0800712 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
713 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
714 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
715
716 injectOutputLayer(layer1);
717 injectOutputLayer(layer2);
718 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800719
720 CompositionRefreshArgs refreshArgs;
721 refreshArgs.updatingGeometryThisFrame = false;
722
723 mOutput->updateLayerStateFromFE(refreshArgs);
724}
725
Lloyd Piquede196652020-01-22 17:29:58 -0800726TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
727 InjectedLayer layer1;
728 InjectedLayer layer2;
729 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800730
Lloyd Piquede196652020-01-22 17:29:58 -0800731 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
732 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
733 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
734
735 injectOutputLayer(layer1);
736 injectOutputLayer(layer2);
737 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800738
739 CompositionRefreshArgs refreshArgs;
740 refreshArgs.updatingGeometryThisFrame = true;
741
742 mOutput->updateLayerStateFromFE(refreshArgs);
743}
744
745/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800746 * Output::updateAndWriteCompositionState()
747 */
748
Lloyd Piquede196652020-01-22 17:29:58 -0800749using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800750
751TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
752 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800753
754 CompositionRefreshArgs args;
755 mOutput->updateAndWriteCompositionState(args);
756}
757
Lloyd Piqueef63b612019-11-14 13:19:56 -0800758TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800759 InjectedLayer layer1;
760 InjectedLayer layer2;
761 InjectedLayer layer3;
762
Lloyd Piqueef63b612019-11-14 13:19:56 -0800763 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800764
Lloyd Piquede196652020-01-22 17:29:58 -0800765 injectOutputLayer(layer1);
766 injectOutputLayer(layer2);
767 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800768
769 CompositionRefreshArgs args;
770 mOutput->updateAndWriteCompositionState(args);
771}
772
773TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800774 InjectedLayer layer1;
775 InjectedLayer layer2;
776 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800777
Snild Dolkow9e217d62020-04-22 15:53:42 +0200778 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800779 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200780 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800781 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200782 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800783 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
784
785 injectOutputLayer(layer1);
786 injectOutputLayer(layer2);
787 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800788
789 mOutput->editState().isEnabled = true;
790
791 CompositionRefreshArgs args;
792 args.updatingGeometryThisFrame = false;
793 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200794 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800795 mOutput->updateAndWriteCompositionState(args);
796}
797
798TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800799 InjectedLayer layer1;
800 InjectedLayer layer2;
801 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800802
Snild Dolkow9e217d62020-04-22 15:53:42 +0200803 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800804 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200805 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800806 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200807 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800808 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
809
810 injectOutputLayer(layer1);
811 injectOutputLayer(layer2);
812 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800813
814 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800815
816 CompositionRefreshArgs args;
817 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818 args.devOptForceClientComposition = false;
819 mOutput->updateAndWriteCompositionState(args);
820}
821
822TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800823 InjectedLayer layer1;
824 InjectedLayer layer2;
825 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800826
Snild Dolkow9e217d62020-04-22 15:53:42 +0200827 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800828 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200829 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800830 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800832 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
833
834 injectOutputLayer(layer1);
835 injectOutputLayer(layer2);
836 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800837
838 mOutput->editState().isEnabled = true;
839
840 CompositionRefreshArgs args;
841 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800842 args.devOptForceClientComposition = true;
843 mOutput->updateAndWriteCompositionState(args);
844}
845
846/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800847 * Output::prepareFrame()
848 */
849
850struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800851 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800852 // Sets up the helper functions called by the function under test to use
853 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800854 MOCK_METHOD0(chooseCompositionStrategy, void());
855 };
856
857 OutputPrepareFrameTest() {
858 mOutput.setDisplayColorProfileForTest(
859 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
860 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
861 }
862
863 StrictMock<mock::CompositionEngine> mCompositionEngine;
864 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
865 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700866 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800867};
868
869TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
870 mOutput.editState().isEnabled = false;
871
872 mOutput.prepareFrame();
873}
874
875TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
876 mOutput.editState().isEnabled = true;
877 mOutput.editState().usesClientComposition = false;
878 mOutput.editState().usesDeviceComposition = true;
879
880 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
881 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
882
883 mOutput.prepareFrame();
884}
885
886// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
887// base chooseCompositionStrategy() is invoked.
888TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700889 mOutput->editState().isEnabled = true;
890 mOutput->editState().usesClientComposition = false;
891 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800892
893 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
894
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700895 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800896
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700897 EXPECT_TRUE(mOutput->getState().usesClientComposition);
898 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800899}
900
Lloyd Pique56eba802019-08-28 15:45:25 -0700901/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800902 * Output::prepare()
903 */
904
905struct OutputPrepareTest : public testing::Test {
906 struct OutputPartialMock : public OutputPartialMockBase {
907 // Sets up the helper functions called by the function under test to use
908 // mock implementations.
909 MOCK_METHOD2(rebuildLayerStacks,
910 void(const compositionengine::CompositionRefreshArgs&,
911 compositionengine::LayerFESet&));
912 };
913
914 StrictMock<OutputPartialMock> mOutput;
915 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800916 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800917};
918
919TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
920 InSequence seq;
921 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
922
923 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
924}
925
926/*
927 * Output::rebuildLayerStacks()
928 */
929
930struct OutputRebuildLayerStacksTest : public testing::Test {
931 struct OutputPartialMock : public OutputPartialMockBase {
932 // Sets up the helper functions called by the function under test to use
933 // mock implementations.
934 MOCK_METHOD2(collectVisibleLayers,
935 void(const compositionengine::CompositionRefreshArgs&,
936 compositionengine::Output::CoverageState&));
937 };
938
939 OutputRebuildLayerStacksTest() {
940 mOutput.mState.isEnabled = true;
941 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200942 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800943
944 mRefreshArgs.updatingOutputGeometryThisFrame = true;
945
946 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
947
948 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
949 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
950 }
951
952 void setTestCoverageValues(const CompositionRefreshArgs&,
953 compositionengine::Output::CoverageState& state) {
954 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
955 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
956 state.dirtyRegion = mCoverageDirtyRegionToSet;
957 }
958
959 static const ui::Transform kIdentityTransform;
960 static const ui::Transform kRotate90Transform;
961 static const Rect kOutputBounds;
962
963 StrictMock<OutputPartialMock> mOutput;
964 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800965 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800966 Region mCoverageAboveCoveredLayersToSet;
967 Region mCoverageAboveOpaqueLayersToSet;
968 Region mCoverageDirtyRegionToSet;
969};
970
971const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
972const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
973const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
974
975TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
976 mOutput.mState.isEnabled = false;
977
978 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
979}
980
981TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
982 mRefreshArgs.updatingOutputGeometryThisFrame = false;
983
984 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
985}
986
987TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
988 mOutput.mState.transform = kIdentityTransform;
989
990 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
991
992 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
993
994 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
995}
996
997TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
998 mOutput.mState.transform = kIdentityTransform;
999
1000 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1001
1002 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1003
1004 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1005}
1006
1007TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1008 mOutput.mState.transform = kRotate90Transform;
1009
1010 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1011
1012 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1013
1014 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1015}
1016
1017TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1018 mOutput.mState.transform = kRotate90Transform;
1019
1020 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1021
1022 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1023
1024 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1025}
1026
1027TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1028 mOutput.mState.transform = kIdentityTransform;
1029 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1030
1031 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1032
1033 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1034
1035 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1036}
1037
1038TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1039 mOutput.mState.transform = kRotate90Transform;
1040 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1041
1042 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1043
1044 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1045
1046 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1047}
1048
1049/*
1050 * Output::collectVisibleLayers()
1051 */
1052
Lloyd Pique1ef93222019-11-21 16:41:53 -08001053struct OutputCollectVisibleLayersTest : public testing::Test {
1054 struct OutputPartialMock : public OutputPartialMockBase {
1055 // Sets up the helper functions called by the function under test to use
1056 // mock implementations.
1057 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001058 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001059 compositionengine::Output::CoverageState&));
1060 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1061 MOCK_METHOD0(finalizePendingOutputLayers, void());
1062 };
1063
1064 struct Layer {
1065 Layer() {
1066 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1067 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1068 }
1069
1070 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001071 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001072 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001073 };
1074
1075 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001076 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001077 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1078 .WillRepeatedly(Return(&mLayer1.outputLayer));
1079 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1080 .WillRepeatedly(Return(&mLayer2.outputLayer));
1081 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1082 .WillRepeatedly(Return(&mLayer3.outputLayer));
1083
Lloyd Piquede196652020-01-22 17:29:58 -08001084 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1085 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1086 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001087 }
1088
1089 StrictMock<OutputPartialMock> mOutput;
1090 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001091 LayerFESet mGeomSnapshots;
1092 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001093 Layer mLayer1;
1094 Layer mLayer2;
1095 Layer mLayer3;
1096};
1097
1098TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1099 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001100 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001101
1102 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1103 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1104
1105 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1106}
1107
1108TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1109 // Enforce a call order sequence for this test.
1110 InSequence seq;
1111
1112 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001113 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1114 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1115 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001116
1117 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1118 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1119
1120 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1121
1122 // Ensure all output layers have been assigned a simple/flattened z-order.
1123 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1124 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1125 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1126}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001127
1128/*
1129 * Output::ensureOutputLayerIfVisible()
1130 */
1131
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001132struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1133 struct OutputPartialMock : public OutputPartialMockBase {
1134 // Sets up the helper functions called by the function under test to use
1135 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001136 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001137 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001138 MOCK_METHOD2(ensureOutputLayer,
1139 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001140 };
1141
1142 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001143 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1144 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001145 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001146 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001147 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001148
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001149 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1150 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001151 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1152
Lloyd Piquede196652020-01-22 17:29:58 -08001153 mLayer.layerFEState.isVisible = true;
1154 mLayer.layerFEState.isOpaque = true;
1155 mLayer.layerFEState.contentDirty = true;
1156 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1157 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1158 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001159
Lloyd Piquede196652020-01-22 17:29:58 -08001160 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1161 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001162
Lloyd Piquede196652020-01-22 17:29:58 -08001163 mGeomSnapshots.insert(mLayer.layerFE);
1164 }
1165
1166 void ensureOutputLayerIfVisible() {
1167 sp<LayerFE> layerFE(mLayer.layerFE);
1168 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001169 }
1170
1171 static const Region kEmptyRegion;
1172 static const Region kFullBoundsNoRotation;
1173 static const Region kRightHalfBoundsNoRotation;
1174 static const Region kLowerHalfBoundsNoRotation;
1175 static const Region kFullBounds90Rotation;
1176
1177 StrictMock<OutputPartialMock> mOutput;
1178 LayerFESet mGeomSnapshots;
1179 Output::CoverageState mCoverageState{mGeomSnapshots};
1180
Lloyd Piquede196652020-01-22 17:29:58 -08001181 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182};
1183
1184const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1185const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1186 Region(Rect(0, 0, 100, 200));
1187const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1188 Region(Rect(0, 100, 100, 200));
1189const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1190 Region(Rect(50, 0, 100, 200));
1191const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1192 Region(Rect(0, 0, 200, 100));
1193
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001194TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001195 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1196 EXPECT_CALL(*mLayer.layerFE,
1197 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001198
1199 mGeomSnapshots.clear();
1200
Lloyd Piquede196652020-01-22 17:29:58 -08001201 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001202}
1203
1204TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1205 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001206 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001207
Lloyd Piquede196652020-01-22 17:29:58 -08001208 ensureOutputLayerIfVisible();
1209}
1210
1211TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1212 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1213
1214 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001215}
1216
1217TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001218 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001219
Lloyd Piquede196652020-01-22 17:29:58 -08001220 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001221}
1222
1223TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001224 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001225
Lloyd Piquede196652020-01-22 17:29:58 -08001226 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227}
1228
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001229TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001230 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231
Lloyd Piquede196652020-01-22 17:29:58 -08001232 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001233}
1234
1235TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1236 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001237 mLayer.layerFEState.isOpaque = true;
1238 mLayer.layerFEState.contentDirty = true;
1239 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240
1241 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001242 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1243 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001244
Lloyd Piquede196652020-01-22 17:29:58 -08001245 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246
1247 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1248 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1249 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1250
Lloyd Piquede196652020-01-22 17:29:58 -08001251 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1252 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1253 RegionEq(kFullBoundsNoRotation));
1254 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1255 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001256}
1257
1258TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1259 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001260 mLayer.layerFEState.isOpaque = true;
1261 mLayer.layerFEState.contentDirty = true;
1262 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001263
Lloyd Piquede196652020-01-22 17:29:58 -08001264 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1265 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001266
Lloyd Piquede196652020-01-22 17:29:58 -08001267 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001268
1269 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1270 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1271 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1272
Lloyd Piquede196652020-01-22 17:29:58 -08001273 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1274 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1275 RegionEq(kFullBoundsNoRotation));
1276 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1277 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001278}
1279
1280TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1281 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001282 mLayer.layerFEState.isOpaque = false;
1283 mLayer.layerFEState.contentDirty = true;
1284 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001285
1286 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001287 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1288 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001289
Lloyd Piquede196652020-01-22 17:29:58 -08001290 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291
1292 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1293 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1294 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1295
Lloyd Piquede196652020-01-22 17:29:58 -08001296 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1297 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001299 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1300 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001301}
1302
1303TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1304 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001305 mLayer.layerFEState.isOpaque = false;
1306 mLayer.layerFEState.contentDirty = true;
1307 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001308
Lloyd Piquede196652020-01-22 17:29:58 -08001309 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1310 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001311
Lloyd Piquede196652020-01-22 17:29:58 -08001312 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313
1314 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1315 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1316 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1317
Lloyd Piquede196652020-01-22 17:29:58 -08001318 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1319 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001320 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001321 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1322 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323}
1324
1325TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1326 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001327 mLayer.layerFEState.isOpaque = true;
1328 mLayer.layerFEState.contentDirty = false;
1329 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001330
1331 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001332 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1333 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001334
Lloyd Piquede196652020-01-22 17:29:58 -08001335 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
1337 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1338 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1339 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1340
Lloyd Piquede196652020-01-22 17:29:58 -08001341 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1342 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1343 RegionEq(kFullBoundsNoRotation));
1344 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1345 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346}
1347
1348TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1349 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001350 mLayer.layerFEState.isOpaque = true;
1351 mLayer.layerFEState.contentDirty = false;
1352 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001353
Lloyd Piquede196652020-01-22 17:29:58 -08001354 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1355 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
1359 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1360 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1361 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1362
Lloyd Piquede196652020-01-22 17:29:58 -08001363 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1365 RegionEq(kFullBoundsNoRotation));
1366 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1367 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368}
1369
1370TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1371 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001372 mLayer.layerFEState.isOpaque = true;
1373 mLayer.layerFEState.contentDirty = true;
1374 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1375 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1376 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1377 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378
1379 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001380 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1381 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001382
Lloyd Piquede196652020-01-22 17:29:58 -08001383 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384
1385 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1388
Lloyd Piquede196652020-01-22 17:29:58 -08001389 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1390 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1391 RegionEq(kFullBoundsNoRotation));
1392 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1393 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001394}
1395
1396TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1397 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001398 mLayer.layerFEState.isOpaque = true;
1399 mLayer.layerFEState.contentDirty = true;
1400 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1401 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1402 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1403 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001404
Lloyd Piquede196652020-01-22 17:29:58 -08001405 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1406 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409
1410 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1411 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1412 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1413
Lloyd Piquede196652020-01-22 17:29:58 -08001414 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1415 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1416 RegionEq(kFullBoundsNoRotation));
1417 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1418 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419}
1420
1421TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1422 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001423 mLayer.layerFEState.isOpaque = true;
1424 mLayer.layerFEState.contentDirty = true;
1425 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001427 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1429
1430 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001431 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1432 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
1436 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1438 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1439
Lloyd Piquede196652020-01-22 17:29:58 -08001440 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1441 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1442 RegionEq(kFullBoundsNoRotation));
1443 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1444 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445}
1446
1447TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1448 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001449 mLayer.layerFEState.isOpaque = true;
1450 mLayer.layerFEState.contentDirty = true;
1451 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001453 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001454 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1455
Lloyd Piquede196652020-01-22 17:29:58 -08001456 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1457 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458
Lloyd Piquede196652020-01-22 17:29:58 -08001459 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
1461 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1462 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1463 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1466 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1467 RegionEq(kFullBoundsNoRotation));
1468 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1469 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470}
1471
1472TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1473 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1474 ui::Transform arbitraryTransform;
1475 arbitraryTransform.set(1, 1, -1, 1);
1476 arbitraryTransform.set(0, 100);
1477
Lloyd Piquede196652020-01-22 17:29:58 -08001478 mLayer.layerFEState.isOpaque = true;
1479 mLayer.layerFEState.contentDirty = true;
1480 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1481 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001482
1483 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001484 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1485 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
1489 const Region kRegion = Region(Rect(0, 0, 300, 300));
1490 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1491
1492 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1493 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1494 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1497 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1498 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1499 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500}
1501
1502TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001503 mLayer.layerFEState.isOpaque = false;
1504 mLayer.layerFEState.contentDirty = true;
1505 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506
1507 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1508 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1509 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1512 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513
Lloyd Piquede196652020-01-22 17:29:58 -08001514 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
1516 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1517 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1518 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1519 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1520 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1521 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1522
1523 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1524 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1525 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1528 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001530 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1531 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1532 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001533}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001534
Vishnu Naira483b4a2019-12-12 15:07:52 -08001535TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1536 ui::Transform translate;
1537 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001538 mLayer.layerFEState.geomLayerTransform = translate;
1539 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001540
1541 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1542 // half of the layer including the casting shadow is covered and opaque
1543 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1544 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1547 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001548
Lloyd Piquede196652020-01-22 17:29:58 -08001549 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001550
1551 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1552 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1553 // add starting opaque region to the opaque half of the casting layer bounds
1554 const Region kExpectedAboveOpaqueRegion =
1555 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1556 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1557 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1558 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1559 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1560 const Region kExpectedLayerShadowRegion =
1561 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1562
1563 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1564 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1565 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1568 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001569 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001570 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1571 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001572 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001574 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1575}
1576
1577TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1578 ui::Transform translate;
1579 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001580 mLayer.layerFEState.geomLayerTransform = translate;
1581 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001582
1583 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1584 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1585 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1586 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1587
Lloyd Piquede196652020-01-22 17:29:58 -08001588 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1589 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001590
Lloyd Piquede196652020-01-22 17:29:58 -08001591 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001592
1593 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1594 const Region kExpectedLayerShadowRegion =
1595 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1596
Lloyd Piquede196652020-01-22 17:29:58 -08001597 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1598 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001599 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1600}
1601
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001602TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001603 ui::Transform translate;
1604 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001605 mLayer.layerFEState.geomLayerTransform = translate;
1606 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001607
1608 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1609 // Casting layer and its shadows are covered by an opaque region
1610 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1611 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001614}
1615
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001616/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001617 * Output::present()
1618 */
1619
1620struct OutputPresentTest : public testing::Test {
1621 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001622 // Sets up the helper functions called by the function under test to use
1623 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001624 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1625 MOCK_METHOD1(updateAndWriteCompositionState,
1626 void(const compositionengine::CompositionRefreshArgs&));
1627 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1628 MOCK_METHOD0(beginFrame, void());
1629 MOCK_METHOD0(prepareFrame, void());
1630 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1631 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1632 MOCK_METHOD0(postFramebuffer, void());
1633 };
1634
1635 StrictMock<OutputPartialMock> mOutput;
1636};
1637
1638TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1639 CompositionRefreshArgs args;
1640
1641 InSequence seq;
1642 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1643 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1644 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1645 EXPECT_CALL(mOutput, beginFrame());
1646 EXPECT_CALL(mOutput, prepareFrame());
1647 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1648 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1649 EXPECT_CALL(mOutput, postFramebuffer());
1650
1651 mOutput.present(args);
1652}
1653
1654/*
1655 * Output::updateColorProfile()
1656 */
1657
Lloyd Pique17ca7422019-11-14 14:24:10 -08001658struct OutputUpdateColorProfileTest : public testing::Test {
1659 using TestType = OutputUpdateColorProfileTest;
1660
1661 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001662 // Sets up the helper functions called by the function under test to use
1663 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001664 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1665 };
1666
1667 struct Layer {
1668 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001669 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001670 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001671 }
1672
1673 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001674 StrictMock<mock::LayerFE> mLayerFE;
1675 LayerFECompositionState mLayerFEState;
1676 };
1677
1678 OutputUpdateColorProfileTest() {
1679 mOutput.setDisplayColorProfileForTest(
1680 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1681 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1682
1683 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1684 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1685 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1686 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1687 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1688 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1689 }
1690
1691 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1692 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1693 };
1694
1695 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1696 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1697 StrictMock<OutputPartialMock> mOutput;
1698
1699 Layer mLayer1;
1700 Layer mLayer2;
1701 Layer mLayer3;
1702
1703 CompositionRefreshArgs mRefreshArgs;
1704};
1705
1706// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1707// to make it easier to write unit tests.
1708
1709TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1710 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1711 // a simple default color profile without looking at anything else.
1712
Lloyd Pique0a456232020-01-16 17:51:13 -08001713 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001714 EXPECT_CALL(mOutput,
1715 setColorProfile(ColorProfileEq(
1716 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1717 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1718
1719 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1720 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1721
1722 mOutput.updateColorProfile(mRefreshArgs);
1723}
1724
1725struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1726 : public OutputUpdateColorProfileTest {
1727 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001728 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001729 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1730 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1731 }
1732
1733 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1734 : public CallOrderStateMachineHelper<
1735 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1736 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1737 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1738 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1739 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1740 _))
1741 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1742 SetArgPointee<4>(renderIntent)));
1743 EXPECT_CALL(getInstance()->mOutput,
1744 setColorProfile(
1745 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1746 ui::Dataspace::UNKNOWN})));
1747 return nextState<ExecuteState>();
1748 }
1749 };
1750
1751 // Call this member function to start using the mini-DSL defined above.
1752 [[nodiscard]] auto verify() {
1753 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1754 }
1755};
1756
1757TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1758 Native_Unknown_Colorimetric_Set) {
1759 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1760 ui::Dataspace::UNKNOWN,
1761 ui::RenderIntent::COLORIMETRIC)
1762 .execute();
1763}
1764
1765TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1766 DisplayP3_DisplayP3_Enhance_Set) {
1767 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1768 ui::Dataspace::DISPLAY_P3,
1769 ui::RenderIntent::ENHANCE)
1770 .execute();
1771}
1772
1773struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1774 : public OutputUpdateColorProfileTest {
1775 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001776 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001777 EXPECT_CALL(*mDisplayColorProfile,
1778 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1779 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1780 SetArgPointee<3>(ui::ColorMode::NATIVE),
1781 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1782 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1783 }
1784
1785 struct IfColorSpaceAgnosticDataspaceSetToState
1786 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1787 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1788 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1789 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1790 }
1791 };
1792
1793 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1794 : public CallOrderStateMachineHelper<
1795 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1796 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1797 ui::Dataspace dataspace) {
1798 EXPECT_CALL(getInstance()->mOutput,
1799 setColorProfile(ColorProfileEq(
1800 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1801 ui::RenderIntent::COLORIMETRIC, dataspace})));
1802 return nextState<ExecuteState>();
1803 }
1804 };
1805
1806 // Call this member function to start using the mini-DSL defined above.
1807 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1808};
1809
1810TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1811 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1812 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1813 .execute();
1814}
1815
1816TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1817 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1818 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1819 .execute();
1820}
1821
1822struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1823 : public OutputUpdateColorProfileTest {
1824 // Internally the implementation looks through the dataspaces of all the
1825 // visible layers. The topmost one that also has an actual dataspace
1826 // preference set is used to drive subsequent choices.
1827
1828 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1829 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1830 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1831
Lloyd Pique0a456232020-01-16 17:51:13 -08001832 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001833 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1834 }
1835
1836 struct IfTopLayerDataspaceState
1837 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1838 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1839 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1840 return nextState<AndIfMiddleLayerDataspaceState>();
1841 }
1842 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1843 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1844 }
1845 };
1846
1847 struct AndIfMiddleLayerDataspaceState
1848 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1849 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1850 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1851 return nextState<AndIfBottomLayerDataspaceState>();
1852 }
1853 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1854 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1855 }
1856 };
1857
1858 struct AndIfBottomLayerDataspaceState
1859 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1860 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1861 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1862 return nextState<ThenExpectBestColorModeCallUsesState>();
1863 }
1864 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1865 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1866 }
1867 };
1868
1869 struct ThenExpectBestColorModeCallUsesState
1870 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1871 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1872 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1873 getBestColorMode(dataspace, _, _, _, _));
1874 return nextState<ExecuteState>();
1875 }
1876 };
1877
1878 // Call this member function to start using the mini-DSL defined above.
1879 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1880};
1881
1882TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1883 noStrongLayerPrefenceUses_V0_SRGB) {
1884 // If none of the layers indicate a preference, then V0_SRGB is the
1885 // preferred choice (subject to additional checks).
1886 verify().ifTopLayerHasNoPreference()
1887 .andIfMiddleLayerHasNoPreference()
1888 .andIfBottomLayerHasNoPreference()
1889 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1890 .execute();
1891}
1892
1893TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1894 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1895 // If only the topmost layer has a preference, then that is what is chosen.
1896 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1897 .andIfMiddleLayerHasNoPreference()
1898 .andIfBottomLayerHasNoPreference()
1899 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1900 .execute();
1901}
1902
1903TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1904 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1905 // If only the middle layer has a preference, that that is what is chosen.
1906 verify().ifTopLayerHasNoPreference()
1907 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1908 .andIfBottomLayerHasNoPreference()
1909 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1910 .execute();
1911}
1912
1913TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1914 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1915 // If only the middle layer has a preference, that that is what is chosen.
1916 verify().ifTopLayerHasNoPreference()
1917 .andIfMiddleLayerHasNoPreference()
1918 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1919 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1920 .execute();
1921}
1922
1923TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1924 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1925 // If multiple layers have a preference, the topmost value is what is used.
1926 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1927 .andIfMiddleLayerHasNoPreference()
1928 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1929 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1930 .execute();
1931}
1932
1933TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1934 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1935 // If multiple layers have a preference, the topmost value is what is used.
1936 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1937 .andIfMiddleLayerHasNoPreference()
1938 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1939 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1940 .execute();
1941}
1942
1943struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1944 : public OutputUpdateColorProfileTest {
1945 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1946 // values, it overrides the layer dataspace choice.
1947
1948 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1949 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1950 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1951
1952 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1953
Lloyd Pique0a456232020-01-16 17:51:13 -08001954 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001955 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1956 }
1957
1958 struct IfForceOutputColorModeState
1959 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1960 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1961 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1962 return nextState<ThenExpectBestColorModeCallUsesState>();
1963 }
1964 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1965 };
1966
1967 struct ThenExpectBestColorModeCallUsesState
1968 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1969 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1970 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1971 getBestColorMode(dataspace, _, _, _, _));
1972 return nextState<ExecuteState>();
1973 }
1974 };
1975
1976 // Call this member function to start using the mini-DSL defined above.
1977 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1978};
1979
1980TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1981 // By default the layer state is used to set the preferred dataspace
1982 verify().ifNoOverride()
1983 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1984 .execute();
1985}
1986
1987TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1988 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1989 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1990 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1991 .execute();
1992}
1993
1994TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1995 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1996 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1997 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1998 .execute();
1999}
2000
2001// HDR output requires all layers to be compatible with the chosen HDR
2002// dataspace, along with there being proper support.
2003struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2004 OutputUpdateColorProfileTest_Hdr() {
2005 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2006 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002007 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002008 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2009 }
2010
2011 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2012 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2013 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2014 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2015
2016 struct IfTopLayerDataspaceState
2017 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2018 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2019 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2020 return nextState<AndTopLayerCompositionTypeState>();
2021 }
2022 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2023 };
2024
2025 struct AndTopLayerCompositionTypeState
2026 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2027 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2028 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2029 return nextState<AndIfBottomLayerDataspaceState>();
2030 }
2031 };
2032
2033 struct AndIfBottomLayerDataspaceState
2034 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2035 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2036 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2037 return nextState<AndBottomLayerCompositionTypeState>();
2038 }
2039 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2040 return andIfBottomLayerIs(kNonHdrDataspace);
2041 }
2042 };
2043
2044 struct AndBottomLayerCompositionTypeState
2045 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2046 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2047 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2048 return nextState<AndIfHasLegacySupportState>();
2049 }
2050 };
2051
2052 struct AndIfHasLegacySupportState
2053 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2054 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2055 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2056 .WillOnce(Return(legacySupport));
2057 return nextState<ThenExpectBestColorModeCallUsesState>();
2058 }
2059 };
2060
2061 struct ThenExpectBestColorModeCallUsesState
2062 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2063 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2064 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2065 getBestColorMode(dataspace, _, _, _, _));
2066 return nextState<ExecuteState>();
2067 }
2068 };
2069
2070 // Call this member function to start using the mini-DSL defined above.
2071 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2072};
2073
2074TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2075 // If all layers use BT2020_PQ, and there are no other special conditions,
2076 // BT2020_PQ is used.
2077 verify().ifTopLayerIs(BT2020_PQ)
2078 .andTopLayerIsREComposed(false)
2079 .andIfBottomLayerIs(BT2020_PQ)
2080 .andBottomLayerIsREComposed(false)
2081 .andIfLegacySupportFor(BT2020_PQ, false)
2082 .thenExpectBestColorModeCallUses(BT2020_PQ)
2083 .execute();
2084}
2085
2086TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2087 // BT2020_PQ is not used if there is only legacy support for it.
2088 verify().ifTopLayerIs(BT2020_PQ)
2089 .andTopLayerIsREComposed(false)
2090 .andIfBottomLayerIs(BT2020_PQ)
2091 .andBottomLayerIsREComposed(false)
2092 .andIfLegacySupportFor(BT2020_PQ, true)
2093 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2094 .execute();
2095}
2096
2097TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2098 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2099 verify().ifTopLayerIs(BT2020_PQ)
2100 .andTopLayerIsREComposed(false)
2101 .andIfBottomLayerIs(BT2020_PQ)
2102 .andBottomLayerIsREComposed(true)
2103 .andIfLegacySupportFor(BT2020_PQ, false)
2104 .thenExpectBestColorModeCallUses(BT2020_PQ)
2105 .execute();
2106}
2107
2108TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2109 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2110 verify().ifTopLayerIs(BT2020_PQ)
2111 .andTopLayerIsREComposed(true)
2112 .andIfBottomLayerIs(BT2020_PQ)
2113 .andBottomLayerIsREComposed(false)
2114 .andIfLegacySupportFor(BT2020_PQ, false)
2115 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2116 .execute();
2117}
2118
2119TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2120 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2121 // are no other special conditions.
2122 verify().ifTopLayerIs(BT2020_PQ)
2123 .andTopLayerIsREComposed(false)
2124 .andIfBottomLayerIs(BT2020_HLG)
2125 .andBottomLayerIsREComposed(false)
2126 .andIfLegacySupportFor(BT2020_PQ, false)
2127 .thenExpectBestColorModeCallUses(BT2020_PQ)
2128 .execute();
2129}
2130
2131TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2132 // BT2020_PQ is not used if there is only legacy support for it.
2133 verify().ifTopLayerIs(BT2020_PQ)
2134 .andTopLayerIsREComposed(false)
2135 .andIfBottomLayerIs(BT2020_HLG)
2136 .andBottomLayerIsREComposed(false)
2137 .andIfLegacySupportFor(BT2020_PQ, true)
2138 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2139 .execute();
2140}
2141
2142TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2143 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2144 verify().ifTopLayerIs(BT2020_PQ)
2145 .andTopLayerIsREComposed(false)
2146 .andIfBottomLayerIs(BT2020_HLG)
2147 .andBottomLayerIsREComposed(true)
2148 .andIfLegacySupportFor(BT2020_PQ, false)
2149 .thenExpectBestColorModeCallUses(BT2020_PQ)
2150 .execute();
2151}
2152
2153TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2154 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2155 verify().ifTopLayerIs(BT2020_PQ)
2156 .andTopLayerIsREComposed(true)
2157 .andIfBottomLayerIs(BT2020_HLG)
2158 .andBottomLayerIsREComposed(false)
2159 .andIfLegacySupportFor(BT2020_PQ, false)
2160 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2161 .execute();
2162}
2163
2164TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2165 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2166 // used if there are no other special conditions.
2167 verify().ifTopLayerIs(BT2020_HLG)
2168 .andTopLayerIsREComposed(false)
2169 .andIfBottomLayerIs(BT2020_PQ)
2170 .andBottomLayerIsREComposed(false)
2171 .andIfLegacySupportFor(BT2020_PQ, false)
2172 .thenExpectBestColorModeCallUses(BT2020_PQ)
2173 .execute();
2174}
2175
2176TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2177 // BT2020_PQ is not used if there is only legacy support for it.
2178 verify().ifTopLayerIs(BT2020_HLG)
2179 .andTopLayerIsREComposed(false)
2180 .andIfBottomLayerIs(BT2020_PQ)
2181 .andBottomLayerIsREComposed(false)
2182 .andIfLegacySupportFor(BT2020_PQ, true)
2183 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2184 .execute();
2185}
2186
2187TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2188 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2189 verify().ifTopLayerIs(BT2020_HLG)
2190 .andTopLayerIsREComposed(false)
2191 .andIfBottomLayerIs(BT2020_PQ)
2192 .andBottomLayerIsREComposed(true)
2193 .andIfLegacySupportFor(BT2020_PQ, false)
2194 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2195 .execute();
2196}
2197
2198TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2199 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2200 verify().ifTopLayerIs(BT2020_HLG)
2201 .andTopLayerIsREComposed(true)
2202 .andIfBottomLayerIs(BT2020_PQ)
2203 .andBottomLayerIsREComposed(false)
2204 .andIfLegacySupportFor(BT2020_PQ, false)
2205 .thenExpectBestColorModeCallUses(BT2020_PQ)
2206 .execute();
2207}
2208
2209TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2210 // If all layers use HLG then HLG is used if there are no other special
2211 // conditions.
2212 verify().ifTopLayerIs(BT2020_HLG)
2213 .andTopLayerIsREComposed(false)
2214 .andIfBottomLayerIs(BT2020_HLG)
2215 .andBottomLayerIsREComposed(false)
2216 .andIfLegacySupportFor(BT2020_HLG, false)
2217 .thenExpectBestColorModeCallUses(BT2020_HLG)
2218 .execute();
2219}
2220
2221TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2222 // BT2020_HLG is not used if there is legacy support for it.
2223 verify().ifTopLayerIs(BT2020_HLG)
2224 .andTopLayerIsREComposed(false)
2225 .andIfBottomLayerIs(BT2020_HLG)
2226 .andBottomLayerIsREComposed(false)
2227 .andIfLegacySupportFor(BT2020_HLG, true)
2228 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2229 .execute();
2230}
2231
2232TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2233 // BT2020_HLG is used even if the bottom layer is client composed.
2234 verify().ifTopLayerIs(BT2020_HLG)
2235 .andTopLayerIsREComposed(false)
2236 .andIfBottomLayerIs(BT2020_HLG)
2237 .andBottomLayerIsREComposed(true)
2238 .andIfLegacySupportFor(BT2020_HLG, false)
2239 .thenExpectBestColorModeCallUses(BT2020_HLG)
2240 .execute();
2241}
2242
2243TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2244 // BT2020_HLG is used even if the top layer is client composed.
2245 verify().ifTopLayerIs(BT2020_HLG)
2246 .andTopLayerIsREComposed(true)
2247 .andIfBottomLayerIs(BT2020_HLG)
2248 .andBottomLayerIsREComposed(false)
2249 .andIfLegacySupportFor(BT2020_HLG, false)
2250 .thenExpectBestColorModeCallUses(BT2020_HLG)
2251 .execute();
2252}
2253
2254TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2255 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2256 verify().ifTopLayerIs(BT2020_PQ)
2257 .andTopLayerIsREComposed(false)
2258 .andIfBottomLayerIsNotHdr()
2259 .andBottomLayerIsREComposed(false)
2260 .andIfLegacySupportFor(BT2020_PQ, false)
2261 .thenExpectBestColorModeCallUses(BT2020_PQ)
2262 .execute();
2263}
2264
2265TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2266 // If all layers use HLG then HLG is used if there are no other special
2267 // conditions.
2268 verify().ifTopLayerIs(BT2020_HLG)
2269 .andTopLayerIsREComposed(false)
2270 .andIfBottomLayerIsNotHdr()
2271 .andBottomLayerIsREComposed(true)
2272 .andIfLegacySupportFor(BT2020_HLG, false)
2273 .thenExpectBestColorModeCallUses(BT2020_HLG)
2274 .execute();
2275}
2276
2277struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2278 : public OutputUpdateColorProfileTest {
2279 // The various values for CompositionRefreshArgs::outputColorSetting affect
2280 // the chosen renderIntent, along with whether the preferred dataspace is an
2281 // HDR dataspace or not.
2282
2283 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2284 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2285 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2286 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002287 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002288 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2289 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2290 .WillRepeatedly(Return(false));
2291 }
2292
2293 // The tests here involve enough state and GMock setup that using a mini-DSL
2294 // makes the tests much more readable, and allows the test to focus more on
2295 // the intent than on some of the details.
2296
2297 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2298 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2299
2300 struct IfDataspaceChosenState
2301 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2302 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2303 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2304 return nextState<AndOutputColorSettingState>();
2305 }
2306 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2307 return ifDataspaceChosenIs(kNonHdrDataspace);
2308 }
2309 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2310 };
2311
2312 struct AndOutputColorSettingState
2313 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2314 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2315 getInstance()->mRefreshArgs.outputColorSetting = setting;
2316 return nextState<ThenExpectBestColorModeCallUsesState>();
2317 }
2318 };
2319
2320 struct ThenExpectBestColorModeCallUsesState
2321 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2322 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2323 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2324 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2325 _, _));
2326 return nextState<ExecuteState>();
2327 }
2328 };
2329
2330 // Tests call one of these two helper member functions to start using the
2331 // mini-DSL defined above.
2332 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2333};
2334
2335TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2336 Managed_NonHdr_Prefers_Colorimetric) {
2337 verify().ifDataspaceChosenIsNonHdr()
2338 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2339 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2340 .execute();
2341}
2342
2343TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2344 Managed_Hdr_Prefers_ToneMapColorimetric) {
2345 verify().ifDataspaceChosenIsHdr()
2346 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2347 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2348 .execute();
2349}
2350
2351TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2352 verify().ifDataspaceChosenIsNonHdr()
2353 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2354 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2355 .execute();
2356}
2357
2358TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2359 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2360 verify().ifDataspaceChosenIsHdr()
2361 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2362 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2363 .execute();
2364}
2365
2366TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2367 verify().ifDataspaceChosenIsNonHdr()
2368 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2369 .thenExpectBestColorModeCallUses(
2370 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2371 .execute();
2372}
2373
2374TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2375 verify().ifDataspaceChosenIsHdr()
2376 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2377 .thenExpectBestColorModeCallUses(
2378 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2379 .execute();
2380}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002381
2382/*
2383 * Output::beginFrame()
2384 */
2385
Lloyd Piquee5965952019-11-18 16:16:32 -08002386struct OutputBeginFrameTest : public ::testing::Test {
2387 using TestType = OutputBeginFrameTest;
2388
2389 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002390 // Sets up the helper functions called by the function under test to use
2391 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002392 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2393 };
2394
2395 OutputBeginFrameTest() {
2396 mOutput.setDisplayColorProfileForTest(
2397 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2398 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2399 }
2400
2401 struct IfGetDirtyRegionExpectationState
2402 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2403 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2404 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2405 .WillOnce(Return(dirtyRegion));
2406 return nextState<AndIfGetOutputLayerCountExpectationState>();
2407 }
2408 };
2409
2410 struct AndIfGetOutputLayerCountExpectationState
2411 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2412 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2413 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2414 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2415 }
2416 };
2417
2418 struct AndIfLastCompositionHadVisibleLayersState
2419 : public CallOrderStateMachineHelper<TestType,
2420 AndIfLastCompositionHadVisibleLayersState> {
2421 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2422 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2423 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2424 }
2425 };
2426
2427 struct ThenExpectRenderSurfaceBeginFrameCallState
2428 : public CallOrderStateMachineHelper<TestType,
2429 ThenExpectRenderSurfaceBeginFrameCallState> {
2430 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2431 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2432 return nextState<ExecuteState>();
2433 }
2434 };
2435
2436 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2437 [[nodiscard]] auto execute() {
2438 getInstance()->mOutput.beginFrame();
2439 return nextState<CheckPostconditionHadVisibleLayersState>();
2440 }
2441 };
2442
2443 struct CheckPostconditionHadVisibleLayersState
2444 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2445 void checkPostconditionHadVisibleLayers(bool expected) {
2446 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2447 }
2448 };
2449
2450 // Tests call one of these two helper member functions to start using the
2451 // mini-DSL defined above.
2452 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2453
2454 static const Region kEmptyRegion;
2455 static const Region kNotEmptyRegion;
2456
2457 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2458 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2459 StrictMock<OutputPartialMock> mOutput;
2460};
2461
2462const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2463const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2464
2465TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2466 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2467 .andIfGetOutputLayerCountReturns(1u)
2468 .andIfLastCompositionHadVisibleLayersIs(true)
2469 .thenExpectRenderSurfaceBeginFrameCall(true)
2470 .execute()
2471 .checkPostconditionHadVisibleLayers(true);
2472}
2473
2474TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2475 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2476 .andIfGetOutputLayerCountReturns(0u)
2477 .andIfLastCompositionHadVisibleLayersIs(true)
2478 .thenExpectRenderSurfaceBeginFrameCall(true)
2479 .execute()
2480 .checkPostconditionHadVisibleLayers(false);
2481}
2482
2483TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2484 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2485 .andIfGetOutputLayerCountReturns(1u)
2486 .andIfLastCompositionHadVisibleLayersIs(false)
2487 .thenExpectRenderSurfaceBeginFrameCall(true)
2488 .execute()
2489 .checkPostconditionHadVisibleLayers(true);
2490}
2491
2492TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2493 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2494 .andIfGetOutputLayerCountReturns(0u)
2495 .andIfLastCompositionHadVisibleLayersIs(false)
2496 .thenExpectRenderSurfaceBeginFrameCall(false)
2497 .execute()
2498 .checkPostconditionHadVisibleLayers(false);
2499}
2500
2501TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2502 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2503 .andIfGetOutputLayerCountReturns(1u)
2504 .andIfLastCompositionHadVisibleLayersIs(true)
2505 .thenExpectRenderSurfaceBeginFrameCall(false)
2506 .execute()
2507 .checkPostconditionHadVisibleLayers(true);
2508}
2509
2510TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2511 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2512 .andIfGetOutputLayerCountReturns(0u)
2513 .andIfLastCompositionHadVisibleLayersIs(true)
2514 .thenExpectRenderSurfaceBeginFrameCall(false)
2515 .execute()
2516 .checkPostconditionHadVisibleLayers(true);
2517}
2518
2519TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2520 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2521 .andIfGetOutputLayerCountReturns(1u)
2522 .andIfLastCompositionHadVisibleLayersIs(false)
2523 .thenExpectRenderSurfaceBeginFrameCall(false)
2524 .execute()
2525 .checkPostconditionHadVisibleLayers(false);
2526}
2527
2528TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2529 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2530 .andIfGetOutputLayerCountReturns(0u)
2531 .andIfLastCompositionHadVisibleLayersIs(false)
2532 .thenExpectRenderSurfaceBeginFrameCall(false)
2533 .execute()
2534 .checkPostconditionHadVisibleLayers(false);
2535}
2536
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002537/*
2538 * Output::devOptRepaintFlash()
2539 */
2540
Lloyd Piquedb462d82019-11-19 17:58:46 -08002541struct OutputDevOptRepaintFlashTest : public testing::Test {
2542 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002543 // Sets up the helper functions called by the function under test to use
2544 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002545 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002546 MOCK_METHOD2(composeSurfaces,
2547 std::optional<base::unique_fd>(
2548 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002549 MOCK_METHOD0(postFramebuffer, void());
2550 MOCK_METHOD0(prepareFrame, void());
2551 };
2552
2553 OutputDevOptRepaintFlashTest() {
2554 mOutput.setDisplayColorProfileForTest(
2555 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2556 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2557 }
2558
2559 static const Region kEmptyRegion;
2560 static const Region kNotEmptyRegion;
2561
2562 StrictMock<OutputPartialMock> mOutput;
2563 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2564 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2565 CompositionRefreshArgs mRefreshArgs;
2566};
2567
2568const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2569const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2570
2571TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2572 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2573 mRefreshArgs.repaintEverything = true;
2574 mOutput.mState.isEnabled = true;
2575
2576 mOutput.devOptRepaintFlash(mRefreshArgs);
2577}
2578
2579TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2580 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2581 mRefreshArgs.repaintEverything = true;
2582 mOutput.mState.isEnabled = false;
2583
2584 InSequence seq;
2585 EXPECT_CALL(mOutput, postFramebuffer());
2586 EXPECT_CALL(mOutput, prepareFrame());
2587
2588 mOutput.devOptRepaintFlash(mRefreshArgs);
2589}
2590
2591TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2592 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2593 mRefreshArgs.repaintEverything = true;
2594 mOutput.mState.isEnabled = true;
2595
2596 InSequence seq;
2597 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2598 EXPECT_CALL(mOutput, postFramebuffer());
2599 EXPECT_CALL(mOutput, prepareFrame());
2600
2601 mOutput.devOptRepaintFlash(mRefreshArgs);
2602}
2603
2604TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2605 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2606 mRefreshArgs.repaintEverything = false;
2607 mOutput.mState.isEnabled = true;
2608
2609 InSequence seq;
2610 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002611 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002612 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2613 EXPECT_CALL(mOutput, postFramebuffer());
2614 EXPECT_CALL(mOutput, prepareFrame());
2615
2616 mOutput.devOptRepaintFlash(mRefreshArgs);
2617}
2618
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002619/*
2620 * Output::finishFrame()
2621 */
2622
Lloyd Pique03561a62019-11-19 18:34:52 -08002623struct OutputFinishFrameTest : public testing::Test {
2624 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002625 // Sets up the helper functions called by the function under test to use
2626 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002627 MOCK_METHOD2(composeSurfaces,
2628 std::optional<base::unique_fd>(
2629 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002630 MOCK_METHOD0(postFramebuffer, void());
2631 };
2632
2633 OutputFinishFrameTest() {
2634 mOutput.setDisplayColorProfileForTest(
2635 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2636 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2637 }
2638
2639 StrictMock<OutputPartialMock> mOutput;
2640 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2641 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2642 CompositionRefreshArgs mRefreshArgs;
2643};
2644
2645TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2646 mOutput.mState.isEnabled = false;
2647
2648 mOutput.finishFrame(mRefreshArgs);
2649}
2650
2651TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2652 mOutput.mState.isEnabled = true;
2653
2654 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002655 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002656
2657 mOutput.finishFrame(mRefreshArgs);
2658}
2659
2660TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2661 mOutput.mState.isEnabled = true;
2662
2663 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002664 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002665 .WillOnce(Return(ByMove(base::unique_fd())));
2666 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2667
2668 mOutput.finishFrame(mRefreshArgs);
2669}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002670
2671/*
2672 * Output::postFramebuffer()
2673 */
2674
Lloyd Pique07178e32019-11-19 19:15:26 -08002675struct OutputPostFramebufferTest : public testing::Test {
2676 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002677 // Sets up the helper functions called by the function under test to use
2678 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002679 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2680 };
2681
2682 struct Layer {
2683 Layer() {
2684 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2685 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2686 }
2687
2688 StrictMock<mock::OutputLayer> outputLayer;
2689 StrictMock<mock::LayerFE> layerFE;
2690 StrictMock<HWC2::mock::Layer> hwc2Layer;
2691 };
2692
2693 OutputPostFramebufferTest() {
2694 mOutput.setDisplayColorProfileForTest(
2695 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2696 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2697
2698 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2699 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2700 .WillRepeatedly(Return(&mLayer1.outputLayer));
2701 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2702 .WillRepeatedly(Return(&mLayer2.outputLayer));
2703 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2704 .WillRepeatedly(Return(&mLayer3.outputLayer));
2705 }
2706
2707 StrictMock<OutputPartialMock> mOutput;
2708 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2709 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2710
2711 Layer mLayer1;
2712 Layer mLayer2;
2713 Layer mLayer3;
2714};
2715
2716TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2717 mOutput.mState.isEnabled = false;
2718
2719 mOutput.postFramebuffer();
2720}
2721
2722TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2723 mOutput.mState.isEnabled = true;
2724
2725 compositionengine::Output::FrameFences frameFences;
2726
2727 // This should happen even if there are no output layers.
2728 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2729
2730 // For this test in particular we want to make sure the call expectations
2731 // setup below are satisfied in the specific order.
2732 InSequence seq;
2733
2734 EXPECT_CALL(*mRenderSurface, flip());
2735 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2736 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2737
2738 mOutput.postFramebuffer();
2739}
2740
2741TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2742 // Simulate getting release fences from each layer, and ensure they are passed to the
2743 // front-end layer interface for each layer correctly.
2744
2745 mOutput.mState.isEnabled = true;
2746
2747 // Create three unique fence instances
2748 sp<Fence> layer1Fence = new Fence();
2749 sp<Fence> layer2Fence = new Fence();
2750 sp<Fence> layer3Fence = new Fence();
2751
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002752 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002753 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2754 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2755 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2756
2757 EXPECT_CALL(*mRenderSurface, flip());
2758 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2759 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2760
2761 // Compare the pointers values of each fence to make sure the correct ones
2762 // are passed. This happens to work with the current implementation, but
2763 // would not survive certain calls like Fence::merge() which would return a
2764 // new instance.
2765 EXPECT_CALL(mLayer1.layerFE,
2766 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2767 EXPECT_CALL(mLayer2.layerFE,
2768 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2769 EXPECT_CALL(mLayer3.layerFE,
2770 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2771
2772 mOutput.postFramebuffer();
2773}
2774
2775TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2776 mOutput.mState.isEnabled = true;
2777 mOutput.mState.usesClientComposition = true;
2778
2779 sp<Fence> clientTargetAcquireFence = new Fence();
2780 sp<Fence> layer1Fence = new Fence();
2781 sp<Fence> layer2Fence = new Fence();
2782 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002783 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002784 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2785 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2786 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2787 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2788
2789 EXPECT_CALL(*mRenderSurface, flip());
2790 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2791 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2792
2793 // Fence::merge is called, and since none of the fences are actually valid,
2794 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2795 // This is the best we can do without creating a real kernel fence object.
2796 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2797 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2798 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2799
2800 mOutput.postFramebuffer();
2801}
2802
2803TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2804 mOutput.mState.isEnabled = true;
2805 mOutput.mState.usesClientComposition = true;
2806
2807 // This should happen even if there are no (current) output layers.
2808 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2809
2810 // Load up the released layers with some mock instances
2811 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2812 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2813 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2814 Output::ReleasedLayers layers;
2815 layers.push_back(releasedLayer1);
2816 layers.push_back(releasedLayer2);
2817 layers.push_back(releasedLayer3);
2818 mOutput.setReleasedLayers(std::move(layers));
2819
2820 // Set up a fake present fence
2821 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002822 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002823 frameFences.presentFence = presentFence;
2824
2825 EXPECT_CALL(*mRenderSurface, flip());
2826 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2827 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2828
2829 // Each released layer should be given the presentFence.
2830 EXPECT_CALL(*releasedLayer1,
2831 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2832 EXPECT_CALL(*releasedLayer2,
2833 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2834 EXPECT_CALL(*releasedLayer3,
2835 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2836
2837 mOutput.postFramebuffer();
2838
2839 // After the call the list of released layers should have been cleared.
2840 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2841}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002842
2843/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002844 * Output::composeSurfaces()
2845 */
2846
2847struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002848 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002849
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002850 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002851 // Sets up the helper functions called by the function under test to use
2852 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002853 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002854 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002855 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002856 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002857 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002858 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2859 };
2860
2861 OutputComposeSurfacesTest() {
2862 mOutput.setDisplayColorProfileForTest(
2863 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2864 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002865 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002866
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002867 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2868 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002869 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002870 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002871 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002872 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002873 mOutput.mState.dataspace = kDefaultOutputDataspace;
2874 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2875 mOutput.mState.isSecure = false;
2876 mOutput.mState.needsFiltering = false;
2877 mOutput.mState.usesClientComposition = true;
2878 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002879 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002880 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002881
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002882 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002883 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002884 EXPECT_CALL(mCompositionEngine, getTimeStats())
2885 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002886 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2887 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002888 }
2889
Lloyd Pique6818fa52019-12-03 12:32:13 -08002890 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2891 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002892 getInstance()->mReadyFence =
2893 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002894 return nextState<FenceCheckState>();
2895 }
2896 };
2897
2898 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2899 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2900
2901 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2902 };
2903
2904 // Call this member function to start using the mini-DSL defined above.
2905 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2906
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002907 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2908 static constexpr uint32_t kDefaultOutputOrientationFlags =
2909 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002910 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2911 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2912 static constexpr float kDefaultMaxLuminance = 0.9f;
2913 static constexpr float kDefaultAvgLuminance = 0.7f;
2914 static constexpr float kDefaultMinLuminance = 0.1f;
2915
2916 static const Rect kDefaultOutputFrame;
2917 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002918 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002919 static const mat4 kDefaultColorTransformMat;
2920
2921 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002922 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002923 static const HdrCapabilities kHdrCapabilities;
2924
Lloyd Pique56eba802019-08-28 15:45:25 -07002925 StrictMock<mock::CompositionEngine> mCompositionEngine;
2926 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002927 // TODO: make this is a proper mock.
2928 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002929 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2930 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002931 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002932 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002933
2934 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002935};
2936
2937const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2938const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002939const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002940const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002941const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002942const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2943const HdrCapabilities OutputComposeSurfacesTest::
2944 kHdrCapabilities{{},
2945 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2946 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2947 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002948
Lloyd Piquea76ce462020-01-14 13:06:37 -08002949TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002950 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002951
Lloyd Piquee9eff972020-05-05 12:36:44 -07002952 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2953
Lloyd Piquea76ce462020-01-14 13:06:37 -08002954 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2955
Lloyd Pique6818fa52019-12-03 12:32:13 -08002956 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002957}
2958
Lloyd Piquee9eff972020-05-05 12:36:44 -07002959TEST_F(OutputComposeSurfacesTest,
2960 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2961 mOutput.mState.usesClientComposition = false;
2962 mOutput.mState.flipClientTarget = true;
2963
Lloyd Pique6818fa52019-12-03 12:32:13 -08002964 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002965
2966 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2967 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2968
2969 verify().execute().expectAFenceWasReturned();
2970}
2971
2972TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2973 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2974
2975 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2976
2977 verify().execute().expectNoFenceWasReturned();
2978}
2979
2980TEST_F(OutputComposeSurfacesTest,
2981 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2982 mOutput.mState.usesClientComposition = false;
2983 mOutput.mState.flipClientTarget = true;
2984
2985 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002986
Lloyd Pique6818fa52019-12-03 12:32:13 -08002987 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002988
Lloyd Pique6818fa52019-12-03 12:32:13 -08002989 verify().execute().expectNoFenceWasReturned();
2990}
Lloyd Pique56eba802019-08-28 15:45:25 -07002991
Lloyd Pique6818fa52019-12-03 12:32:13 -08002992TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2993 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2994 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2995 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2996 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002997 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002998 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2999 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003000
Lloyd Pique6818fa52019-12-03 12:32:13 -08003001 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3002 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
3003 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003004
Lloyd Pique6818fa52019-12-03 12:32:13 -08003005 verify().execute().expectAFenceWasReturned();
3006}
Lloyd Pique56eba802019-08-28 15:45:25 -07003007
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003009 LayerFE::LayerSettings r1;
3010 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003011
3012 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3013 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3014
3015 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3016 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3017 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3018 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003019 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003020 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3021 .WillRepeatedly(
3022 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003023 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003024 clientCompositionLayers.emplace_back(r2);
3025 }));
3026
3027 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003028 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003029 .WillRepeatedly(Return(NO_ERROR));
3030
3031 verify().execute().expectAFenceWasReturned();
3032}
3033
Vishnu Nair9b079a22020-01-21 14:36:08 -08003034TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3035 mOutput.cacheClientCompositionRequests(0);
3036 LayerFE::LayerSettings r1;
3037 LayerFE::LayerSettings r2;
3038
3039 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3040 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3041
3042 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3043 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3044 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3045 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3046 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3047 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3048 .WillRepeatedly(Return());
3049
3050 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3051 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3052 .Times(2)
3053 .WillOnce(Return(NO_ERROR));
3054
3055 verify().execute().expectAFenceWasReturned();
3056 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3057
3058 verify().execute().expectAFenceWasReturned();
3059 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3060}
3061
3062TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3063 mOutput.cacheClientCompositionRequests(3);
3064 LayerFE::LayerSettings r1;
3065 LayerFE::LayerSettings r2;
3066
3067 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3068 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3069
3070 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3071 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3072 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3073 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3074 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3075 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3076 .WillRepeatedly(Return());
3077
3078 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3079 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3080 .WillOnce(Return(NO_ERROR));
3081 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3082
3083 verify().execute().expectAFenceWasReturned();
3084 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3085
3086 // We do not expect another call to draw layers.
3087 verify().execute().expectAFenceWasReturned();
3088 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3089}
3090
3091TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3092 LayerFE::LayerSettings r1;
3093 LayerFE::LayerSettings r2;
3094
3095 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3096 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3097
3098 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3099 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3100 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3101 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3102 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3103 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3104 .WillRepeatedly(Return());
3105
3106 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3107 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3108 .WillOnce(Return(mOutputBuffer))
3109 .WillOnce(Return(otherOutputBuffer));
3110 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3111 .WillRepeatedly(Return(NO_ERROR));
3112
3113 verify().execute().expectAFenceWasReturned();
3114 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3115
3116 verify().execute().expectAFenceWasReturned();
3117 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3118}
3119
3120TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3121 LayerFE::LayerSettings r1;
3122 LayerFE::LayerSettings r2;
3123 LayerFE::LayerSettings r3;
3124
3125 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3126 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3127 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3128
3129 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3130 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3131 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3132 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3133 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3134 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3135 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3136 .WillRepeatedly(Return());
3137
3138 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3139 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3140 .WillOnce(Return(NO_ERROR));
3141 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3142 .WillOnce(Return(NO_ERROR));
3143
3144 verify().execute().expectAFenceWasReturned();
3145 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3146
3147 verify().execute().expectAFenceWasReturned();
3148 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3149}
3150
Lloyd Pique6818fa52019-12-03 12:32:13 -08003151struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3152 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3153 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3154 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003155 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3157 .WillRepeatedly(Return());
3158 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3159 }
3160
3161 struct MixedCompositionState
3162 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3163 auto ifMixedCompositionIs(bool used) {
3164 getInstance()->mOutput.mState.usesDeviceComposition = used;
3165 return nextState<OutputUsesHdrState>();
3166 }
3167 };
3168
3169 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3170 auto andIfUsesHdr(bool used) {
3171 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3172 .WillOnce(Return(used));
3173 return nextState<SkipColorTransformState>();
3174 }
3175 };
3176
3177 struct SkipColorTransformState
3178 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3179 auto andIfSkipColorTransform(bool skip) {
3180 // May be called zero or one times.
3181 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3182 .WillRepeatedly(Return(skip));
3183 return nextState<ExpectDisplaySettingsState>();
3184 }
3185 };
3186
3187 struct ExpectDisplaySettingsState
3188 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3189 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3190 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3191 .WillOnce(Return(NO_ERROR));
3192 return nextState<ExecuteState>();
3193 }
3194 };
3195
3196 // Call this member function to start using the mini-DSL defined above.
3197 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3198};
3199
3200TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3201 verify().ifMixedCompositionIs(true)
3202 .andIfUsesHdr(true)
3203 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003204 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003205 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003206 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003207 .execute()
3208 .expectAFenceWasReturned();
3209}
3210
3211TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3212 verify().ifMixedCompositionIs(true)
3213 .andIfUsesHdr(false)
3214 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003215 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003216 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003217 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003218 .execute()
3219 .expectAFenceWasReturned();
3220}
3221
3222TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3223 verify().ifMixedCompositionIs(false)
3224 .andIfUsesHdr(true)
3225 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003226 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003227 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003228 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003229 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003230 .execute()
3231 .expectAFenceWasReturned();
3232}
3233
3234TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3235 verify().ifMixedCompositionIs(false)
3236 .andIfUsesHdr(false)
3237 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003238 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003239 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003240 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003241 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003242 .execute()
3243 .expectAFenceWasReturned();
3244}
3245
3246TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3247 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3248 verify().ifMixedCompositionIs(false)
3249 .andIfUsesHdr(true)
3250 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003251 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003252 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003253 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003254 .execute()
3255 .expectAFenceWasReturned();
3256}
3257
3258struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3259 struct Layer {
3260 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003261 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3262 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003263 }
3264
3265 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003266 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003267 LayerFECompositionState mLayerFEState;
3268 };
3269
3270 OutputComposeSurfacesTest_HandlesProtectedContent() {
3271 mLayer1.mLayerFEState.hasProtectedContent = false;
3272 mLayer2.mLayerFEState.hasProtectedContent = false;
3273
3274 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3275 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3276 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3277 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3278 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3279
3280 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3281
3282 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3283
3284 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003285 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003286 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3287 .WillRepeatedly(Return());
3288 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3289 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3290 .WillRepeatedly(Return(NO_ERROR));
3291 }
3292
3293 Layer mLayer1;
3294 Layer mLayer2;
3295};
3296
3297TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3298 mOutput.mState.isSecure = false;
3299 mLayer2.mLayerFEState.hasProtectedContent = true;
3300 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3301
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003302 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003303}
3304
3305TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3306 mOutput.mState.isSecure = true;
3307 mLayer2.mLayerFEState.hasProtectedContent = true;
3308 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3309
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003310 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003311}
3312
3313TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3314 mOutput.mState.isSecure = true;
3315 mLayer2.mLayerFEState.hasProtectedContent = false;
3316 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3317 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3318 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3319 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3320 EXPECT_CALL(*mRenderSurface, setProtected(false));
3321
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003322 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323}
3324
3325TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3326 mOutput.mState.isSecure = true;
3327 mLayer2.mLayerFEState.hasProtectedContent = true;
3328 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3329
3330 // For this test, we also check the call order of key functions.
3331 InSequence seq;
3332
3333 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3334 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3335 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3336 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3337 EXPECT_CALL(*mRenderSurface, setProtected(true));
3338 // Must happen after setting the protected content state.
3339 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3340 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3341
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003342 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003343}
3344
3345TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3346 mOutput.mState.isSecure = true;
3347 mLayer2.mLayerFEState.hasProtectedContent = true;
3348 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3349 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3350 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3351
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003352 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353}
3354
3355TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3356 mOutput.mState.isSecure = true;
3357 mLayer2.mLayerFEState.hasProtectedContent = true;
3358 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3359 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3360 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3361 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3362
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003363 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003364}
3365
3366TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3367 mOutput.mState.isSecure = true;
3368 mLayer2.mLayerFEState.hasProtectedContent = true;
3369 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3370 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3371 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3372 EXPECT_CALL(*mRenderSurface, setProtected(true));
3373
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003374 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003375}
3376
3377TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3378 mOutput.mState.isSecure = true;
3379 mLayer2.mLayerFEState.hasProtectedContent = true;
3380 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3381 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3382 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3383 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3384
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003385 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003386}
3387
3388struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3389 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3390 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3391 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3392 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3393 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3394 .WillRepeatedly(Return());
3395 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3396 }
3397};
3398
3399TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3400 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3401
3402 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003403 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404
3405 // For this test, we also check the call order of key functions.
3406 InSequence seq;
3407
3408 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3409 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003411 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3412}
3413
3414struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3415 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3416 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3417 mLayer.layerFEState.backgroundBlurRadius = 10;
3418 mOutput.editState().isEnabled = true;
3419
Snild Dolkow9e217d62020-04-22 15:53:42 +02003420 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003421 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3422 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3423 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3424 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3425 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3426 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3427 .WillRepeatedly(Return(&mLayer.outputLayer));
3428 }
3429
3430 NonInjectedLayer mLayer;
3431 compositionengine::CompositionRefreshArgs mRefreshArgs;
3432};
3433
3434TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3435 mRefreshArgs.blursAreExpensive = true;
3436 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3437
3438 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3439 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3440}
3441
3442TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3443 mRefreshArgs.blursAreExpensive = false;
3444 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3445
3446 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3447 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003448}
3449
3450/*
3451 * Output::generateClientCompositionRequests()
3452 */
3453
3454struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003455 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003456 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003457 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003458 bool supportsProtectedContent, Region& clearRegion,
3459 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003460 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003461 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003462 }
3463 };
3464
Lloyd Piquea4863342019-12-04 18:45:02 -08003465 struct Layer {
3466 Layer() {
3467 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3468 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003469 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003470 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003471 }
3472
3473 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003474 StrictMock<mock::LayerFE> mLayerFE;
3475 LayerFECompositionState mLayerFEState;
3476 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003477 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003478 };
3479
Lloyd Pique56eba802019-08-28 15:45:25 -07003480 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003481 mOutput.mState.needsFiltering = false;
3482
Lloyd Pique56eba802019-08-28 15:45:25 -07003483 mOutput.setDisplayColorProfileForTest(
3484 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3485 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3486 }
3487
Lloyd Pique56eba802019-08-28 15:45:25 -07003488 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3489 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003490 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003491};
3492
Lloyd Piquea4863342019-12-04 18:45:02 -08003493struct GenerateClientCompositionRequestsTest_ThreeLayers
3494 : public GenerateClientCompositionRequestsTest {
3495 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003496 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3497 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3498 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003499 mOutput.mState.transform =
3500 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3501 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003502 mOutput.mState.needsFiltering = false;
3503 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003504
Lloyd Piquea4863342019-12-04 18:45:02 -08003505 for (size_t i = 0; i < mLayers.size(); i++) {
3506 mLayers[i].mOutputLayerState.clearClientTarget = false;
3507 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3508 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003509 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003510 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003511 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3512 mLayers[i].mLayerSettings.alpha = 1.0f;
3513 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003514
Lloyd Piquea4863342019-12-04 18:45:02 -08003515 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3516 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3517 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3518 .WillRepeatedly(Return(true));
3519 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3520 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003521
Lloyd Piquea4863342019-12-04 18:45:02 -08003522 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3523 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003524
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003525 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003526 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003527
Lloyd Piquea4863342019-12-04 18:45:02 -08003528 static const Rect kDisplayFrame;
3529 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003530 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003531
Lloyd Piquea4863342019-12-04 18:45:02 -08003532 std::array<Layer, 3> mLayers;
3533};
Lloyd Pique56eba802019-08-28 15:45:25 -07003534
Lloyd Piquea4863342019-12-04 18:45:02 -08003535const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3536const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003537const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3538 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003539
Lloyd Piquea4863342019-12-04 18:45:02 -08003540TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3541 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3542 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3543 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003544
Lloyd Piquea4863342019-12-04 18:45:02 -08003545 Region accumClearRegion(Rect(10, 11, 12, 13));
3546 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3547 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003548 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003549 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003550}
3551
Lloyd Piquea4863342019-12-04 18:45:02 -08003552TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3553 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3554 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3555 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3556
3557 Region accumClearRegion(Rect(10, 11, 12, 13));
3558 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3559 accumClearRegion, kDisplayDataspace);
3560 EXPECT_EQ(0u, requests.size());
3561 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3562}
3563
3564TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003565 LayerFE::LayerSettings mShadowSettings;
3566 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003567
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003568 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3569 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3570 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3571 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3572 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3573 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3574 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003575
3576 Region accumClearRegion(Rect(10, 11, 12, 13));
3577 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3578 accumClearRegion, kDisplayDataspace);
3579 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003580 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3581 EXPECT_EQ(mShadowSettings, requests[1]);
3582 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003583
3584 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3585
3586 // Check that a timestamp was set for the layers that generated requests
3587 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3588 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3589 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3590}
3591
3592TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3593 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3594 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3595 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3596 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3597
3598 mLayers[0].mOutputLayerState.clearClientTarget = false;
3599 mLayers[1].mOutputLayerState.clearClientTarget = false;
3600 mLayers[2].mOutputLayerState.clearClientTarget = false;
3601
3602 mLayers[0].mLayerFEState.isOpaque = true;
3603 mLayers[1].mLayerFEState.isOpaque = true;
3604 mLayers[2].mLayerFEState.isOpaque = true;
3605
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003606 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3607 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003608
3609 Region accumClearRegion(Rect(10, 11, 12, 13));
3610 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3611 accumClearRegion, kDisplayDataspace);
3612 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003613 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003614
3615 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3616}
3617
3618TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3619 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3620 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3621 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3622 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3623
3624 mLayers[0].mOutputLayerState.clearClientTarget = true;
3625 mLayers[1].mOutputLayerState.clearClientTarget = true;
3626 mLayers[2].mOutputLayerState.clearClientTarget = true;
3627
3628 mLayers[0].mLayerFEState.isOpaque = false;
3629 mLayers[1].mLayerFEState.isOpaque = false;
3630 mLayers[2].mLayerFEState.isOpaque = false;
3631
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003632 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3633 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003634
3635 Region accumClearRegion(Rect(10, 11, 12, 13));
3636 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3637 accumClearRegion, kDisplayDataspace);
3638 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003639 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003640
3641 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3642}
3643
3644TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003645 // If client composition is performed with some layers set to use device
3646 // composition, device layers after the first layer (device or client) will
3647 // clear the frame buffer if they are opaque and if that layer has a flag
3648 // set to do so. The first layer is skipped as the frame buffer is already
3649 // expected to be clear.
3650
Lloyd Piquea4863342019-12-04 18:45:02 -08003651 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3652 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3653 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003654
Lloyd Piquea4863342019-12-04 18:45:02 -08003655 mLayers[0].mOutputLayerState.clearClientTarget = true;
3656 mLayers[1].mOutputLayerState.clearClientTarget = true;
3657 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003658
Lloyd Piquea4863342019-12-04 18:45:02 -08003659 mLayers[0].mLayerFEState.isOpaque = true;
3660 mLayers[1].mLayerFEState.isOpaque = true;
3661 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003662 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003663 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003664
3665 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3666 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003667 false, /* needs filtering */
3668 false, /* secure */
3669 false, /* supports protected content */
3670 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003671 kDisplayViewport,
3672 kDisplayDataspace,
3673 false /* realContentIsVisible */,
3674 true /* clearContent */,
3675 };
3676 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3677 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003678 false, /* needs filtering */
3679 false, /* secure */
3680 false, /* supports protected content */
3681 accumClearRegion,
3682 kDisplayViewport,
3683 kDisplayDataspace,
3684 true /* realContentIsVisible */,
3685 false /* clearContent */,
3686 };
3687
3688 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3689 mBlackoutSettings.source.buffer.buffer = nullptr;
3690 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3691 mBlackoutSettings.alpha = 0.f;
3692 mBlackoutSettings.disableBlending = true;
3693
3694 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3695 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3696 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3697 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3698
Lloyd Piquea4863342019-12-04 18:45:02 -08003699 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3700 accumClearRegion, kDisplayDataspace);
3701 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003702
Lloyd Piquea4863342019-12-04 18:45:02 -08003703 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003704 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003705
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003707
Lloyd Piquea4863342019-12-04 18:45:02 -08003708 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3709}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003710
Lloyd Piquea4863342019-12-04 18:45:02 -08003711TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3712 clippedVisibleRegionUsedToGenerateRequest) {
3713 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3714 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3715 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003716
Lloyd Piquea4863342019-12-04 18:45:02 -08003717 Region accumClearRegion(Rect(10, 11, 12, 13));
3718
3719 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3720 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003721 false, /* needs filtering */
3722 false, /* secure */
3723 false, /* supports protected content */
3724 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003725 kDisplayViewport,
3726 kDisplayDataspace,
3727 true /* realContentIsVisible */,
3728 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003729 };
3730 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3731 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003732 false, /* needs filtering */
3733 false, /* secure */
3734 false, /* supports protected content */
3735 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003736 kDisplayViewport,
3737 kDisplayDataspace,
3738 true /* realContentIsVisible */,
3739 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003740 };
3741 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3742 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003743 false, /* needs filtering */
3744 false, /* secure */
3745 false, /* supports protected content */
3746 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003747 kDisplayViewport,
3748 kDisplayDataspace,
3749 true /* realContentIsVisible */,
3750 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003751 };
3752
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003753 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3754 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3755 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3756 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3757 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3758 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003759
3760 static_cast<void>(
3761 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3762 accumClearRegion, kDisplayDataspace));
3763}
3764
3765TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3766 perLayerNeedsFilteringUsedToGenerateRequests) {
3767 mOutput.mState.needsFiltering = false;
3768 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3769
3770 Region accumClearRegion(Rect(10, 11, 12, 13));
3771
3772 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3773 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003774 true, /* needs filtering */
3775 false, /* secure */
3776 false, /* supports protected content */
3777 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003778 kDisplayViewport,
3779 kDisplayDataspace,
3780 true /* realContentIsVisible */,
3781 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003782 };
3783 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3784 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003785 false, /* needs filtering */
3786 false, /* secure */
3787 false, /* supports protected content */
3788 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003789 kDisplayViewport,
3790 kDisplayDataspace,
3791 true /* realContentIsVisible */,
3792 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003793 };
3794 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3795 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003796 false, /* needs filtering */
3797 false, /* secure */
3798 false, /* supports protected content */
3799 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003800 kDisplayViewport,
3801 kDisplayDataspace,
3802 true /* realContentIsVisible */,
3803 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003804 };
3805
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003806 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3807 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3808 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3809 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3810 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3811 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003812
3813 static_cast<void>(
3814 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3815 accumClearRegion, kDisplayDataspace));
3816}
3817
3818TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3819 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3820 mOutput.mState.needsFiltering = true;
3821 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3822
3823 Region accumClearRegion(Rect(10, 11, 12, 13));
3824
3825 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3826 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003827 true, /* needs filtering */
3828 false, /* secure */
3829 false, /* supports protected content */
3830 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003831 kDisplayViewport,
3832 kDisplayDataspace,
3833 true /* realContentIsVisible */,
3834 false /* clearContent */,
3835
Lloyd Piquea4863342019-12-04 18:45:02 -08003836 };
3837 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3838 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003839 true, /* needs filtering */
3840 false, /* secure */
3841 false, /* supports protected content */
3842 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003843 kDisplayViewport,
3844 kDisplayDataspace,
3845 true /* realContentIsVisible */,
3846 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003847 };
3848 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3849 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003850 true, /* needs filtering */
3851 false, /* secure */
3852 false, /* supports protected content */
3853 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003854 kDisplayViewport,
3855 kDisplayDataspace,
3856 true /* realContentIsVisible */,
3857 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003858 };
3859
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003860 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3861 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3862 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3863 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3864 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3865 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003866
3867 static_cast<void>(
3868 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3869 accumClearRegion, kDisplayDataspace));
3870}
3871
3872TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3873 wholeOutputSecurityUsedToGenerateRequests) {
3874 mOutput.mState.isSecure = true;
3875
3876 Region accumClearRegion(Rect(10, 11, 12, 13));
3877
3878 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3879 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003880 false, /* needs filtering */
3881 true, /* secure */
3882 false, /* supports protected content */
3883 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003884 kDisplayViewport,
3885 kDisplayDataspace,
3886 true /* realContentIsVisible */,
3887 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003888 };
3889 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3890 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003891 false, /* needs filtering */
3892 true, /* secure */
3893 false, /* supports protected content */
3894 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003895 kDisplayViewport,
3896 kDisplayDataspace,
3897 true /* realContentIsVisible */,
3898 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 };
3900 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3901 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003902 false, /* needs filtering */
3903 true, /* secure */
3904 false, /* supports protected content */
3905 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003906 kDisplayViewport,
3907 kDisplayDataspace,
3908 true /* realContentIsVisible */,
3909 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003910 };
3911
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003912 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3913 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3914 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3915 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3916 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003918
3919 static_cast<void>(
3920 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3921 accumClearRegion, kDisplayDataspace));
3922}
3923
3924TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3925 protectedContentSupportUsedToGenerateRequests) {
3926 Region accumClearRegion(Rect(10, 11, 12, 13));
3927
3928 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3929 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003930 false, /* needs filtering */
3931 false, /* secure */
3932 true, /* supports protected content */
3933 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003934 kDisplayViewport,
3935 kDisplayDataspace,
3936 true /* realContentIsVisible */,
3937 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003938 };
3939 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3940 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003941 false, /* needs filtering */
3942 false, /* secure */
3943 true, /* supports protected content */
3944 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003945 kDisplayViewport,
3946 kDisplayDataspace,
3947 true /* realContentIsVisible */,
3948 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003949 };
3950 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3951 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003952 false, /* needs filtering */
3953 false, /* secure */
3954 true, /* supports protected content */
3955 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003956 kDisplayViewport,
3957 kDisplayDataspace,
3958 true /* realContentIsVisible */,
3959 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 };
3961
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003962 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3963 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3964 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3965 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3966 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3967 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003968
3969 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3970 accumClearRegion,
3971 kDisplayDataspace));
3972}
3973
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003974TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003975 InjectedLayer layer1;
3976 InjectedLayer layer2;
3977 InjectedLayer layer3;
3978
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003979 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003980 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003981 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003982 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003983 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003984 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003985 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003986
Lloyd Piquede196652020-01-22 17:29:58 -08003987 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003988
Lloyd Piquede196652020-01-22 17:29:58 -08003989 injectOutputLayer(layer1);
3990 injectOutputLayer(layer2);
3991 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003992
3993 mOutput->editState().isEnabled = true;
3994
3995 CompositionRefreshArgs args;
3996 args.updatingGeometryThisFrame = false;
3997 args.devOptForceClientComposition = false;
3998 mOutput->updateAndWriteCompositionState(args);
3999}
4000
Lloyd Piquea4863342019-12-04 18:45:02 -08004001TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4002 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4003 // one layer on the left covering the left side of the output, and one layer
4004 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004005
4006 const Rect kPortraitFrame(0, 0, 1000, 2000);
4007 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004008 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004009 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004010 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004011
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004012 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4013 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4014 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004015 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4016 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004017 mOutput.mState.needsFiltering = false;
4018 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004019
Lloyd Piquea4863342019-12-04 18:45:02 -08004020 Layer leftLayer;
4021 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004022
Lloyd Piquea4863342019-12-04 18:45:02 -08004023 leftLayer.mOutputLayerState.clearClientTarget = false;
4024 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4025 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004026 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004027
Lloyd Piquea4863342019-12-04 18:45:02 -08004028 rightLayer.mOutputLayerState.clearClientTarget = false;
4029 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4030 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004031 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004032
4033 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4034 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4035 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4036 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4037 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4038
4039 Region accumClearRegion(Rect(10, 11, 12, 13));
4040
4041 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4042 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004043 false, /* needs filtering */
4044 true, /* secure */
4045 true, /* supports protected content */
4046 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004047 kPortraitViewport,
4048 kOutputDataspace,
4049 true /* realContentIsVisible */,
4050 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004051 };
4052
4053 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4054 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004055 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4056 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004057
4058 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4059 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004060 false, /* needs filtering */
4061 true, /* secure */
4062 true, /* supports protected content */
4063 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004064 kPortraitViewport,
4065 kOutputDataspace,
4066 true /* realContentIsVisible */,
4067 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004068 };
4069
4070 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4071 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004072 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4073 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004074
4075 constexpr bool supportsProtectedContent = true;
4076 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4077 accumClearRegion, kOutputDataspace);
4078 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004079 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4080 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004081}
4082
Vishnu Naira483b4a2019-12-12 15:07:52 -08004083TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4084 shadowRegionOnlyVisibleSkipsContentComposition) {
4085 const Rect kContentWithShadow(40, 40, 70, 90);
4086 const Rect kContent(50, 50, 60, 80);
4087 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4088 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4089
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004090 Region accumClearRegion(Rect(10, 11, 12, 13));
4091 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4092 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004093 false, /* needs filtering */
4094 false, /* secure */
4095 false, /* supports protected content */
4096 accumClearRegion,
4097 kDisplayViewport,
4098 kDisplayDataspace,
4099 false /* realContentIsVisible */,
4100 false /* clearContent */,
4101 };
4102
Vishnu Nair9b079a22020-01-21 14:36:08 -08004103 LayerFE::LayerSettings mShadowSettings;
4104 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004105
4106 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4107 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4108
4109 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4110 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004111 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4112 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004113
Vishnu Naira483b4a2019-12-12 15:07:52 -08004114 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4115 accumClearRegion, kDisplayDataspace);
4116 ASSERT_EQ(1u, requests.size());
4117
Vishnu Nair9b079a22020-01-21 14:36:08 -08004118 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004119}
4120
4121TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4122 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4123 const Rect kContentWithShadow(40, 40, 70, 90);
4124 const Rect kContent(50, 50, 60, 80);
4125 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4126 const Region kPartialContentWithPartialShadowRegion =
4127 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4128
Vishnu Nair9b079a22020-01-21 14:36:08 -08004129 LayerFE::LayerSettings mShadowSettings;
4130 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004131
4132 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4133 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4134
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004135 Region accumClearRegion(Rect(10, 11, 12, 13));
4136 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4137 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004138 false, /* needs filtering */
4139 false, /* secure */
4140 false, /* supports protected content */
4141 accumClearRegion,
4142 kDisplayViewport,
4143 kDisplayDataspace,
4144 true /* realContentIsVisible */,
4145 false /* clearContent */,
4146 };
4147
Vishnu Naira483b4a2019-12-12 15:07:52 -08004148 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4149 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004150 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4151 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4152 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004153
Vishnu Naira483b4a2019-12-12 15:07:52 -08004154 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4155 accumClearRegion, kDisplayDataspace);
4156 ASSERT_EQ(2u, requests.size());
4157
Vishnu Nair9b079a22020-01-21 14:36:08 -08004158 EXPECT_EQ(mShadowSettings, requests[0]);
4159 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004160}
4161
Lloyd Pique32cbe282018-10-19 13:09:22 -07004162} // namespace
4163} // namespace android::compositionengine