blob: f654c2fd07e2391e41a5943dedd299a9ebc90188 [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));
Dan Stoza269dc4d2021-01-15 15:07:43 -080099 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
100 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800101 }
102
103 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
104 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
105 LayerFECompositionState layerFEState;
106 impl::OutputLayerCompositionState outputLayerState;
107};
108
109struct NonInjectedLayer {
110 NonInjectedLayer() {
111 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
112 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
113 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
114
115 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800116 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
117 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800118 }
119
120 mock::OutputLayer outputLayer;
121 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
122 LayerFECompositionState layerFEState;
123 impl::OutputLayerCompositionState outputLayerState;
124};
125
Lloyd Pique66d68602019-02-13 14:23:31 -0800126struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700127 class Output : public impl::Output {
128 public:
129 using impl::Output::injectOutputLayerForTest;
130 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
131 };
132
133 static std::shared_ptr<Output> createOutput(
134 const compositionengine::CompositionEngine& compositionEngine) {
135 return impl::createOutputTemplated<Output>(compositionEngine);
136 }
137
Lloyd Pique31cb2942018-10-19 17:23:03 -0700138 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700139 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700140 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700141 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800142
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200143 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700144 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700145
Lloyd Piquede196652020-01-22 17:29:58 -0800146 void injectOutputLayer(InjectedLayer& layer) {
147 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
148 }
149
150 void injectNullOutputLayer() {
151 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
152 }
153
Lloyd Piqueef958122019-02-05 18:00:12 -0800154 static const Rect kDefaultDisplaySize;
155
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700157 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700158 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700159 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700160};
161
Lloyd Piqueef958122019-02-05 18:00:12 -0800162const Rect OutputTest::kDefaultDisplaySize{100, 200};
163
Lloyd Pique17ca7422019-11-14 14:24:10 -0800164using ColorProfile = compositionengine::Output::ColorProfile;
165
166void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
167 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
168 toString(profile.mode).c_str(), profile.mode,
169 toString(profile.dataspace).c_str(), profile.dataspace,
170 toString(profile.renderIntent).c_str(), profile.renderIntent,
171 toString(profile.colorSpaceAgnosticDataspace).c_str(),
172 profile.colorSpaceAgnosticDataspace);
173}
174
175// Checks for a ColorProfile match
176MATCHER_P(ColorProfileEq, expected, "") {
177 std::string buf;
178 buf.append("ColorProfiles are not equal\n");
179 dumpColorProfile(expected, buf, "expected value");
180 dumpColorProfile(arg, buf, "actual value");
181 *result_listener << buf;
182
183 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
184 (expected.renderIntent == arg.renderIntent) &&
185 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
186}
187
Lloyd Pique66d68602019-02-13 14:23:31 -0800188/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700189 * Basic construction
190 */
191
Lloyd Pique31cb2942018-10-19 17:23:03 -0700192TEST_F(OutputTest, canInstantiateOutput) {
193 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700194 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700195 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
196
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700197 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700198
199 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700200 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700202 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
203
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700204 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700205}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700206
Lloyd Pique66d68602019-02-13 14:23:31 -0800207/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208 * Output::setCompositionEnabled()
209 */
210
211TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700213
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700214 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 EXPECT_TRUE(mOutput->getState().isEnabled);
217 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218}
219
220TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 EXPECT_TRUE(mOutput->getState().isEnabled);
226 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227}
228
229TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700231
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 EXPECT_FALSE(mOutput->getState().isEnabled);
235 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236}
237
Lloyd Pique66d68602019-02-13 14:23:31 -0800238/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239 * Output::setProjection()
240 */
241
Marin Shalamanov209ae612020-10-01 00:17:39 +0200242TEST_F(OutputTest, setProjectionWorks) {
243 const Rect displayRect{0, 0, 1000, 2000};
244 mOutput->editState().displaySpace.bounds = displayRect;
245 mOutput->editState().framebufferSpace.bounds = displayRect;
246
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200247 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200248 const Rect frame{50, 60, 100, 100};
249 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700250
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200251 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700252
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200253 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200254 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
255 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200256
257 const auto state = mOutput->getState();
258 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
259 EXPECT_EQ(viewport, state.layerStackSpace.content);
260 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
261
262 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
263 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
264 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
265
266 EXPECT_EQ(displayRect, state.displaySpace.bounds);
267 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
268 EXPECT_EQ(orientation, state.displaySpace.orientation);
269
270 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
271 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
272 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
273
274 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700275
276 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200277}
278
279TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
280 const Rect displayRect{0, 0, 1000, 2000};
281 const Rect framebufferRect{0, 0, 500, 1000};
282 mOutput->editState().displaySpace.bounds = displayRect;
283 mOutput->editState().framebufferSpace.bounds = framebufferRect;
284
285 const ui::Rotation orientation = ui::ROTATION_90;
286 const Rect frame{50, 60, 100, 100};
287 const Rect viewport{10, 20, 30, 40};
288
289 mOutput->setProjection(orientation, viewport, frame);
290
291 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
292 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
293 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
294
295 const auto state = mOutput->getState();
296 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
297 EXPECT_EQ(viewport, state.layerStackSpace.content);
298 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
299
300 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
301 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
302 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
303
304 EXPECT_EQ(displayRect, state.displaySpace.bounds);
305 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
306 EXPECT_EQ(orientation, state.displaySpace.orientation);
307
308 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
309 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
310 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
311
312 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700313}
314
Lloyd Pique66d68602019-02-13 14:23:31 -0800315/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200316 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700317 */
318
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200319TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
320 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
321 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
322 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
323 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
324 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
325 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
326 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
327 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
328 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
329 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700330
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200331 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700332
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200333 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700334
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200335 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700336
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200337 const auto state = mOutput->getState();
338
339 const Rect displayRect(newDisplaySize);
340 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
341 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
342 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200343
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200344 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200345 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200346
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200347 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200348 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200349
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200350 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200351 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
352
353 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
354
355 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700356}
357
Lloyd Pique66d68602019-02-13 14:23:31 -0800358/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700359 * Output::setLayerStackFilter()
360 */
361
362TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700363 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700364 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700365
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700366 EXPECT_TRUE(mOutput->getState().layerStackInternal);
367 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700368
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700369 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700370}
371
Lloyd Pique66d68602019-02-13 14:23:31 -0800372/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700373 * Output::setColorTransform
374 */
375
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800376TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700377 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700378
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800379 // If no colorTransformMatrix is set the update should be skipped.
380 CompositionRefreshArgs refreshArgs;
381 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700382
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700383 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800385 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700386 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800387
388 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700389 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800390}
Lloyd Piqueef958122019-02-05 18:00:12 -0800391
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800392TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700393 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700394
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800395 // Attempting to set the same colorTransformMatrix that is already set should
396 // also skip the update.
397 CompositionRefreshArgs refreshArgs;
398 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700399
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700400 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700401
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800402 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700403 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800404
405 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700406 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800407}
408
409TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700410 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800411
412 // Setting a different colorTransformMatrix should perform the update.
413 CompositionRefreshArgs refreshArgs;
414 refreshArgs.colorTransformMatrix = kIdentity;
415
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700416 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800417
418 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700419 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800420
421 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700422 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800423}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700424
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800425TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700426 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700427
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800428 // Setting a different colorTransformMatrix should perform the update.
429 CompositionRefreshArgs refreshArgs;
430 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700431
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800433
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800434 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436
437 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439}
440
441TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700442 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800443
444 // Setting a different colorTransformMatrix should perform the update.
445 CompositionRefreshArgs refreshArgs;
446 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
447
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700448 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449
450 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452
453 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455}
456
Lloyd Pique66d68602019-02-13 14:23:31 -0800457/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800458 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459 */
460
Lloyd Pique17ca7422019-11-14 14:24:10 -0800461using OutputSetColorProfileTest = OutputTest;
462
463TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800464 using ColorProfile = Output::ColorProfile;
465
Lloyd Piquef5275482019-01-29 18:42:42 -0800466 EXPECT_CALL(*mDisplayColorProfile,
467 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
468 ui::Dataspace::UNKNOWN))
469 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800470 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700471
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700472 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
473 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
474 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700475
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
477 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
478 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
479 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800480
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800482}
483
Lloyd Pique17ca7422019-11-14 14:24:10 -0800484TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800485 using ColorProfile = Output::ColorProfile;
486
Lloyd Piquef5275482019-01-29 18:42:42 -0800487 EXPECT_CALL(*mDisplayColorProfile,
488 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
489 ui::Dataspace::UNKNOWN))
490 .WillOnce(Return(ui::Dataspace::UNKNOWN));
491
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
493 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
494 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
495 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800496
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
498 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
499 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800500
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700501 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700502}
503
Lloyd Pique66d68602019-02-13 14:23:31 -0800504/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700505 * Output::setRenderSurface()
506 */
507
508TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
509 const ui::Size newDisplaySize{640, 480};
510
511 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
512 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
513
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700515
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200516 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700517}
518
Lloyd Pique66d68602019-02-13 14:23:31 -0800519/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000520 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700521 */
522
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000523TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
524 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200525 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700527
528 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700530
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000531 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700532 }
533}
534
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000535TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
536 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200537 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700538 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539
540 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700541 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700542
543 // The dirtyRegion should be clipped to the display bounds.
544 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
545 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700546}
547
Lloyd Pique66d68602019-02-13 14:23:31 -0800548/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800549 * Output::belongsInOutput()
550 */
551
552TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
553 const uint32_t layerStack1 = 123u;
554 const uint32_t layerStack2 = 456u;
555
556 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700557 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800558
Lloyd Piquec6687342019-03-07 21:34:57 -0800559 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700560 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
561 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800562
Lloyd Piqueef36b002019-01-23 17:52:04 -0800563 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700564 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
565 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
566 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
567 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800568
569 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700570 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800571
572 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700573 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
574 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
575 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
576 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800577}
578
Lloyd Piquede196652020-01-22 17:29:58 -0800579TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
580 NonInjectedLayer layer;
581 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800582
Lloyd Piquede196652020-01-22 17:29:58 -0800583 // If the layer has no composition state, it does not belong to any output.
584 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
585 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
586}
587
588TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
589 NonInjectedLayer layer;
590 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800591
592 const uint32_t layerStack1 = 123u;
593 const uint32_t layerStack2 = 456u;
594
595 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700596 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800597
Lloyd Pique66c20c42019-03-07 21:44:02 -0800598 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800599 layer.layerFEState.layerStackId = std::nullopt;
600 layer.layerFEState.internalOnly = false;
601 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800602
Lloyd Piquede196652020-01-22 17:29:58 -0800603 layer.layerFEState.layerStackId = std::nullopt;
604 layer.layerFEState.internalOnly = true;
605 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800606
607 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800608 layer.layerFEState.layerStackId = layerStack1;
609 layer.layerFEState.internalOnly = false;
610 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800611
Lloyd Piquede196652020-01-22 17:29:58 -0800612 layer.layerFEState.layerStackId = layerStack1;
613 layer.layerFEState.internalOnly = true;
614 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800615
Lloyd Piquede196652020-01-22 17:29:58 -0800616 layer.layerFEState.layerStackId = layerStack2;
617 layer.layerFEState.internalOnly = true;
618 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800619
Lloyd Piquede196652020-01-22 17:29:58 -0800620 layer.layerFEState.layerStackId = layerStack2;
621 layer.layerFEState.internalOnly = false;
622 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800623
624 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700625 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800626
Lloyd Pique66c20c42019-03-07 21:44:02 -0800627 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800628 layer.layerFEState.layerStackId = layerStack1;
629 layer.layerFEState.internalOnly = false;
630 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800631
Lloyd Piquede196652020-01-22 17:29:58 -0800632 layer.layerFEState.layerStackId = layerStack1;
633 layer.layerFEState.internalOnly = true;
634 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Lloyd Piquede196652020-01-22 17:29:58 -0800636 layer.layerFEState.layerStackId = layerStack2;
637 layer.layerFEState.internalOnly = true;
638 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800639
Lloyd Piquede196652020-01-22 17:29:58 -0800640 layer.layerFEState.layerStackId = layerStack2;
641 layer.layerFEState.internalOnly = false;
642 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800643}
644
Lloyd Pique66d68602019-02-13 14:23:31 -0800645/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800646 * Output::getOutputLayerForLayer()
647 */
648
649TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800650 InjectedLayer layer1;
651 InjectedLayer layer2;
652 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800653
Lloyd Piquede196652020-01-22 17:29:58 -0800654 injectOutputLayer(layer1);
655 injectNullOutputLayer();
656 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800657
658 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800659 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
660 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800661
662 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800663 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
664 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
665 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800666
667 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800668 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
669 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
670 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800671}
672
Lloyd Pique66d68602019-02-13 14:23:31 -0800673/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800674 * Output::setReleasedLayers()
675 */
676
677using OutputSetReleasedLayersTest = OutputTest;
678
679TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
680 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
681 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
682 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
683
684 Output::ReleasedLayers layers;
685 layers.push_back(layer1FE);
686 layers.push_back(layer2FE);
687 layers.push_back(layer3FE);
688
689 mOutput->setReleasedLayers(std::move(layers));
690
691 const auto& setLayers = mOutput->getReleasedLayersForTest();
692 ASSERT_EQ(3u, setLayers.size());
693 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
694 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
695 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
696}
697
698/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800699 * Output::updateLayerStateFromFE()
700 */
701
Lloyd Piquede196652020-01-22 17:29:58 -0800702using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800703
704TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
705 CompositionRefreshArgs refreshArgs;
706
707 mOutput->updateLayerStateFromFE(refreshArgs);
708}
709
Lloyd Piquede196652020-01-22 17:29:58 -0800710TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
711 InjectedLayer layer1;
712 InjectedLayer layer2;
713 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800714
Lloyd Piquede196652020-01-22 17:29:58 -0800715 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
716 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
717 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
718
719 injectOutputLayer(layer1);
720 injectOutputLayer(layer2);
721 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800722
723 CompositionRefreshArgs refreshArgs;
724 refreshArgs.updatingGeometryThisFrame = false;
725
726 mOutput->updateLayerStateFromFE(refreshArgs);
727}
728
Lloyd Piquede196652020-01-22 17:29:58 -0800729TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
730 InjectedLayer layer1;
731 InjectedLayer layer2;
732 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800733
Lloyd Piquede196652020-01-22 17:29:58 -0800734 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
735 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
736 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
737
738 injectOutputLayer(layer1);
739 injectOutputLayer(layer2);
740 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800741
742 CompositionRefreshArgs refreshArgs;
743 refreshArgs.updatingGeometryThisFrame = true;
744
745 mOutput->updateLayerStateFromFE(refreshArgs);
746}
747
748/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800749 * Output::updateAndWriteCompositionState()
750 */
751
Lloyd Piquede196652020-01-22 17:29:58 -0800752using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800753
754TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
755 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800756
757 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800758 mOutput->updateCompositionState(args);
759 mOutput->planComposition();
760 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800761}
762
Lloyd Piqueef63b612019-11-14 13:19:56 -0800763TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800764 InjectedLayer layer1;
765 InjectedLayer layer2;
766 InjectedLayer layer3;
767
Lloyd Piqueef63b612019-11-14 13:19:56 -0800768 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800769
Lloyd Piquede196652020-01-22 17:29:58 -0800770 injectOutputLayer(layer1);
771 injectOutputLayer(layer2);
772 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800773
774 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800775 mOutput->updateCompositionState(args);
776 mOutput->planComposition();
777 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800778}
779
780TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800781 InjectedLayer layer1;
782 InjectedLayer layer2;
783 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800784
Snild Dolkow9e217d62020-04-22 15:53:42 +0200785 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800786 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200787 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800788 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200789 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800790 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
791
792 injectOutputLayer(layer1);
793 injectOutputLayer(layer2);
794 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800795
796 mOutput->editState().isEnabled = true;
797
798 CompositionRefreshArgs args;
799 args.updatingGeometryThisFrame = false;
800 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200801 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800802 mOutput->updateCompositionState(args);
803 mOutput->planComposition();
804 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800805}
806
807TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800808 InjectedLayer layer1;
809 InjectedLayer layer2;
810 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811
Snild Dolkow9e217d62020-04-22 15:53:42 +0200812 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800813 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200814 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800815 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200816 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800817 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
818
819 injectOutputLayer(layer1);
820 injectOutputLayer(layer2);
821 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800822
823 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800824
825 CompositionRefreshArgs args;
826 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800828 mOutput->updateCompositionState(args);
829 mOutput->planComposition();
830 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800831}
832
833TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800834 InjectedLayer layer1;
835 InjectedLayer layer2;
836 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800837
Snild Dolkow9e217d62020-04-22 15:53:42 +0200838 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800839 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800841 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200842 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800843 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
844
845 injectOutputLayer(layer1);
846 injectOutputLayer(layer2);
847 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800848
849 mOutput->editState().isEnabled = true;
850
851 CompositionRefreshArgs args;
852 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800853 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800854 mOutput->updateCompositionState(args);
855 mOutput->planComposition();
856 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800857}
858
859/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800860 * Output::prepareFrame()
861 */
862
863struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800864 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800865 // Sets up the helper functions called by the function under test to use
866 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800867 MOCK_METHOD0(chooseCompositionStrategy, void());
868 };
869
870 OutputPrepareFrameTest() {
871 mOutput.setDisplayColorProfileForTest(
872 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
873 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
874 }
875
876 StrictMock<mock::CompositionEngine> mCompositionEngine;
877 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
878 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700879 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800880};
881
882TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
883 mOutput.editState().isEnabled = false;
884
885 mOutput.prepareFrame();
886}
887
888TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
889 mOutput.editState().isEnabled = true;
890 mOutput.editState().usesClientComposition = false;
891 mOutput.editState().usesDeviceComposition = true;
892
893 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
894 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
895
896 mOutput.prepareFrame();
897}
898
899// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
900// base chooseCompositionStrategy() is invoked.
901TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700902 mOutput->editState().isEnabled = true;
903 mOutput->editState().usesClientComposition = false;
904 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800905
906 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
907
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700908 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800909
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700910 EXPECT_TRUE(mOutput->getState().usesClientComposition);
911 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800912}
913
Lloyd Pique56eba802019-08-28 15:45:25 -0700914/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800915 * Output::prepare()
916 */
917
918struct OutputPrepareTest : public testing::Test {
919 struct OutputPartialMock : public OutputPartialMockBase {
920 // Sets up the helper functions called by the function under test to use
921 // mock implementations.
922 MOCK_METHOD2(rebuildLayerStacks,
923 void(const compositionengine::CompositionRefreshArgs&,
924 compositionengine::LayerFESet&));
925 };
926
927 StrictMock<OutputPartialMock> mOutput;
928 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800929 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800930};
931
932TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
933 InSequence seq;
934 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
935
936 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
937}
938
939/*
940 * Output::rebuildLayerStacks()
941 */
942
943struct OutputRebuildLayerStacksTest : public testing::Test {
944 struct OutputPartialMock : public OutputPartialMockBase {
945 // Sets up the helper functions called by the function under test to use
946 // mock implementations.
947 MOCK_METHOD2(collectVisibleLayers,
948 void(const compositionengine::CompositionRefreshArgs&,
949 compositionengine::Output::CoverageState&));
950 };
951
952 OutputRebuildLayerStacksTest() {
953 mOutput.mState.isEnabled = true;
954 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200955 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800956
957 mRefreshArgs.updatingOutputGeometryThisFrame = true;
958
959 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
960
961 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
962 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
963 }
964
965 void setTestCoverageValues(const CompositionRefreshArgs&,
966 compositionengine::Output::CoverageState& state) {
967 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
968 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
969 state.dirtyRegion = mCoverageDirtyRegionToSet;
970 }
971
972 static const ui::Transform kIdentityTransform;
973 static const ui::Transform kRotate90Transform;
974 static const Rect kOutputBounds;
975
976 StrictMock<OutputPartialMock> mOutput;
977 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800978 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800979 Region mCoverageAboveCoveredLayersToSet;
980 Region mCoverageAboveOpaqueLayersToSet;
981 Region mCoverageDirtyRegionToSet;
982};
983
984const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
985const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
986const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
987
988TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
989 mOutput.mState.isEnabled = false;
990
991 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
992}
993
994TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
995 mRefreshArgs.updatingOutputGeometryThisFrame = false;
996
997 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
998}
999
1000TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1001 mOutput.mState.transform = kIdentityTransform;
1002
1003 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1004
1005 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1006
1007 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1008}
1009
1010TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1011 mOutput.mState.transform = kIdentityTransform;
1012
1013 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1014
1015 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1016
1017 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1018}
1019
1020TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1021 mOutput.mState.transform = kRotate90Transform;
1022
1023 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1024
1025 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1026
1027 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1028}
1029
1030TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1031 mOutput.mState.transform = kRotate90Transform;
1032
1033 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1034
1035 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1036
1037 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1038}
1039
1040TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1041 mOutput.mState.transform = kIdentityTransform;
1042 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1043
1044 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1045
1046 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1047
1048 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1049}
1050
1051TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1052 mOutput.mState.transform = kRotate90Transform;
1053 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1054
1055 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1056
1057 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1058
1059 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1060}
1061
1062/*
1063 * Output::collectVisibleLayers()
1064 */
1065
Lloyd Pique1ef93222019-11-21 16:41:53 -08001066struct OutputCollectVisibleLayersTest : public testing::Test {
1067 struct OutputPartialMock : public OutputPartialMockBase {
1068 // Sets up the helper functions called by the function under test to use
1069 // mock implementations.
1070 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001071 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001072 compositionengine::Output::CoverageState&));
1073 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1074 MOCK_METHOD0(finalizePendingOutputLayers, void());
1075 };
1076
1077 struct Layer {
1078 Layer() {
1079 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1080 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1081 }
1082
1083 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001084 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001085 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001086 };
1087
1088 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001089 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001090 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1091 .WillRepeatedly(Return(&mLayer1.outputLayer));
1092 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1093 .WillRepeatedly(Return(&mLayer2.outputLayer));
1094 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1095 .WillRepeatedly(Return(&mLayer3.outputLayer));
1096
Lloyd Piquede196652020-01-22 17:29:58 -08001097 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1098 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1099 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001100 }
1101
1102 StrictMock<OutputPartialMock> mOutput;
1103 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001104 LayerFESet mGeomSnapshots;
1105 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001106 Layer mLayer1;
1107 Layer mLayer2;
1108 Layer mLayer3;
1109};
1110
1111TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1112 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001113 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001114
1115 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1116 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1117
1118 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1119}
1120
1121TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1122 // Enforce a call order sequence for this test.
1123 InSequence seq;
1124
1125 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001126 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1127 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1128 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001129
1130 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1131 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1132
1133 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1134
1135 // Ensure all output layers have been assigned a simple/flattened z-order.
1136 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1137 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1138 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1139}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001140
1141/*
1142 * Output::ensureOutputLayerIfVisible()
1143 */
1144
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001145struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1146 struct OutputPartialMock : public OutputPartialMockBase {
1147 // Sets up the helper functions called by the function under test to use
1148 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001149 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001150 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001151 MOCK_METHOD2(ensureOutputLayer,
1152 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153 };
1154
1155 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001156 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1157 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001158 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001159 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001160 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001161
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001162 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1163 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001164 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1165
Lloyd Piquede196652020-01-22 17:29:58 -08001166 mLayer.layerFEState.isVisible = true;
1167 mLayer.layerFEState.isOpaque = true;
1168 mLayer.layerFEState.contentDirty = true;
1169 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1170 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1171 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001172
Lloyd Piquede196652020-01-22 17:29:58 -08001173 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1174 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001175
Lloyd Piquede196652020-01-22 17:29:58 -08001176 mGeomSnapshots.insert(mLayer.layerFE);
1177 }
1178
1179 void ensureOutputLayerIfVisible() {
1180 sp<LayerFE> layerFE(mLayer.layerFE);
1181 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182 }
1183
1184 static const Region kEmptyRegion;
1185 static const Region kFullBoundsNoRotation;
1186 static const Region kRightHalfBoundsNoRotation;
1187 static const Region kLowerHalfBoundsNoRotation;
1188 static const Region kFullBounds90Rotation;
1189
1190 StrictMock<OutputPartialMock> mOutput;
1191 LayerFESet mGeomSnapshots;
1192 Output::CoverageState mCoverageState{mGeomSnapshots};
1193
Lloyd Piquede196652020-01-22 17:29:58 -08001194 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001195};
1196
1197const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1198const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1199 Region(Rect(0, 0, 100, 200));
1200const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1201 Region(Rect(0, 100, 100, 200));
1202const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1203 Region(Rect(50, 0, 100, 200));
1204const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1205 Region(Rect(0, 0, 200, 100));
1206
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001207TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001208 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1209 EXPECT_CALL(*mLayer.layerFE,
1210 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001211
1212 mGeomSnapshots.clear();
1213
Lloyd Piquede196652020-01-22 17:29:58 -08001214 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001215}
1216
1217TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1218 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001219 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220
Lloyd Piquede196652020-01-22 17:29:58 -08001221 ensureOutputLayerIfVisible();
1222}
1223
1224TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1225 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1226
1227 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228}
1229
1230TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001231 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232
Lloyd Piquede196652020-01-22 17:29:58 -08001233 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001234}
1235
1236TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001237 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001238
Lloyd Piquede196652020-01-22 17:29:58 -08001239 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240}
1241
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001242TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001243 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
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
1248TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1249 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001250 mLayer.layerFEState.isOpaque = true;
1251 mLayer.layerFEState.contentDirty = true;
1252 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253
1254 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001255 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1256 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257
Lloyd Piquede196652020-01-22 17:29:58 -08001258 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001259
1260 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1261 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1262 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1263
Lloyd Piquede196652020-01-22 17:29:58 -08001264 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1265 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1266 RegionEq(kFullBoundsNoRotation));
1267 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1268 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001269}
1270
1271TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1272 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001273 mLayer.layerFEState.isOpaque = true;
1274 mLayer.layerFEState.contentDirty = true;
1275 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001276
Lloyd Piquede196652020-01-22 17:29:58 -08001277 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1278 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001279
Lloyd Piquede196652020-01-22 17:29:58 -08001280 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281
1282 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1283 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1284 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1285
Lloyd Piquede196652020-01-22 17:29:58 -08001286 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1287 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1288 RegionEq(kFullBoundsNoRotation));
1289 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1290 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291}
1292
1293TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1294 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001295 mLayer.layerFEState.isOpaque = false;
1296 mLayer.layerFEState.contentDirty = true;
1297 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298
1299 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001300 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1301 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001302
Lloyd Piquede196652020-01-22 17:29:58 -08001303 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001304
1305 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1306 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1307 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1308
Lloyd Piquede196652020-01-22 17:29:58 -08001309 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1310 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001311 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001312 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1313 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314}
1315
1316TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1317 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001318 mLayer.layerFEState.isOpaque = false;
1319 mLayer.layerFEState.contentDirty = true;
1320 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001321
Lloyd Piquede196652020-01-22 17:29:58 -08001322 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1323 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001324
Lloyd Piquede196652020-01-22 17:29:58 -08001325 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001326
1327 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1328 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1329 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1330
Lloyd Piquede196652020-01-22 17:29:58 -08001331 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1332 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1335 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336}
1337
1338TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1339 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001340 mLayer.layerFEState.isOpaque = true;
1341 mLayer.layerFEState.contentDirty = false;
1342 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343
1344 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001345 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1346 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
Lloyd Piquede196652020-01-22 17:29:58 -08001348 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001349
1350 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1351 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1352 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1353
Lloyd Piquede196652020-01-22 17:29:58 -08001354 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1355 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1356 RegionEq(kFullBoundsNoRotation));
1357 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1358 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001359}
1360
1361TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1362 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001363 mLayer.layerFEState.isOpaque = true;
1364 mLayer.layerFEState.contentDirty = false;
1365 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366
Lloyd Piquede196652020-01-22 17:29:58 -08001367 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1368 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001369
Lloyd Piquede196652020-01-22 17:29:58 -08001370 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371
1372 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1373 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1374 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1377 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1378 RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1380 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381}
1382
1383TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1384 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001385 mLayer.layerFEState.isOpaque = true;
1386 mLayer.layerFEState.contentDirty = true;
1387 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1388 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1389 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1390 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001391
1392 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001393 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1394 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001395
Lloyd Piquede196652020-01-22 17:29:58 -08001396 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001397
1398 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1399 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1400 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1401
Lloyd Piquede196652020-01-22 17:29:58 -08001402 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1403 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1404 RegionEq(kFullBoundsNoRotation));
1405 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1406 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407}
1408
1409TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1410 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001411 mLayer.layerFEState.isOpaque = true;
1412 mLayer.layerFEState.contentDirty = true;
1413 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1414 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1415 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1416 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001417
Lloyd Piquede196652020-01-22 17:29:58 -08001418 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1419 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
Lloyd Piquede196652020-01-22 17:29:58 -08001421 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
1423 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1424 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1425 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1426
Lloyd Piquede196652020-01-22 17:29:58 -08001427 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1428 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1429 RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1431 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432}
1433
1434TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1435 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001436 mLayer.layerFEState.isOpaque = true;
1437 mLayer.layerFEState.contentDirty = true;
1438 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001439
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001440 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1442
1443 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001444 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1445 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
1449 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1450 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1452
Lloyd Piquede196652020-01-22 17:29:58 -08001453 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1455 RegionEq(kFullBoundsNoRotation));
1456 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1457 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458}
1459
1460TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1461 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001462 mLayer.layerFEState.isOpaque = true;
1463 mLayer.layerFEState.contentDirty = true;
1464 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001466 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1468
Lloyd Piquede196652020-01-22 17:29:58 -08001469 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1470 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471
Lloyd Piquede196652020-01-22 17:29:58 -08001472 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001473
1474 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1476 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1477
Lloyd Piquede196652020-01-22 17:29:58 -08001478 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1479 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1480 RegionEq(kFullBoundsNoRotation));
1481 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1482 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001483}
1484
1485TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1486 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1487 ui::Transform arbitraryTransform;
1488 arbitraryTransform.set(1, 1, -1, 1);
1489 arbitraryTransform.set(0, 100);
1490
Lloyd Piquede196652020-01-22 17:29:58 -08001491 mLayer.layerFEState.isOpaque = true;
1492 mLayer.layerFEState.contentDirty = true;
1493 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1494 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495
1496 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001497 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1498 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499
Lloyd Piquede196652020-01-22 17:29:58 -08001500 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501
1502 const Region kRegion = Region(Rect(0, 0, 300, 300));
1503 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1504
1505 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1506 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1507 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1508
Lloyd Piquede196652020-01-22 17:29:58 -08001509 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1510 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1511 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1512 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513}
1514
1515TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001516 mLayer.layerFEState.isOpaque = false;
1517 mLayer.layerFEState.contentDirty = true;
1518 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
1520 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1521 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1522 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1523
Lloyd Piquede196652020-01-22 17:29:58 -08001524 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1525 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528
1529 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1530 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1531 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1532 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1533 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1534 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1535
1536 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1537 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1538 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1539
Lloyd Piquede196652020-01-22 17:29:58 -08001540 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1541 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001543 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1544 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1545 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001547
Vishnu Naira483b4a2019-12-12 15:07:52 -08001548TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1549 ui::Transform translate;
1550 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001551 mLayer.layerFEState.geomLayerTransform = translate;
1552 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001553
1554 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1555 // half of the layer including the casting shadow is covered and opaque
1556 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1557 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1560 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001561
Lloyd Piquede196652020-01-22 17:29:58 -08001562 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001563
1564 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1565 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1566 // add starting opaque region to the opaque half of the casting layer bounds
1567 const Region kExpectedAboveOpaqueRegion =
1568 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1569 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1570 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1571 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1572 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1573 const Region kExpectedLayerShadowRegion =
1574 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1575
1576 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1577 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1578 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1579
Lloyd Piquede196652020-01-22 17:29:58 -08001580 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1581 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001582 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001583 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1584 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001585 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001587 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1588}
1589
1590TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1591 ui::Transform translate;
1592 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001593 mLayer.layerFEState.geomLayerTransform = translate;
1594 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001595
1596 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1597 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1598 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1599 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1600
Lloyd Piquede196652020-01-22 17:29:58 -08001601 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1602 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001603
Lloyd Piquede196652020-01-22 17:29:58 -08001604 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001605
1606 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1607 const Region kExpectedLayerShadowRegion =
1608 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1609
Lloyd Piquede196652020-01-22 17:29:58 -08001610 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1611 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001612 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1613}
1614
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001615TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001616 ui::Transform translate;
1617 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001618 mLayer.layerFEState.geomLayerTransform = translate;
1619 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001620
1621 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1622 // Casting layer and its shadows are covered by an opaque region
1623 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1624 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1625
Lloyd Piquede196652020-01-22 17:29:58 -08001626 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001627}
1628
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001629/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001630 * Output::present()
1631 */
1632
1633struct OutputPresentTest : public testing::Test {
1634 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001635 // Sets up the helper functions called by the function under test to use
1636 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001637 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001638 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001639 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001640 MOCK_METHOD0(planComposition, void());
1641 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001642 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1643 MOCK_METHOD0(beginFrame, void());
1644 MOCK_METHOD0(prepareFrame, void());
1645 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1646 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1647 MOCK_METHOD0(postFramebuffer, void());
1648 };
1649
1650 StrictMock<OutputPartialMock> mOutput;
1651};
1652
1653TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1654 CompositionRefreshArgs args;
1655
1656 InSequence seq;
1657 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001658 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1659 EXPECT_CALL(mOutput, planComposition());
1660 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001661 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1662 EXPECT_CALL(mOutput, beginFrame());
1663 EXPECT_CALL(mOutput, prepareFrame());
1664 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1665 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1666 EXPECT_CALL(mOutput, postFramebuffer());
1667
1668 mOutput.present(args);
1669}
1670
1671/*
1672 * Output::updateColorProfile()
1673 */
1674
Lloyd Pique17ca7422019-11-14 14:24:10 -08001675struct OutputUpdateColorProfileTest : public testing::Test {
1676 using TestType = OutputUpdateColorProfileTest;
1677
1678 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001679 // Sets up the helper functions called by the function under test to use
1680 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001681 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1682 };
1683
1684 struct Layer {
1685 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001686 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001687 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001688 }
1689
1690 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001691 StrictMock<mock::LayerFE> mLayerFE;
1692 LayerFECompositionState mLayerFEState;
1693 };
1694
1695 OutputUpdateColorProfileTest() {
1696 mOutput.setDisplayColorProfileForTest(
1697 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1698 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1699
1700 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1701 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1702 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1703 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1704 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1705 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1706 }
1707
1708 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1709 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1710 };
1711
1712 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1713 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1714 StrictMock<OutputPartialMock> mOutput;
1715
1716 Layer mLayer1;
1717 Layer mLayer2;
1718 Layer mLayer3;
1719
1720 CompositionRefreshArgs mRefreshArgs;
1721};
1722
1723// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1724// to make it easier to write unit tests.
1725
1726TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1727 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1728 // a simple default color profile without looking at anything else.
1729
Lloyd Pique0a456232020-01-16 17:51:13 -08001730 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001731 EXPECT_CALL(mOutput,
1732 setColorProfile(ColorProfileEq(
1733 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1734 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1735
1736 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1737 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1738
1739 mOutput.updateColorProfile(mRefreshArgs);
1740}
1741
1742struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1743 : public OutputUpdateColorProfileTest {
1744 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001745 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001746 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1747 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1748 }
1749
1750 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1751 : public CallOrderStateMachineHelper<
1752 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1753 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1754 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1755 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1756 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1757 _))
1758 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1759 SetArgPointee<4>(renderIntent)));
1760 EXPECT_CALL(getInstance()->mOutput,
1761 setColorProfile(
1762 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1763 ui::Dataspace::UNKNOWN})));
1764 return nextState<ExecuteState>();
1765 }
1766 };
1767
1768 // Call this member function to start using the mini-DSL defined above.
1769 [[nodiscard]] auto verify() {
1770 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1771 }
1772};
1773
1774TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1775 Native_Unknown_Colorimetric_Set) {
1776 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1777 ui::Dataspace::UNKNOWN,
1778 ui::RenderIntent::COLORIMETRIC)
1779 .execute();
1780}
1781
1782TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1783 DisplayP3_DisplayP3_Enhance_Set) {
1784 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1785 ui::Dataspace::DISPLAY_P3,
1786 ui::RenderIntent::ENHANCE)
1787 .execute();
1788}
1789
1790struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1791 : public OutputUpdateColorProfileTest {
1792 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001793 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001794 EXPECT_CALL(*mDisplayColorProfile,
1795 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1796 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1797 SetArgPointee<3>(ui::ColorMode::NATIVE),
1798 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1799 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1800 }
1801
1802 struct IfColorSpaceAgnosticDataspaceSetToState
1803 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1804 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1805 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1806 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1807 }
1808 };
1809
1810 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1811 : public CallOrderStateMachineHelper<
1812 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1813 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1814 ui::Dataspace dataspace) {
1815 EXPECT_CALL(getInstance()->mOutput,
1816 setColorProfile(ColorProfileEq(
1817 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1818 ui::RenderIntent::COLORIMETRIC, dataspace})));
1819 return nextState<ExecuteState>();
1820 }
1821 };
1822
1823 // Call this member function to start using the mini-DSL defined above.
1824 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1825};
1826
1827TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1828 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1829 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1830 .execute();
1831}
1832
1833TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1834 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1835 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1836 .execute();
1837}
1838
1839struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1840 : public OutputUpdateColorProfileTest {
1841 // Internally the implementation looks through the dataspaces of all the
1842 // visible layers. The topmost one that also has an actual dataspace
1843 // preference set is used to drive subsequent choices.
1844
1845 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1846 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1847 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1848
Lloyd Pique0a456232020-01-16 17:51:13 -08001849 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001850 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1851 }
1852
1853 struct IfTopLayerDataspaceState
1854 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1855 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1856 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1857 return nextState<AndIfMiddleLayerDataspaceState>();
1858 }
1859 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1860 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1861 }
1862 };
1863
1864 struct AndIfMiddleLayerDataspaceState
1865 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1866 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1867 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1868 return nextState<AndIfBottomLayerDataspaceState>();
1869 }
1870 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1871 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1872 }
1873 };
1874
1875 struct AndIfBottomLayerDataspaceState
1876 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1877 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1878 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1879 return nextState<ThenExpectBestColorModeCallUsesState>();
1880 }
1881 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1882 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1883 }
1884 };
1885
1886 struct ThenExpectBestColorModeCallUsesState
1887 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1888 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1889 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1890 getBestColorMode(dataspace, _, _, _, _));
1891 return nextState<ExecuteState>();
1892 }
1893 };
1894
1895 // Call this member function to start using the mini-DSL defined above.
1896 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1897};
1898
1899TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1900 noStrongLayerPrefenceUses_V0_SRGB) {
1901 // If none of the layers indicate a preference, then V0_SRGB is the
1902 // preferred choice (subject to additional checks).
1903 verify().ifTopLayerHasNoPreference()
1904 .andIfMiddleLayerHasNoPreference()
1905 .andIfBottomLayerHasNoPreference()
1906 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1907 .execute();
1908}
1909
1910TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1911 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1912 // If only the topmost layer has a preference, then that is what is chosen.
1913 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1914 .andIfMiddleLayerHasNoPreference()
1915 .andIfBottomLayerHasNoPreference()
1916 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1917 .execute();
1918}
1919
1920TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1921 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1922 // If only the middle layer has a preference, that that is what is chosen.
1923 verify().ifTopLayerHasNoPreference()
1924 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1925 .andIfBottomLayerHasNoPreference()
1926 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1927 .execute();
1928}
1929
1930TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1931 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1932 // If only the middle layer has a preference, that that is what is chosen.
1933 verify().ifTopLayerHasNoPreference()
1934 .andIfMiddleLayerHasNoPreference()
1935 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1936 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1937 .execute();
1938}
1939
1940TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1941 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1942 // If multiple layers have a preference, the topmost value is what is used.
1943 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1944 .andIfMiddleLayerHasNoPreference()
1945 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1946 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1947 .execute();
1948}
1949
1950TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1951 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1952 // If multiple layers have a preference, the topmost value is what is used.
1953 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1954 .andIfMiddleLayerHasNoPreference()
1955 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1956 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1957 .execute();
1958}
1959
1960struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1961 : public OutputUpdateColorProfileTest {
1962 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1963 // values, it overrides the layer dataspace choice.
1964
1965 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1966 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1967 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1968
1969 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1970
Lloyd Pique0a456232020-01-16 17:51:13 -08001971 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001972 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1973 }
1974
1975 struct IfForceOutputColorModeState
1976 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1977 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1978 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1979 return nextState<ThenExpectBestColorModeCallUsesState>();
1980 }
1981 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1982 };
1983
1984 struct ThenExpectBestColorModeCallUsesState
1985 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1986 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1987 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1988 getBestColorMode(dataspace, _, _, _, _));
1989 return nextState<ExecuteState>();
1990 }
1991 };
1992
1993 // Call this member function to start using the mini-DSL defined above.
1994 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1995};
1996
1997TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1998 // By default the layer state is used to set the preferred dataspace
1999 verify().ifNoOverride()
2000 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2001 .execute();
2002}
2003
2004TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2005 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2006 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2007 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2008 .execute();
2009}
2010
2011TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2012 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2013 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2014 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2015 .execute();
2016}
2017
2018// HDR output requires all layers to be compatible with the chosen HDR
2019// dataspace, along with there being proper support.
2020struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2021 OutputUpdateColorProfileTest_Hdr() {
2022 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2023 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002024 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002025 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2026 }
2027
2028 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2029 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2030 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2031 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2032
2033 struct IfTopLayerDataspaceState
2034 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2035 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2036 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2037 return nextState<AndTopLayerCompositionTypeState>();
2038 }
2039 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2040 };
2041
2042 struct AndTopLayerCompositionTypeState
2043 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2044 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2045 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2046 return nextState<AndIfBottomLayerDataspaceState>();
2047 }
2048 };
2049
2050 struct AndIfBottomLayerDataspaceState
2051 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2052 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2053 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2054 return nextState<AndBottomLayerCompositionTypeState>();
2055 }
2056 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2057 return andIfBottomLayerIs(kNonHdrDataspace);
2058 }
2059 };
2060
2061 struct AndBottomLayerCompositionTypeState
2062 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2063 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2064 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2065 return nextState<AndIfHasLegacySupportState>();
2066 }
2067 };
2068
2069 struct AndIfHasLegacySupportState
2070 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2071 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2072 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2073 .WillOnce(Return(legacySupport));
2074 return nextState<ThenExpectBestColorModeCallUsesState>();
2075 }
2076 };
2077
2078 struct ThenExpectBestColorModeCallUsesState
2079 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2080 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2081 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2082 getBestColorMode(dataspace, _, _, _, _));
2083 return nextState<ExecuteState>();
2084 }
2085 };
2086
2087 // Call this member function to start using the mini-DSL defined above.
2088 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2089};
2090
2091TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2092 // If all layers use BT2020_PQ, and there are no other special conditions,
2093 // BT2020_PQ is used.
2094 verify().ifTopLayerIs(BT2020_PQ)
2095 .andTopLayerIsREComposed(false)
2096 .andIfBottomLayerIs(BT2020_PQ)
2097 .andBottomLayerIsREComposed(false)
2098 .andIfLegacySupportFor(BT2020_PQ, false)
2099 .thenExpectBestColorModeCallUses(BT2020_PQ)
2100 .execute();
2101}
2102
2103TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2104 // BT2020_PQ is not used if there is only legacy support for it.
2105 verify().ifTopLayerIs(BT2020_PQ)
2106 .andTopLayerIsREComposed(false)
2107 .andIfBottomLayerIs(BT2020_PQ)
2108 .andBottomLayerIsREComposed(false)
2109 .andIfLegacySupportFor(BT2020_PQ, true)
2110 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2111 .execute();
2112}
2113
2114TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2115 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2116 verify().ifTopLayerIs(BT2020_PQ)
2117 .andTopLayerIsREComposed(false)
2118 .andIfBottomLayerIs(BT2020_PQ)
2119 .andBottomLayerIsREComposed(true)
2120 .andIfLegacySupportFor(BT2020_PQ, false)
2121 .thenExpectBestColorModeCallUses(BT2020_PQ)
2122 .execute();
2123}
2124
2125TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2126 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2127 verify().ifTopLayerIs(BT2020_PQ)
2128 .andTopLayerIsREComposed(true)
2129 .andIfBottomLayerIs(BT2020_PQ)
2130 .andBottomLayerIsREComposed(false)
2131 .andIfLegacySupportFor(BT2020_PQ, false)
2132 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2133 .execute();
2134}
2135
2136TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2137 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2138 // are no other special conditions.
2139 verify().ifTopLayerIs(BT2020_PQ)
2140 .andTopLayerIsREComposed(false)
2141 .andIfBottomLayerIs(BT2020_HLG)
2142 .andBottomLayerIsREComposed(false)
2143 .andIfLegacySupportFor(BT2020_PQ, false)
2144 .thenExpectBestColorModeCallUses(BT2020_PQ)
2145 .execute();
2146}
2147
2148TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2149 // BT2020_PQ is not used if there is only legacy support for it.
2150 verify().ifTopLayerIs(BT2020_PQ)
2151 .andTopLayerIsREComposed(false)
2152 .andIfBottomLayerIs(BT2020_HLG)
2153 .andBottomLayerIsREComposed(false)
2154 .andIfLegacySupportFor(BT2020_PQ, true)
2155 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2156 .execute();
2157}
2158
2159TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2160 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2161 verify().ifTopLayerIs(BT2020_PQ)
2162 .andTopLayerIsREComposed(false)
2163 .andIfBottomLayerIs(BT2020_HLG)
2164 .andBottomLayerIsREComposed(true)
2165 .andIfLegacySupportFor(BT2020_PQ, false)
2166 .thenExpectBestColorModeCallUses(BT2020_PQ)
2167 .execute();
2168}
2169
2170TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2171 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2172 verify().ifTopLayerIs(BT2020_PQ)
2173 .andTopLayerIsREComposed(true)
2174 .andIfBottomLayerIs(BT2020_HLG)
2175 .andBottomLayerIsREComposed(false)
2176 .andIfLegacySupportFor(BT2020_PQ, false)
2177 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2178 .execute();
2179}
2180
2181TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2182 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2183 // used if there are no other special conditions.
2184 verify().ifTopLayerIs(BT2020_HLG)
2185 .andTopLayerIsREComposed(false)
2186 .andIfBottomLayerIs(BT2020_PQ)
2187 .andBottomLayerIsREComposed(false)
2188 .andIfLegacySupportFor(BT2020_PQ, false)
2189 .thenExpectBestColorModeCallUses(BT2020_PQ)
2190 .execute();
2191}
2192
2193TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2194 // BT2020_PQ is not used if there is only legacy support for it.
2195 verify().ifTopLayerIs(BT2020_HLG)
2196 .andTopLayerIsREComposed(false)
2197 .andIfBottomLayerIs(BT2020_PQ)
2198 .andBottomLayerIsREComposed(false)
2199 .andIfLegacySupportFor(BT2020_PQ, true)
2200 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2201 .execute();
2202}
2203
2204TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2205 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2206 verify().ifTopLayerIs(BT2020_HLG)
2207 .andTopLayerIsREComposed(false)
2208 .andIfBottomLayerIs(BT2020_PQ)
2209 .andBottomLayerIsREComposed(true)
2210 .andIfLegacySupportFor(BT2020_PQ, false)
2211 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2212 .execute();
2213}
2214
2215TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2216 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2217 verify().ifTopLayerIs(BT2020_HLG)
2218 .andTopLayerIsREComposed(true)
2219 .andIfBottomLayerIs(BT2020_PQ)
2220 .andBottomLayerIsREComposed(false)
2221 .andIfLegacySupportFor(BT2020_PQ, false)
2222 .thenExpectBestColorModeCallUses(BT2020_PQ)
2223 .execute();
2224}
2225
2226TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2227 // If all layers use HLG then HLG is used if there are no other special
2228 // conditions.
2229 verify().ifTopLayerIs(BT2020_HLG)
2230 .andTopLayerIsREComposed(false)
2231 .andIfBottomLayerIs(BT2020_HLG)
2232 .andBottomLayerIsREComposed(false)
2233 .andIfLegacySupportFor(BT2020_HLG, false)
2234 .thenExpectBestColorModeCallUses(BT2020_HLG)
2235 .execute();
2236}
2237
2238TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2239 // BT2020_HLG is not used if there is legacy support for it.
2240 verify().ifTopLayerIs(BT2020_HLG)
2241 .andTopLayerIsREComposed(false)
2242 .andIfBottomLayerIs(BT2020_HLG)
2243 .andBottomLayerIsREComposed(false)
2244 .andIfLegacySupportFor(BT2020_HLG, true)
2245 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2246 .execute();
2247}
2248
2249TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2250 // BT2020_HLG is used even if the bottom layer is client composed.
2251 verify().ifTopLayerIs(BT2020_HLG)
2252 .andTopLayerIsREComposed(false)
2253 .andIfBottomLayerIs(BT2020_HLG)
2254 .andBottomLayerIsREComposed(true)
2255 .andIfLegacySupportFor(BT2020_HLG, false)
2256 .thenExpectBestColorModeCallUses(BT2020_HLG)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2261 // BT2020_HLG is used even if the top layer is client composed.
2262 verify().ifTopLayerIs(BT2020_HLG)
2263 .andTopLayerIsREComposed(true)
2264 .andIfBottomLayerIs(BT2020_HLG)
2265 .andBottomLayerIsREComposed(false)
2266 .andIfLegacySupportFor(BT2020_HLG, false)
2267 .thenExpectBestColorModeCallUses(BT2020_HLG)
2268 .execute();
2269}
2270
2271TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2272 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2273 verify().ifTopLayerIs(BT2020_PQ)
2274 .andTopLayerIsREComposed(false)
2275 .andIfBottomLayerIsNotHdr()
2276 .andBottomLayerIsREComposed(false)
2277 .andIfLegacySupportFor(BT2020_PQ, false)
2278 .thenExpectBestColorModeCallUses(BT2020_PQ)
2279 .execute();
2280}
2281
2282TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2283 // If all layers use HLG then HLG is used if there are no other special
2284 // conditions.
2285 verify().ifTopLayerIs(BT2020_HLG)
2286 .andTopLayerIsREComposed(false)
2287 .andIfBottomLayerIsNotHdr()
2288 .andBottomLayerIsREComposed(true)
2289 .andIfLegacySupportFor(BT2020_HLG, false)
2290 .thenExpectBestColorModeCallUses(BT2020_HLG)
2291 .execute();
2292}
2293
2294struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2295 : public OutputUpdateColorProfileTest {
2296 // The various values for CompositionRefreshArgs::outputColorSetting affect
2297 // the chosen renderIntent, along with whether the preferred dataspace is an
2298 // HDR dataspace or not.
2299
2300 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2301 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2302 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2303 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002304 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002305 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2306 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2307 .WillRepeatedly(Return(false));
2308 }
2309
2310 // The tests here involve enough state and GMock setup that using a mini-DSL
2311 // makes the tests much more readable, and allows the test to focus more on
2312 // the intent than on some of the details.
2313
2314 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2315 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2316
2317 struct IfDataspaceChosenState
2318 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2319 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2320 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2321 return nextState<AndOutputColorSettingState>();
2322 }
2323 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2324 return ifDataspaceChosenIs(kNonHdrDataspace);
2325 }
2326 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2327 };
2328
2329 struct AndOutputColorSettingState
2330 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2331 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2332 getInstance()->mRefreshArgs.outputColorSetting = setting;
2333 return nextState<ThenExpectBestColorModeCallUsesState>();
2334 }
2335 };
2336
2337 struct ThenExpectBestColorModeCallUsesState
2338 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2339 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2340 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2341 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2342 _, _));
2343 return nextState<ExecuteState>();
2344 }
2345 };
2346
2347 // Tests call one of these two helper member functions to start using the
2348 // mini-DSL defined above.
2349 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2350};
2351
2352TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2353 Managed_NonHdr_Prefers_Colorimetric) {
2354 verify().ifDataspaceChosenIsNonHdr()
2355 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2356 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2361 Managed_Hdr_Prefers_ToneMapColorimetric) {
2362 verify().ifDataspaceChosenIsHdr()
2363 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2364 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2365 .execute();
2366}
2367
2368TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2369 verify().ifDataspaceChosenIsNonHdr()
2370 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2371 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2372 .execute();
2373}
2374
2375TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2376 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2377 verify().ifDataspaceChosenIsHdr()
2378 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2379 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2380 .execute();
2381}
2382
2383TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2384 verify().ifDataspaceChosenIsNonHdr()
2385 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2386 .thenExpectBestColorModeCallUses(
2387 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2388 .execute();
2389}
2390
2391TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2392 verify().ifDataspaceChosenIsHdr()
2393 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2394 .thenExpectBestColorModeCallUses(
2395 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2396 .execute();
2397}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002398
2399/*
2400 * Output::beginFrame()
2401 */
2402
Lloyd Piquee5965952019-11-18 16:16:32 -08002403struct OutputBeginFrameTest : public ::testing::Test {
2404 using TestType = OutputBeginFrameTest;
2405
2406 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002407 // Sets up the helper functions called by the function under test to use
2408 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002409 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2410 };
2411
2412 OutputBeginFrameTest() {
2413 mOutput.setDisplayColorProfileForTest(
2414 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2415 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2416 }
2417
2418 struct IfGetDirtyRegionExpectationState
2419 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2420 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2421 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2422 .WillOnce(Return(dirtyRegion));
2423 return nextState<AndIfGetOutputLayerCountExpectationState>();
2424 }
2425 };
2426
2427 struct AndIfGetOutputLayerCountExpectationState
2428 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2429 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2430 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2431 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2432 }
2433 };
2434
2435 struct AndIfLastCompositionHadVisibleLayersState
2436 : public CallOrderStateMachineHelper<TestType,
2437 AndIfLastCompositionHadVisibleLayersState> {
2438 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2439 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2440 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2441 }
2442 };
2443
2444 struct ThenExpectRenderSurfaceBeginFrameCallState
2445 : public CallOrderStateMachineHelper<TestType,
2446 ThenExpectRenderSurfaceBeginFrameCallState> {
2447 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2448 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2449 return nextState<ExecuteState>();
2450 }
2451 };
2452
2453 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2454 [[nodiscard]] auto execute() {
2455 getInstance()->mOutput.beginFrame();
2456 return nextState<CheckPostconditionHadVisibleLayersState>();
2457 }
2458 };
2459
2460 struct CheckPostconditionHadVisibleLayersState
2461 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2462 void checkPostconditionHadVisibleLayers(bool expected) {
2463 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2464 }
2465 };
2466
2467 // Tests call one of these two helper member functions to start using the
2468 // mini-DSL defined above.
2469 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2470
2471 static const Region kEmptyRegion;
2472 static const Region kNotEmptyRegion;
2473
2474 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2475 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2476 StrictMock<OutputPartialMock> mOutput;
2477};
2478
2479const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2480const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2481
2482TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2483 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2484 .andIfGetOutputLayerCountReturns(1u)
2485 .andIfLastCompositionHadVisibleLayersIs(true)
2486 .thenExpectRenderSurfaceBeginFrameCall(true)
2487 .execute()
2488 .checkPostconditionHadVisibleLayers(true);
2489}
2490
2491TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2492 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2493 .andIfGetOutputLayerCountReturns(0u)
2494 .andIfLastCompositionHadVisibleLayersIs(true)
2495 .thenExpectRenderSurfaceBeginFrameCall(true)
2496 .execute()
2497 .checkPostconditionHadVisibleLayers(false);
2498}
2499
2500TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2501 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2502 .andIfGetOutputLayerCountReturns(1u)
2503 .andIfLastCompositionHadVisibleLayersIs(false)
2504 .thenExpectRenderSurfaceBeginFrameCall(true)
2505 .execute()
2506 .checkPostconditionHadVisibleLayers(true);
2507}
2508
2509TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2510 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2511 .andIfGetOutputLayerCountReturns(0u)
2512 .andIfLastCompositionHadVisibleLayersIs(false)
2513 .thenExpectRenderSurfaceBeginFrameCall(false)
2514 .execute()
2515 .checkPostconditionHadVisibleLayers(false);
2516}
2517
2518TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2519 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2520 .andIfGetOutputLayerCountReturns(1u)
2521 .andIfLastCompositionHadVisibleLayersIs(true)
2522 .thenExpectRenderSurfaceBeginFrameCall(false)
2523 .execute()
2524 .checkPostconditionHadVisibleLayers(true);
2525}
2526
2527TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2528 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2529 .andIfGetOutputLayerCountReturns(0u)
2530 .andIfLastCompositionHadVisibleLayersIs(true)
2531 .thenExpectRenderSurfaceBeginFrameCall(false)
2532 .execute()
2533 .checkPostconditionHadVisibleLayers(true);
2534}
2535
2536TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2537 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2538 .andIfGetOutputLayerCountReturns(1u)
2539 .andIfLastCompositionHadVisibleLayersIs(false)
2540 .thenExpectRenderSurfaceBeginFrameCall(false)
2541 .execute()
2542 .checkPostconditionHadVisibleLayers(false);
2543}
2544
2545TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2546 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2547 .andIfGetOutputLayerCountReturns(0u)
2548 .andIfLastCompositionHadVisibleLayersIs(false)
2549 .thenExpectRenderSurfaceBeginFrameCall(false)
2550 .execute()
2551 .checkPostconditionHadVisibleLayers(false);
2552}
2553
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002554/*
2555 * Output::devOptRepaintFlash()
2556 */
2557
Lloyd Piquedb462d82019-11-19 17:58:46 -08002558struct OutputDevOptRepaintFlashTest : public testing::Test {
2559 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002560 // Sets up the helper functions called by the function under test to use
2561 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002562 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002563 MOCK_METHOD2(composeSurfaces,
2564 std::optional<base::unique_fd>(
2565 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002566 MOCK_METHOD0(postFramebuffer, void());
2567 MOCK_METHOD0(prepareFrame, void());
2568 };
2569
2570 OutputDevOptRepaintFlashTest() {
2571 mOutput.setDisplayColorProfileForTest(
2572 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2573 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2574 }
2575
2576 static const Region kEmptyRegion;
2577 static const Region kNotEmptyRegion;
2578
2579 StrictMock<OutputPartialMock> mOutput;
2580 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2581 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2582 CompositionRefreshArgs mRefreshArgs;
2583};
2584
2585const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2586const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2587
2588TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2589 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2590 mRefreshArgs.repaintEverything = true;
2591 mOutput.mState.isEnabled = true;
2592
2593 mOutput.devOptRepaintFlash(mRefreshArgs);
2594}
2595
2596TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2597 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2598 mRefreshArgs.repaintEverything = true;
2599 mOutput.mState.isEnabled = false;
2600
2601 InSequence seq;
2602 EXPECT_CALL(mOutput, postFramebuffer());
2603 EXPECT_CALL(mOutput, prepareFrame());
2604
2605 mOutput.devOptRepaintFlash(mRefreshArgs);
2606}
2607
2608TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2609 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2610 mRefreshArgs.repaintEverything = true;
2611 mOutput.mState.isEnabled = true;
2612
2613 InSequence seq;
2614 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2615 EXPECT_CALL(mOutput, postFramebuffer());
2616 EXPECT_CALL(mOutput, prepareFrame());
2617
2618 mOutput.devOptRepaintFlash(mRefreshArgs);
2619}
2620
2621TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2622 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2623 mRefreshArgs.repaintEverything = false;
2624 mOutput.mState.isEnabled = true;
2625
2626 InSequence seq;
2627 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002628 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002629 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2630 EXPECT_CALL(mOutput, postFramebuffer());
2631 EXPECT_CALL(mOutput, prepareFrame());
2632
2633 mOutput.devOptRepaintFlash(mRefreshArgs);
2634}
2635
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002636/*
2637 * Output::finishFrame()
2638 */
2639
Lloyd Pique03561a62019-11-19 18:34:52 -08002640struct OutputFinishFrameTest : public testing::Test {
2641 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002642 // Sets up the helper functions called by the function under test to use
2643 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002644 MOCK_METHOD2(composeSurfaces,
2645 std::optional<base::unique_fd>(
2646 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002647 MOCK_METHOD0(postFramebuffer, void());
2648 };
2649
2650 OutputFinishFrameTest() {
2651 mOutput.setDisplayColorProfileForTest(
2652 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2653 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2654 }
2655
2656 StrictMock<OutputPartialMock> mOutput;
2657 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2658 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2659 CompositionRefreshArgs mRefreshArgs;
2660};
2661
2662TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2663 mOutput.mState.isEnabled = false;
2664
2665 mOutput.finishFrame(mRefreshArgs);
2666}
2667
2668TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2669 mOutput.mState.isEnabled = true;
2670
2671 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002672 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002673
2674 mOutput.finishFrame(mRefreshArgs);
2675}
2676
2677TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2678 mOutput.mState.isEnabled = true;
2679
2680 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002681 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002682 .WillOnce(Return(ByMove(base::unique_fd())));
2683 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2684
2685 mOutput.finishFrame(mRefreshArgs);
2686}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002687
2688/*
2689 * Output::postFramebuffer()
2690 */
2691
Lloyd Pique07178e32019-11-19 19:15:26 -08002692struct OutputPostFramebufferTest : public testing::Test {
2693 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002694 // Sets up the helper functions called by the function under test to use
2695 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002696 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2697 };
2698
2699 struct Layer {
2700 Layer() {
2701 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2702 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2703 }
2704
2705 StrictMock<mock::OutputLayer> outputLayer;
2706 StrictMock<mock::LayerFE> layerFE;
2707 StrictMock<HWC2::mock::Layer> hwc2Layer;
2708 };
2709
2710 OutputPostFramebufferTest() {
2711 mOutput.setDisplayColorProfileForTest(
2712 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2713 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2714
2715 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2716 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2717 .WillRepeatedly(Return(&mLayer1.outputLayer));
2718 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2719 .WillRepeatedly(Return(&mLayer2.outputLayer));
2720 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2721 .WillRepeatedly(Return(&mLayer3.outputLayer));
2722 }
2723
2724 StrictMock<OutputPartialMock> mOutput;
2725 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2726 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2727
2728 Layer mLayer1;
2729 Layer mLayer2;
2730 Layer mLayer3;
2731};
2732
2733TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2734 mOutput.mState.isEnabled = false;
2735
2736 mOutput.postFramebuffer();
2737}
2738
2739TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2740 mOutput.mState.isEnabled = true;
2741
2742 compositionengine::Output::FrameFences frameFences;
2743
2744 // This should happen even if there are no output layers.
2745 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2746
2747 // For this test in particular we want to make sure the call expectations
2748 // setup below are satisfied in the specific order.
2749 InSequence seq;
2750
2751 EXPECT_CALL(*mRenderSurface, flip());
2752 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2753 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2754
2755 mOutput.postFramebuffer();
2756}
2757
2758TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2759 // Simulate getting release fences from each layer, and ensure they are passed to the
2760 // front-end layer interface for each layer correctly.
2761
2762 mOutput.mState.isEnabled = true;
2763
2764 // Create three unique fence instances
2765 sp<Fence> layer1Fence = new Fence();
2766 sp<Fence> layer2Fence = new Fence();
2767 sp<Fence> layer3Fence = new Fence();
2768
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002769 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002770 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2771 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2772 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2773
2774 EXPECT_CALL(*mRenderSurface, flip());
2775 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2776 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2777
2778 // Compare the pointers values of each fence to make sure the correct ones
2779 // are passed. This happens to work with the current implementation, but
2780 // would not survive certain calls like Fence::merge() which would return a
2781 // new instance.
2782 EXPECT_CALL(mLayer1.layerFE,
2783 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2784 EXPECT_CALL(mLayer2.layerFE,
2785 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2786 EXPECT_CALL(mLayer3.layerFE,
2787 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2788
2789 mOutput.postFramebuffer();
2790}
2791
2792TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2793 mOutput.mState.isEnabled = true;
2794 mOutput.mState.usesClientComposition = true;
2795
2796 sp<Fence> clientTargetAcquireFence = new Fence();
2797 sp<Fence> layer1Fence = new Fence();
2798 sp<Fence> layer2Fence = new Fence();
2799 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002800 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002801 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2802 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2803 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2804 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2805
2806 EXPECT_CALL(*mRenderSurface, flip());
2807 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2808 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2809
2810 // Fence::merge is called, and since none of the fences are actually valid,
2811 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2812 // This is the best we can do without creating a real kernel fence object.
2813 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2814 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2815 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2816
2817 mOutput.postFramebuffer();
2818}
2819
2820TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2821 mOutput.mState.isEnabled = true;
2822 mOutput.mState.usesClientComposition = true;
2823
2824 // This should happen even if there are no (current) output layers.
2825 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2826
2827 // Load up the released layers with some mock instances
2828 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2829 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2830 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2831 Output::ReleasedLayers layers;
2832 layers.push_back(releasedLayer1);
2833 layers.push_back(releasedLayer2);
2834 layers.push_back(releasedLayer3);
2835 mOutput.setReleasedLayers(std::move(layers));
2836
2837 // Set up a fake present fence
2838 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002839 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002840 frameFences.presentFence = presentFence;
2841
2842 EXPECT_CALL(*mRenderSurface, flip());
2843 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2844 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2845
2846 // Each released layer should be given the presentFence.
2847 EXPECT_CALL(*releasedLayer1,
2848 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2849 EXPECT_CALL(*releasedLayer2,
2850 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2851 EXPECT_CALL(*releasedLayer3,
2852 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2853
2854 mOutput.postFramebuffer();
2855
2856 // After the call the list of released layers should have been cleared.
2857 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2858}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002859
2860/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002861 * Output::composeSurfaces()
2862 */
2863
2864struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002865 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002866
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002867 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002868 // Sets up the helper functions called by the function under test to use
2869 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002870 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002871 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002872 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002873 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002874 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002875 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2876 };
2877
2878 OutputComposeSurfacesTest() {
2879 mOutput.setDisplayColorProfileForTest(
2880 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2881 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002882 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002883
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002884 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2885 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002886 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002887 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002888 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002889 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002890 mOutput.mState.dataspace = kDefaultOutputDataspace;
2891 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2892 mOutput.mState.isSecure = false;
2893 mOutput.mState.needsFiltering = false;
2894 mOutput.mState.usesClientComposition = true;
2895 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002896 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002897 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002898
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002899 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002900 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002901 EXPECT_CALL(mCompositionEngine, getTimeStats())
2902 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002903 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2904 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002905 }
2906
Lloyd Pique6818fa52019-12-03 12:32:13 -08002907 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2908 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002909 getInstance()->mReadyFence =
2910 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002911 return nextState<FenceCheckState>();
2912 }
2913 };
2914
2915 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2916 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2917
2918 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2919 };
2920
2921 // Call this member function to start using the mini-DSL defined above.
2922 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2923
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002924 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2925 static constexpr uint32_t kDefaultOutputOrientationFlags =
2926 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002927 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2928 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2929 static constexpr float kDefaultMaxLuminance = 0.9f;
2930 static constexpr float kDefaultAvgLuminance = 0.7f;
2931 static constexpr float kDefaultMinLuminance = 0.1f;
2932
2933 static const Rect kDefaultOutputFrame;
2934 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002935 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002936 static const mat4 kDefaultColorTransformMat;
2937
2938 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002939 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002940 static const HdrCapabilities kHdrCapabilities;
2941
Lloyd Pique56eba802019-08-28 15:45:25 -07002942 StrictMock<mock::CompositionEngine> mCompositionEngine;
2943 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002944 // TODO: make this is a proper mock.
2945 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002946 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2947 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002948 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002949 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002950
2951 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002952};
2953
2954const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2955const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002956const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002957const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002958const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002959const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2960const HdrCapabilities OutputComposeSurfacesTest::
2961 kHdrCapabilities{{},
2962 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2963 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2964 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002965
Lloyd Piquea76ce462020-01-14 13:06:37 -08002966TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002967 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002968
Lloyd Piquee9eff972020-05-05 12:36:44 -07002969 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002970 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002971
Lloyd Piquea76ce462020-01-14 13:06:37 -08002972 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2973
Lloyd Pique6818fa52019-12-03 12:32:13 -08002974 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002975}
2976
Lloyd Piquee9eff972020-05-05 12:36:44 -07002977TEST_F(OutputComposeSurfacesTest,
2978 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2979 mOutput.mState.usesClientComposition = false;
2980 mOutput.mState.flipClientTarget = true;
2981
Lloyd Pique6818fa52019-12-03 12:32:13 -08002982 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002983 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002984
2985 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2986 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2987
2988 verify().execute().expectAFenceWasReturned();
2989}
2990
2991TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2992 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002993 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002994
2995 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2996
2997 verify().execute().expectNoFenceWasReturned();
2998}
2999
3000TEST_F(OutputComposeSurfacesTest,
3001 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3002 mOutput.mState.usesClientComposition = false;
3003 mOutput.mState.flipClientTarget = true;
3004
3005 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003006 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003007
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003009
Lloyd Pique6818fa52019-12-03 12:32:13 -08003010 verify().execute().expectNoFenceWasReturned();
3011}
Lloyd Pique56eba802019-08-28 15:45:25 -07003012
Lloyd Pique6818fa52019-12-03 12:32:13 -08003013TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3014 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3015 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3016 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003017 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003018 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003019 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003020 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3021 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003022
Lloyd Pique6818fa52019-12-03 12:32:13 -08003023 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003024 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003025 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003026
Lloyd Pique6818fa52019-12-03 12:32:13 -08003027 verify().execute().expectAFenceWasReturned();
3028}
Lloyd Pique56eba802019-08-28 15:45:25 -07003029
Lloyd Pique6818fa52019-12-03 12:32:13 -08003030TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003031 LayerFE::LayerSettings r1;
3032 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003033
3034 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3035 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3036
3037 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3038 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3039 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003040 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003041 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003042 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3044 .WillRepeatedly(
3045 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003046 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003047 clientCompositionLayers.emplace_back(r2);
3048 }));
3049
3050 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003051 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3052 .WillRepeatedly(Return(NO_ERROR));
3053
3054 verify().execute().expectAFenceWasReturned();
3055}
3056
3057TEST_F(OutputComposeSurfacesTest,
3058 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3059 LayerFE::LayerSettings r1;
3060 LayerFE::LayerSettings r2;
3061
3062 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3063 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3064 const constexpr uint32_t kInternalLayerStack = 1234;
3065 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3066
3067 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3068 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3069 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3070 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3071 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3072 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3073 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3074 .WillRepeatedly(
3075 Invoke([&](const Region&,
3076 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3077 clientCompositionLayers.emplace_back(r2);
3078 }));
3079
3080 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003081 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003082 .WillRepeatedly(Return(NO_ERROR));
3083
3084 verify().execute().expectAFenceWasReturned();
3085}
3086
Vishnu Nair9b079a22020-01-21 14:36:08 -08003087TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3088 mOutput.cacheClientCompositionRequests(0);
3089 LayerFE::LayerSettings r1;
3090 LayerFE::LayerSettings r2;
3091
3092 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3093 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3094
3095 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3096 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3097 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003098 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003099 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3100 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3101 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3102 .WillRepeatedly(Return());
3103
3104 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003105 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003106 .Times(2)
3107 .WillOnce(Return(NO_ERROR));
3108
3109 verify().execute().expectAFenceWasReturned();
3110 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3111
3112 verify().execute().expectAFenceWasReturned();
3113 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3114}
3115
3116TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3117 mOutput.cacheClientCompositionRequests(3);
3118 LayerFE::LayerSettings r1;
3119 LayerFE::LayerSettings r2;
3120
3121 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3122 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3123
3124 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3125 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3126 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003127 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003128 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3129 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3130 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3131 .WillRepeatedly(Return());
3132
3133 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003134 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003135 .WillOnce(Return(NO_ERROR));
3136 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3137
3138 verify().execute().expectAFenceWasReturned();
3139 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3140
3141 // We do not expect another call to draw layers.
3142 verify().execute().expectAFenceWasReturned();
3143 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3144}
3145
3146TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3147 LayerFE::LayerSettings r1;
3148 LayerFE::LayerSettings r2;
3149
3150 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3151 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3152
3153 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3154 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3155 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003156 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003157 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3158 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3159 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3160 .WillRepeatedly(Return());
3161
3162 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3163 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3164 .WillOnce(Return(mOutputBuffer))
3165 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003166 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003167 .WillRepeatedly(Return(NO_ERROR));
3168
3169 verify().execute().expectAFenceWasReturned();
3170 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3171
3172 verify().execute().expectAFenceWasReturned();
3173 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3174}
3175
3176TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3177 LayerFE::LayerSettings r1;
3178 LayerFE::LayerSettings r2;
3179 LayerFE::LayerSettings r3;
3180
3181 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3182 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3183 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3184
3185 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3186 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3187 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003188 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003189 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3190 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3191 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3192 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3193 .WillRepeatedly(Return());
3194
3195 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003196 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003197 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003198 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003199 .WillOnce(Return(NO_ERROR));
3200
3201 verify().execute().expectAFenceWasReturned();
3202 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3203
3204 verify().execute().expectAFenceWasReturned();
3205 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3206}
3207
Lloyd Pique6818fa52019-12-03 12:32:13 -08003208struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3209 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3210 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003211 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003212 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003213 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003214 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3215 .WillRepeatedly(Return());
3216 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3217 }
3218
3219 struct MixedCompositionState
3220 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3221 auto ifMixedCompositionIs(bool used) {
3222 getInstance()->mOutput.mState.usesDeviceComposition = used;
3223 return nextState<OutputUsesHdrState>();
3224 }
3225 };
3226
3227 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3228 auto andIfUsesHdr(bool used) {
3229 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3230 .WillOnce(Return(used));
3231 return nextState<SkipColorTransformState>();
3232 }
3233 };
3234
3235 struct SkipColorTransformState
3236 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3237 auto andIfSkipColorTransform(bool skip) {
3238 // May be called zero or one times.
3239 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3240 .WillRepeatedly(Return(skip));
3241 return nextState<ExpectDisplaySettingsState>();
3242 }
3243 };
3244
3245 struct ExpectDisplaySettingsState
3246 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3247 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003248 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003249 .WillOnce(Return(NO_ERROR));
3250 return nextState<ExecuteState>();
3251 }
3252 };
3253
3254 // Call this member function to start using the mini-DSL defined above.
3255 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3256};
3257
3258TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3259 verify().ifMixedCompositionIs(true)
3260 .andIfUsesHdr(true)
3261 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003262 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003263 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003264 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003265 .execute()
3266 .expectAFenceWasReturned();
3267}
3268
3269TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3270 verify().ifMixedCompositionIs(true)
3271 .andIfUsesHdr(false)
3272 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003273 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003274 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003275 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003276 .execute()
3277 .expectAFenceWasReturned();
3278}
3279
3280TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3281 verify().ifMixedCompositionIs(false)
3282 .andIfUsesHdr(true)
3283 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003284 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003285 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003286 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003287 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003288 .execute()
3289 .expectAFenceWasReturned();
3290}
3291
3292TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3293 verify().ifMixedCompositionIs(false)
3294 .andIfUsesHdr(false)
3295 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003296 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003297 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003298 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003299 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003300 .execute()
3301 .expectAFenceWasReturned();
3302}
3303
3304TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3305 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3306 verify().ifMixedCompositionIs(false)
3307 .andIfUsesHdr(true)
3308 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003309 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003310 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003311 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003312 .execute()
3313 .expectAFenceWasReturned();
3314}
3315
3316struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3317 struct Layer {
3318 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003319 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3320 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 }
3322
3323 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003324 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003325 LayerFECompositionState mLayerFEState;
3326 };
3327
3328 OutputComposeSurfacesTest_HandlesProtectedContent() {
3329 mLayer1.mLayerFEState.hasProtectedContent = false;
3330 mLayer2.mLayerFEState.hasProtectedContent = false;
3331
3332 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3333 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3334 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3335 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3336 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3337
3338 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3339
3340 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3341
3342 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003343 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003344 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3345 .WillRepeatedly(Return());
3346 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003347 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003348 .WillRepeatedly(Return(NO_ERROR));
3349 }
3350
3351 Layer mLayer1;
3352 Layer mLayer2;
3353};
3354
3355TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3356 mOutput.mState.isSecure = false;
3357 mLayer2.mLayerFEState.hasProtectedContent = true;
3358 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003359 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3360 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003361
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003362 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003363}
3364
3365TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3366 mOutput.mState.isSecure = true;
3367 mLayer2.mLayerFEState.hasProtectedContent = true;
3368 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3369
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003370 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003371}
3372
3373TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3374 mOutput.mState.isSecure = true;
3375 mLayer2.mLayerFEState.hasProtectedContent = false;
3376 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3377 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3378 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3379 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3380 EXPECT_CALL(*mRenderSurface, setProtected(false));
3381
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003382 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383}
3384
3385TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3386 mOutput.mState.isSecure = true;
3387 mLayer2.mLayerFEState.hasProtectedContent = true;
3388 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3389
3390 // For this test, we also check the call order of key functions.
3391 InSequence seq;
3392
3393 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3394 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3395 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3396 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3397 EXPECT_CALL(*mRenderSurface, setProtected(true));
3398 // Must happen after setting the protected content state.
3399 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003400 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003401
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003402 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003403}
3404
3405TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3406 mOutput.mState.isSecure = true;
3407 mLayer2.mLayerFEState.hasProtectedContent = true;
3408 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3409 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3410 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3411
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003412 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003413}
3414
3415TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3416 mOutput.mState.isSecure = true;
3417 mLayer2.mLayerFEState.hasProtectedContent = true;
3418 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3419 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3420 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3421 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3422
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003423 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003424}
3425
3426TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3427 mOutput.mState.isSecure = true;
3428 mLayer2.mLayerFEState.hasProtectedContent = true;
3429 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3430 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3431 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3432 EXPECT_CALL(*mRenderSurface, setProtected(true));
3433
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003434 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003435}
3436
3437TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3438 mOutput.mState.isSecure = true;
3439 mLayer2.mLayerFEState.hasProtectedContent = true;
3440 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3441 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3442 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3443 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3444
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003445 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003446}
3447
3448struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3449 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3450 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3451 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3452 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003453 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003454 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3455 .WillRepeatedly(Return());
3456 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3457 }
3458};
3459
3460TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3461 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3462
3463 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003464 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465
3466 // For this test, we also check the call order of key functions.
3467 InSequence seq;
3468
3469 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003470 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003471
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003472 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3473}
3474
3475struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3476 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3477 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3478 mLayer.layerFEState.backgroundBlurRadius = 10;
3479 mOutput.editState().isEnabled = true;
3480
Snild Dolkow9e217d62020-04-22 15:53:42 +02003481 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003482 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3483 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003485 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003486 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3487 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3488 .WillRepeatedly(Return(&mLayer.outputLayer));
3489 }
3490
3491 NonInjectedLayer mLayer;
3492 compositionengine::CompositionRefreshArgs mRefreshArgs;
3493};
3494
3495TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3496 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003497 mOutput.updateCompositionState(mRefreshArgs);
3498 mOutput.planComposition();
3499 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003500
3501 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3502 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3503}
3504
3505TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3506 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003507 mOutput.updateCompositionState(mRefreshArgs);
3508 mOutput.planComposition();
3509 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003510
3511 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3512 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003513}
3514
3515/*
3516 * Output::generateClientCompositionRequests()
3517 */
3518
3519struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003520 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003521 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003522 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003523 bool supportsProtectedContent, Region& clearRegion,
3524 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003525 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003526 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003527 }
3528 };
3529
Lloyd Piquea4863342019-12-04 18:45:02 -08003530 struct Layer {
3531 Layer() {
3532 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3533 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003534 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003535 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003536 }
3537
3538 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003539 StrictMock<mock::LayerFE> mLayerFE;
3540 LayerFECompositionState mLayerFEState;
3541 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003542 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003543 };
3544
Lloyd Pique56eba802019-08-28 15:45:25 -07003545 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003546 mOutput.mState.needsFiltering = false;
3547
Lloyd Pique56eba802019-08-28 15:45:25 -07003548 mOutput.setDisplayColorProfileForTest(
3549 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3550 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3551 }
3552
Lloyd Pique56eba802019-08-28 15:45:25 -07003553 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3554 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003555 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003556};
3557
Lloyd Piquea4863342019-12-04 18:45:02 -08003558struct GenerateClientCompositionRequestsTest_ThreeLayers
3559 : public GenerateClientCompositionRequestsTest {
3560 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003561 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3562 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3563 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003564 mOutput.mState.transform =
3565 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3566 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003567 mOutput.mState.needsFiltering = false;
3568 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003569
Lloyd Piquea4863342019-12-04 18:45:02 -08003570 for (size_t i = 0; i < mLayers.size(); i++) {
3571 mLayers[i].mOutputLayerState.clearClientTarget = false;
3572 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3573 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003574 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003575 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003576 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3577 mLayers[i].mLayerSettings.alpha = 1.0f;
3578 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003579
Lloyd Piquea4863342019-12-04 18:45:02 -08003580 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3581 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3582 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3583 .WillRepeatedly(Return(true));
3584 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3585 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003586
Lloyd Piquea4863342019-12-04 18:45:02 -08003587 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3588 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003589
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003590 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003591 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003592
Lloyd Piquea4863342019-12-04 18:45:02 -08003593 static const Rect kDisplayFrame;
3594 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003595 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003596
Lloyd Piquea4863342019-12-04 18:45:02 -08003597 std::array<Layer, 3> mLayers;
3598};
Lloyd Pique56eba802019-08-28 15:45:25 -07003599
Lloyd Piquea4863342019-12-04 18:45:02 -08003600const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3601const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003602const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3603 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003604
Lloyd Piquea4863342019-12-04 18:45:02 -08003605TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3606 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3607 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3608 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003609
Lloyd Piquea4863342019-12-04 18:45:02 -08003610 Region accumClearRegion(Rect(10, 11, 12, 13));
3611 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3612 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003613 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003614 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003615}
3616
Lloyd Piquea4863342019-12-04 18:45:02 -08003617TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3618 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3619 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3620 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3621
3622 Region accumClearRegion(Rect(10, 11, 12, 13));
3623 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3624 accumClearRegion, kDisplayDataspace);
3625 EXPECT_EQ(0u, requests.size());
3626 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3627}
3628
3629TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003630 LayerFE::LayerSettings mShadowSettings;
3631 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003632
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003633 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3634 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3635 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3636 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3637 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3638 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3639 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003640
3641 Region accumClearRegion(Rect(10, 11, 12, 13));
3642 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3643 accumClearRegion, kDisplayDataspace);
3644 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003645 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3646 EXPECT_EQ(mShadowSettings, requests[1]);
3647 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003648
3649 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3650
3651 // Check that a timestamp was set for the layers that generated requests
3652 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3653 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3654 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3655}
3656
3657TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3658 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3659 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3660 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3661 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3662
3663 mLayers[0].mOutputLayerState.clearClientTarget = false;
3664 mLayers[1].mOutputLayerState.clearClientTarget = false;
3665 mLayers[2].mOutputLayerState.clearClientTarget = false;
3666
3667 mLayers[0].mLayerFEState.isOpaque = true;
3668 mLayers[1].mLayerFEState.isOpaque = true;
3669 mLayers[2].mLayerFEState.isOpaque = true;
3670
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003671 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3672 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003673
3674 Region accumClearRegion(Rect(10, 11, 12, 13));
3675 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3676 accumClearRegion, kDisplayDataspace);
3677 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003678 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003679
3680 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3681}
3682
3683TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3684 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3685 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3686 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3687 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3688
3689 mLayers[0].mOutputLayerState.clearClientTarget = true;
3690 mLayers[1].mOutputLayerState.clearClientTarget = true;
3691 mLayers[2].mOutputLayerState.clearClientTarget = true;
3692
3693 mLayers[0].mLayerFEState.isOpaque = false;
3694 mLayers[1].mLayerFEState.isOpaque = false;
3695 mLayers[2].mLayerFEState.isOpaque = false;
3696
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003697 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3698 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003699
3700 Region accumClearRegion(Rect(10, 11, 12, 13));
3701 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3702 accumClearRegion, kDisplayDataspace);
3703 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003704 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003705
3706 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3707}
3708
3709TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003710 // If client composition is performed with some layers set to use device
3711 // composition, device layers after the first layer (device or client) will
3712 // clear the frame buffer if they are opaque and if that layer has a flag
3713 // set to do so. The first layer is skipped as the frame buffer is already
3714 // expected to be clear.
3715
Lloyd Piquea4863342019-12-04 18:45:02 -08003716 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3717 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3718 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003719
Lloyd Piquea4863342019-12-04 18:45:02 -08003720 mLayers[0].mOutputLayerState.clearClientTarget = true;
3721 mLayers[1].mOutputLayerState.clearClientTarget = true;
3722 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003723
Lloyd Piquea4863342019-12-04 18:45:02 -08003724 mLayers[0].mLayerFEState.isOpaque = true;
3725 mLayers[1].mLayerFEState.isOpaque = true;
3726 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003727 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003728 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003729
3730 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3731 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003732 false, /* needs filtering */
3733 false, /* secure */
3734 false, /* supports protected content */
3735 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003736 kDisplayViewport,
3737 kDisplayDataspace,
3738 false /* realContentIsVisible */,
3739 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003740 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003741 };
3742 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3743 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003744 false, /* needs filtering */
3745 false, /* secure */
3746 false, /* supports protected content */
3747 accumClearRegion,
3748 kDisplayViewport,
3749 kDisplayDataspace,
3750 true /* realContentIsVisible */,
3751 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003752 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003753 };
3754
3755 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3756 mBlackoutSettings.source.buffer.buffer = nullptr;
3757 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3758 mBlackoutSettings.alpha = 0.f;
3759 mBlackoutSettings.disableBlending = true;
3760
3761 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3762 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3763 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3764 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3765
Lloyd Piquea4863342019-12-04 18:45:02 -08003766 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3767 accumClearRegion, kDisplayDataspace);
3768 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003769
Lloyd Piquea4863342019-12-04 18:45:02 -08003770 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003771 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003772
Vishnu Nair9b079a22020-01-21 14:36:08 -08003773 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003774
Lloyd Piquea4863342019-12-04 18:45:02 -08003775 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3776}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003777
Lloyd Piquea4863342019-12-04 18:45:02 -08003778TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3779 clippedVisibleRegionUsedToGenerateRequest) {
3780 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3781 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3782 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003783
Lloyd Piquea4863342019-12-04 18:45:02 -08003784 Region accumClearRegion(Rect(10, 11, 12, 13));
3785
3786 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3787 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003788 false, /* needs filtering */
3789 false, /* secure */
3790 false, /* supports protected content */
3791 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003792 kDisplayViewport,
3793 kDisplayDataspace,
3794 true /* realContentIsVisible */,
3795 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003796 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003797 };
3798 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3799 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003800 false, /* needs filtering */
3801 false, /* secure */
3802 false, /* supports protected content */
3803 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003804 kDisplayViewport,
3805 kDisplayDataspace,
3806 true /* realContentIsVisible */,
3807 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003808 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003809 };
3810 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3811 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003812 false, /* needs filtering */
3813 false, /* secure */
3814 false, /* supports protected content */
3815 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003816 kDisplayViewport,
3817 kDisplayDataspace,
3818 true /* realContentIsVisible */,
3819 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003820 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003821 };
3822
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003823 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3824 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3825 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3826 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3827 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3828 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003829
3830 static_cast<void>(
3831 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3832 accumClearRegion, kDisplayDataspace));
3833}
3834
3835TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3836 perLayerNeedsFilteringUsedToGenerateRequests) {
3837 mOutput.mState.needsFiltering = false;
3838 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3839
3840 Region accumClearRegion(Rect(10, 11, 12, 13));
3841
3842 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3843 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003844 true, /* needs filtering */
3845 false, /* secure */
3846 false, /* supports protected content */
3847 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003848 kDisplayViewport,
3849 kDisplayDataspace,
3850 true /* realContentIsVisible */,
3851 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003852 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003853 };
3854 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3855 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003856 false, /* needs filtering */
3857 false, /* secure */
3858 false, /* supports protected content */
3859 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003860 kDisplayViewport,
3861 kDisplayDataspace,
3862 true /* realContentIsVisible */,
3863 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003864 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003865 };
3866 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3867 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003868 false, /* needs filtering */
3869 false, /* secure */
3870 false, /* supports protected content */
3871 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003872 kDisplayViewport,
3873 kDisplayDataspace,
3874 true /* realContentIsVisible */,
3875 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003876 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003877 };
3878
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003879 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3880 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3881 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3882 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3883 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3884 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003885
3886 static_cast<void>(
3887 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3888 accumClearRegion, kDisplayDataspace));
3889}
3890
3891TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3892 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3893 mOutput.mState.needsFiltering = true;
3894 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3895
3896 Region accumClearRegion(Rect(10, 11, 12, 13));
3897
3898 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3899 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003900 true, /* needs filtering */
3901 false, /* secure */
3902 false, /* supports protected content */
3903 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003904 kDisplayViewport,
3905 kDisplayDataspace,
3906 true /* realContentIsVisible */,
3907 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003908 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003909
Lloyd Piquea4863342019-12-04 18:45:02 -08003910 };
3911 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3912 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003913 true, /* needs filtering */
3914 false, /* secure */
3915 false, /* supports protected content */
3916 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003917 kDisplayViewport,
3918 kDisplayDataspace,
3919 true /* realContentIsVisible */,
3920 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003921 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003922 };
3923 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3924 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003925 true, /* needs filtering */
3926 false, /* secure */
3927 false, /* supports protected content */
3928 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003929 kDisplayViewport,
3930 kDisplayDataspace,
3931 true /* realContentIsVisible */,
3932 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003933 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003934 };
3935
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003936 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3937 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3938 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3939 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3940 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3941 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003942
3943 static_cast<void>(
3944 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3945 accumClearRegion, kDisplayDataspace));
3946}
3947
3948TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3949 wholeOutputSecurityUsedToGenerateRequests) {
3950 mOutput.mState.isSecure = true;
3951
3952 Region accumClearRegion(Rect(10, 11, 12, 13));
3953
3954 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3955 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 false, /* needs filtering */
3957 true, /* secure */
3958 false, /* supports protected content */
3959 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003960 kDisplayViewport,
3961 kDisplayDataspace,
3962 true /* realContentIsVisible */,
3963 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003964 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003965 };
3966 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3967 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003968 false, /* needs filtering */
3969 true, /* secure */
3970 false, /* supports protected content */
3971 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003972 kDisplayViewport,
3973 kDisplayDataspace,
3974 true /* realContentIsVisible */,
3975 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003976 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 };
3978 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3979 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003980 false, /* needs filtering */
3981 true, /* secure */
3982 false, /* supports protected content */
3983 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003984 kDisplayViewport,
3985 kDisplayDataspace,
3986 true /* realContentIsVisible */,
3987 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003988 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003989 };
3990
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3992 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3993 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3994 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3995 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3996 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003997
3998 static_cast<void>(
3999 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4000 accumClearRegion, kDisplayDataspace));
4001}
4002
4003TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4004 protectedContentSupportUsedToGenerateRequests) {
4005 Region accumClearRegion(Rect(10, 11, 12, 13));
4006
4007 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4008 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004009 false, /* needs filtering */
4010 false, /* secure */
4011 true, /* supports protected content */
4012 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004013 kDisplayViewport,
4014 kDisplayDataspace,
4015 true /* realContentIsVisible */,
4016 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004017 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004018 };
4019 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4020 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004021 false, /* needs filtering */
4022 false, /* secure */
4023 true, /* supports protected content */
4024 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004025 kDisplayViewport,
4026 kDisplayDataspace,
4027 true /* realContentIsVisible */,
4028 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004029 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 };
4031 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4032 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004033 false, /* needs filtering */
4034 false, /* secure */
4035 true, /* supports protected content */
4036 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004037 kDisplayViewport,
4038 kDisplayDataspace,
4039 true /* realContentIsVisible */,
4040 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004041 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004042 };
4043
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004044 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
4045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4046 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
4047 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4048 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
4049 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004050
4051 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4052 accumClearRegion,
4053 kDisplayDataspace));
4054}
4055
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004056TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004057 InjectedLayer layer1;
4058 InjectedLayer layer2;
4059 InjectedLayer layer3;
4060
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004061 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004062 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004063 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004064 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004065 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004066 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004067 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004068
Lloyd Piquede196652020-01-22 17:29:58 -08004069 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004070
Lloyd Piquede196652020-01-22 17:29:58 -08004071 injectOutputLayer(layer1);
4072 injectOutputLayer(layer2);
4073 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004074
4075 mOutput->editState().isEnabled = true;
4076
4077 CompositionRefreshArgs args;
4078 args.updatingGeometryThisFrame = false;
4079 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004080 mOutput->updateCompositionState(args);
4081 mOutput->planComposition();
4082 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004083}
4084
Lucas Dupinc3800b82020-10-02 16:24:48 -07004085TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4086 InjectedLayer layer1;
4087 InjectedLayer layer2;
4088 InjectedLayer layer3;
4089
4090 // Layer requesting blur, or below, should request client composition.
4091 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4092 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
4093 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4094 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
4095 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4096 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
4097
4098 BlurRegion region;
4099 layer2.layerFEState.blurRegions.push_back(region);
4100
4101 injectOutputLayer(layer1);
4102 injectOutputLayer(layer2);
4103 injectOutputLayer(layer3);
4104
4105 mOutput->editState().isEnabled = true;
4106
4107 CompositionRefreshArgs args;
4108 args.updatingGeometryThisFrame = false;
4109 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004110 mOutput->updateCompositionState(args);
4111 mOutput->planComposition();
4112 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004113}
4114
Lloyd Piquea4863342019-12-04 18:45:02 -08004115TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4116 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4117 // one layer on the left covering the left side of the output, and one layer
4118 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004119
4120 const Rect kPortraitFrame(0, 0, 1000, 2000);
4121 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004122 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004123 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004124 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004125
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004126 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4127 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4128 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004129 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4130 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004131 mOutput.mState.needsFiltering = false;
4132 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004133
Lloyd Piquea4863342019-12-04 18:45:02 -08004134 Layer leftLayer;
4135 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004136
Lloyd Piquea4863342019-12-04 18:45:02 -08004137 leftLayer.mOutputLayerState.clearClientTarget = false;
4138 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4139 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004140 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004141
Lloyd Piquea4863342019-12-04 18:45:02 -08004142 rightLayer.mOutputLayerState.clearClientTarget = false;
4143 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4144 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004145 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004146
4147 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4148 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4149 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4150 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4151 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4152
4153 Region accumClearRegion(Rect(10, 11, 12, 13));
4154
4155 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4156 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004157 false, /* needs filtering */
4158 true, /* secure */
4159 true, /* supports protected content */
4160 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004161 kPortraitViewport,
4162 kOutputDataspace,
4163 true /* realContentIsVisible */,
4164 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004165 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004166 };
4167
4168 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4169 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004170 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4171 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004172
4173 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4174 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004175 false, /* needs filtering */
4176 true, /* secure */
4177 true, /* supports protected content */
4178 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004179 kPortraitViewport,
4180 kOutputDataspace,
4181 true /* realContentIsVisible */,
4182 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004183 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004184 };
4185
4186 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4187 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004188 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4189 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004190
4191 constexpr bool supportsProtectedContent = true;
4192 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4193 accumClearRegion, kOutputDataspace);
4194 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004195 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4196 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004197}
4198
Vishnu Naira483b4a2019-12-12 15:07:52 -08004199TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4200 shadowRegionOnlyVisibleSkipsContentComposition) {
4201 const Rect kContentWithShadow(40, 40, 70, 90);
4202 const Rect kContent(50, 50, 60, 80);
4203 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4204 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4205
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004206 Region accumClearRegion(Rect(10, 11, 12, 13));
4207 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4208 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004209 false, /* needs filtering */
4210 false, /* secure */
4211 false, /* supports protected content */
4212 accumClearRegion,
4213 kDisplayViewport,
4214 kDisplayDataspace,
4215 false /* realContentIsVisible */,
4216 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004217 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004218 };
4219
Vishnu Nair9b079a22020-01-21 14:36:08 -08004220 LayerFE::LayerSettings mShadowSettings;
4221 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004222
4223 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4224 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4225
4226 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4227 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004228 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4229 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004230
Vishnu Naira483b4a2019-12-12 15:07:52 -08004231 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4232 accumClearRegion, kDisplayDataspace);
4233 ASSERT_EQ(1u, requests.size());
4234
Vishnu Nair9b079a22020-01-21 14:36:08 -08004235 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004236}
4237
4238TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4239 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4240 const Rect kContentWithShadow(40, 40, 70, 90);
4241 const Rect kContent(50, 50, 60, 80);
4242 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4243 const Region kPartialContentWithPartialShadowRegion =
4244 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4245
Vishnu Nair9b079a22020-01-21 14:36:08 -08004246 LayerFE::LayerSettings mShadowSettings;
4247 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004248
4249 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4250 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4251
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004252 Region accumClearRegion(Rect(10, 11, 12, 13));
4253 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4254 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004255 false, /* needs filtering */
4256 false, /* secure */
4257 false, /* supports protected content */
4258 accumClearRegion,
4259 kDisplayViewport,
4260 kDisplayDataspace,
4261 true /* realContentIsVisible */,
4262 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004263 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004264 };
4265
Vishnu Naira483b4a2019-12-12 15:07:52 -08004266 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4267 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004268 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4269 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4270 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004271
Vishnu Naira483b4a2019-12-12 15:07:52 -08004272 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4273 accumClearRegion, kDisplayDataspace);
4274 ASSERT_EQ(2u, requests.size());
4275
Vishnu Nair9b079a22020-01-21 14:36:08 -08004276 EXPECT_EQ(mShadowSettings, requests[0]);
4277 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004278}
4279
Lloyd Pique32cbe282018-10-19 13:09:22 -07004280} // namespace
4281} // namespace android::compositionengine