blob: 8dcace6b6c406f070c4e71b7cf84e8c46bc39492 [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);
Dan Stoza47437bb2021-01-15 16:21:07 -0800894 if (mOutput.plannerEnabled()) {
895 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
896 }
Lloyd Pique66d68602019-02-13 14:23:31 -0800897 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
898
899 mOutput.prepareFrame();
900}
901
902// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
903// base chooseCompositionStrategy() is invoked.
904TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700905 mOutput->editState().isEnabled = true;
906 mOutput->editState().usesClientComposition = false;
907 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800908
909 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
910
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700911 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800912
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700913 EXPECT_TRUE(mOutput->getState().usesClientComposition);
914 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800915}
916
Lloyd Pique56eba802019-08-28 15:45:25 -0700917/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800918 * Output::prepare()
919 */
920
921struct OutputPrepareTest : public testing::Test {
922 struct OutputPartialMock : public OutputPartialMockBase {
923 // Sets up the helper functions called by the function under test to use
924 // mock implementations.
925 MOCK_METHOD2(rebuildLayerStacks,
926 void(const compositionengine::CompositionRefreshArgs&,
927 compositionengine::LayerFESet&));
928 };
929
930 StrictMock<OutputPartialMock> mOutput;
931 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800932 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800933};
934
935TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
936 InSequence seq;
937 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
938
939 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
940}
941
942/*
943 * Output::rebuildLayerStacks()
944 */
945
946struct OutputRebuildLayerStacksTest : public testing::Test {
947 struct OutputPartialMock : public OutputPartialMockBase {
948 // Sets up the helper functions called by the function under test to use
949 // mock implementations.
950 MOCK_METHOD2(collectVisibleLayers,
951 void(const compositionengine::CompositionRefreshArgs&,
952 compositionengine::Output::CoverageState&));
953 };
954
955 OutputRebuildLayerStacksTest() {
956 mOutput.mState.isEnabled = true;
957 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200958 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800959
960 mRefreshArgs.updatingOutputGeometryThisFrame = true;
961
962 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
963
964 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
965 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
966 }
967
968 void setTestCoverageValues(const CompositionRefreshArgs&,
969 compositionengine::Output::CoverageState& state) {
970 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
971 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
972 state.dirtyRegion = mCoverageDirtyRegionToSet;
973 }
974
975 static const ui::Transform kIdentityTransform;
976 static const ui::Transform kRotate90Transform;
977 static const Rect kOutputBounds;
978
979 StrictMock<OutputPartialMock> mOutput;
980 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800981 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800982 Region mCoverageAboveCoveredLayersToSet;
983 Region mCoverageAboveOpaqueLayersToSet;
984 Region mCoverageDirtyRegionToSet;
985};
986
987const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
988const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
989const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
990
991TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
992 mOutput.mState.isEnabled = false;
993
994 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
995}
996
997TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
998 mRefreshArgs.updatingOutputGeometryThisFrame = false;
999
1000 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1001}
1002
1003TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1004 mOutput.mState.transform = kIdentityTransform;
1005
1006 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1007
1008 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1009
1010 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1011}
1012
1013TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1014 mOutput.mState.transform = kIdentityTransform;
1015
1016 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1017
1018 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1019
1020 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1021}
1022
1023TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1024 mOutput.mState.transform = kRotate90Transform;
1025
1026 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1027
1028 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1029
1030 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1031}
1032
1033TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1034 mOutput.mState.transform = kRotate90Transform;
1035
1036 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1037
1038 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1039
1040 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1041}
1042
1043TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1044 mOutput.mState.transform = kIdentityTransform;
1045 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1046
1047 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1048
1049 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1050
1051 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1052}
1053
1054TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1055 mOutput.mState.transform = kRotate90Transform;
1056 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1057
1058 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1059
1060 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1061
1062 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1063}
1064
1065/*
1066 * Output::collectVisibleLayers()
1067 */
1068
Lloyd Pique1ef93222019-11-21 16:41:53 -08001069struct OutputCollectVisibleLayersTest : public testing::Test {
1070 struct OutputPartialMock : public OutputPartialMockBase {
1071 // Sets up the helper functions called by the function under test to use
1072 // mock implementations.
1073 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001074 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001075 compositionengine::Output::CoverageState&));
1076 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1077 MOCK_METHOD0(finalizePendingOutputLayers, void());
1078 };
1079
1080 struct Layer {
1081 Layer() {
1082 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1083 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1084 }
1085
1086 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001087 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001088 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001089 };
1090
1091 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001092 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001093 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1094 .WillRepeatedly(Return(&mLayer1.outputLayer));
1095 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1096 .WillRepeatedly(Return(&mLayer2.outputLayer));
1097 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1098 .WillRepeatedly(Return(&mLayer3.outputLayer));
1099
Lloyd Piquede196652020-01-22 17:29:58 -08001100 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1101 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1102 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001103 }
1104
1105 StrictMock<OutputPartialMock> mOutput;
1106 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001107 LayerFESet mGeomSnapshots;
1108 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001109 Layer mLayer1;
1110 Layer mLayer2;
1111 Layer mLayer3;
1112};
1113
1114TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1115 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001116 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001117
1118 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1119 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1120
1121 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1122}
1123
1124TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1125 // Enforce a call order sequence for this test.
1126 InSequence seq;
1127
1128 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001129 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1130 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1131 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001132
1133 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1134 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1135
1136 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1137
1138 // Ensure all output layers have been assigned a simple/flattened z-order.
1139 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1140 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1141 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1142}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001143
1144/*
1145 * Output::ensureOutputLayerIfVisible()
1146 */
1147
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001148struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1149 struct OutputPartialMock : public OutputPartialMockBase {
1150 // Sets up the helper functions called by the function under test to use
1151 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001152 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001154 MOCK_METHOD2(ensureOutputLayer,
1155 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001156 };
1157
1158 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001159 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1160 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001161 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001162 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001163 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001164
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001165 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1166 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001167 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1168
Lloyd Piquede196652020-01-22 17:29:58 -08001169 mLayer.layerFEState.isVisible = true;
1170 mLayer.layerFEState.isOpaque = true;
1171 mLayer.layerFEState.contentDirty = true;
1172 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1173 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1174 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001175
Lloyd Piquede196652020-01-22 17:29:58 -08001176 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1177 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001178
Lloyd Piquede196652020-01-22 17:29:58 -08001179 mGeomSnapshots.insert(mLayer.layerFE);
1180 }
1181
1182 void ensureOutputLayerIfVisible() {
1183 sp<LayerFE> layerFE(mLayer.layerFE);
1184 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001185 }
1186
1187 static const Region kEmptyRegion;
1188 static const Region kFullBoundsNoRotation;
1189 static const Region kRightHalfBoundsNoRotation;
1190 static const Region kLowerHalfBoundsNoRotation;
1191 static const Region kFullBounds90Rotation;
1192
1193 StrictMock<OutputPartialMock> mOutput;
1194 LayerFESet mGeomSnapshots;
1195 Output::CoverageState mCoverageState{mGeomSnapshots};
1196
Lloyd Piquede196652020-01-22 17:29:58 -08001197 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001198};
1199
1200const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1201const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1202 Region(Rect(0, 0, 100, 200));
1203const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1204 Region(Rect(0, 100, 100, 200));
1205const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1206 Region(Rect(50, 0, 100, 200));
1207const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1208 Region(Rect(0, 0, 200, 100));
1209
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001210TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001211 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1212 EXPECT_CALL(*mLayer.layerFE,
1213 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001214
1215 mGeomSnapshots.clear();
1216
Lloyd Piquede196652020-01-22 17:29:58 -08001217 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001218}
1219
1220TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1221 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001222 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001223
Lloyd Piquede196652020-01-22 17:29:58 -08001224 ensureOutputLayerIfVisible();
1225}
1226
1227TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1228 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1229
1230 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231}
1232
1233TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001234 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001235
Lloyd Piquede196652020-01-22 17:29:58 -08001236 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001237}
1238
1239TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001240 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001241
Lloyd Piquede196652020-01-22 17:29:58 -08001242 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001243}
1244
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001245TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001246 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001247
Lloyd Piquede196652020-01-22 17:29:58 -08001248 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249}
1250
1251TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1252 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001253 mLayer.layerFEState.isOpaque = true;
1254 mLayer.layerFEState.contentDirty = true;
1255 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001256
1257 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001258 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1259 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001260
Lloyd Piquede196652020-01-22 17:29:58 -08001261 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262
1263 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1264 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1265 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1266
Lloyd Piquede196652020-01-22 17:29:58 -08001267 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1268 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1269 RegionEq(kFullBoundsNoRotation));
1270 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1271 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272}
1273
1274TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1275 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001276 mLayer.layerFEState.isOpaque = true;
1277 mLayer.layerFEState.contentDirty = true;
1278 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001279
Lloyd Piquede196652020-01-22 17:29:58 -08001280 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1281 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001282
Lloyd Piquede196652020-01-22 17:29:58 -08001283 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
1285 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1286 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1287 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1288
Lloyd Piquede196652020-01-22 17:29:58 -08001289 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1290 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1291 RegionEq(kFullBoundsNoRotation));
1292 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1293 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294}
1295
1296TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1297 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001298 mLayer.layerFEState.isOpaque = false;
1299 mLayer.layerFEState.contentDirty = true;
1300 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001301
1302 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001303 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1304 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001305
Lloyd Piquede196652020-01-22 17:29:58 -08001306 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001307
1308 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1309 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1310 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1311
Lloyd Piquede196652020-01-22 17:29:58 -08001312 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1313 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001315 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1316 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001317}
1318
1319TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1320 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001321 mLayer.layerFEState.isOpaque = false;
1322 mLayer.layerFEState.contentDirty = true;
1323 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001324
Lloyd Piquede196652020-01-22 17:29:58 -08001325 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1326 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327
Lloyd Piquede196652020-01-22 17:29:58 -08001328 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329
1330 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1332 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1335 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001337 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1338 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001339}
1340
1341TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1342 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001343 mLayer.layerFEState.isOpaque = true;
1344 mLayer.layerFEState.contentDirty = false;
1345 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346
1347 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001348 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1349 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001350
Lloyd Piquede196652020-01-22 17:29:58 -08001351 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
1353 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1354 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1355 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1358 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1359 RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1361 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001362}
1363
1364TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1365 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001366 mLayer.layerFEState.isOpaque = true;
1367 mLayer.layerFEState.contentDirty = false;
1368 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001369
Lloyd Piquede196652020-01-22 17:29:58 -08001370 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1371 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372
Lloyd Piquede196652020-01-22 17:29:58 -08001373 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001374
1375 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1376 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1377 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1380 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1381 RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1383 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384}
1385
1386TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1387 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001388 mLayer.layerFEState.isOpaque = true;
1389 mLayer.layerFEState.contentDirty = true;
1390 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1391 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1392 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1393 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001394
1395 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001396 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1397 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398
Lloyd Piquede196652020-01-22 17:29:58 -08001399 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400
1401 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1402 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1403 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1404
Lloyd Piquede196652020-01-22 17:29:58 -08001405 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1407 RegionEq(kFullBoundsNoRotation));
1408 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1409 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410}
1411
1412TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1413 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001414 mLayer.layerFEState.isOpaque = true;
1415 mLayer.layerFEState.contentDirty = true;
1416 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1417 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1418 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1419 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
Lloyd Piquede196652020-01-22 17:29:58 -08001421 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1422 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423
Lloyd Piquede196652020-01-22 17:29:58 -08001424 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
1426 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1428 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1431 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1432 RegionEq(kFullBoundsNoRotation));
1433 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1434 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435}
1436
1437TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1438 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001439 mLayer.layerFEState.isOpaque = true;
1440 mLayer.layerFEState.contentDirty = true;
1441 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001442
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001443 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1445
1446 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001447 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1448 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001449
Lloyd Piquede196652020-01-22 17:29:58 -08001450 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
1452 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1453 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1455
Lloyd Piquede196652020-01-22 17:29:58 -08001456 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1457 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1458 RegionEq(kFullBoundsNoRotation));
1459 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1460 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461}
1462
1463TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1464 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001465 mLayer.layerFEState.isOpaque = true;
1466 mLayer.layerFEState.contentDirty = true;
1467 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001469 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1471
Lloyd Piquede196652020-01-22 17:29:58 -08001472 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1473 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001476
1477 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1479 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1480
Lloyd Piquede196652020-01-22 17:29:58 -08001481 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1482 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1483 RegionEq(kFullBoundsNoRotation));
1484 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1485 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486}
1487
1488TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1489 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1490 ui::Transform arbitraryTransform;
1491 arbitraryTransform.set(1, 1, -1, 1);
1492 arbitraryTransform.set(0, 100);
1493
Lloyd Piquede196652020-01-22 17:29:58 -08001494 mLayer.layerFEState.isOpaque = true;
1495 mLayer.layerFEState.contentDirty = true;
1496 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1497 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498
1499 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001500 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1501 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502
Lloyd Piquede196652020-01-22 17:29:58 -08001503 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001504
1505 const Region kRegion = Region(Rect(0, 0, 300, 300));
1506 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1507
1508 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1509 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1510 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1513 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1514 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1515 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516}
1517
1518TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001519 mLayer.layerFEState.isOpaque = false;
1520 mLayer.layerFEState.contentDirty = true;
1521 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001522
1523 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1524 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1525 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1528 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
1532 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1533 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1534 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1535 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1536 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1537 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1538
1539 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1540 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1541 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1542
Lloyd Piquede196652020-01-22 17:29:58 -08001543 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1544 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001546 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1547 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1548 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001550
Vishnu Naira483b4a2019-12-12 15:07:52 -08001551TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1552 ui::Transform translate;
1553 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001554 mLayer.layerFEState.geomLayerTransform = translate;
1555 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001556
1557 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1558 // half of the layer including the casting shadow is covered and opaque
1559 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1560 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1561
Lloyd Piquede196652020-01-22 17:29:58 -08001562 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1563 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001564
Lloyd Piquede196652020-01-22 17:29:58 -08001565 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001566
1567 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1568 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1569 // add starting opaque region to the opaque half of the casting layer bounds
1570 const Region kExpectedAboveOpaqueRegion =
1571 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1572 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1573 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1574 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1575 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1576 const Region kExpectedLayerShadowRegion =
1577 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1578
1579 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1580 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1581 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1584 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001585 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1587 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001588 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001590 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1591}
1592
1593TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1594 ui::Transform translate;
1595 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001596 mLayer.layerFEState.geomLayerTransform = translate;
1597 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001598
1599 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1600 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1601 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1602 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1603
Lloyd Piquede196652020-01-22 17:29:58 -08001604 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1605 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001608
1609 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1610 const Region kExpectedLayerShadowRegion =
1611 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1614 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001615 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1616}
1617
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001618TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001619 ui::Transform translate;
1620 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001621 mLayer.layerFEState.geomLayerTransform = translate;
1622 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001623
1624 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1625 // Casting layer and its shadows are covered by an opaque region
1626 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1627 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001630}
1631
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001632/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001633 * Output::present()
1634 */
1635
1636struct OutputPresentTest : public testing::Test {
1637 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001638 // Sets up the helper functions called by the function under test to use
1639 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001640 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001641 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001642 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001643 MOCK_METHOD0(planComposition, void());
1644 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001645 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1646 MOCK_METHOD0(beginFrame, void());
1647 MOCK_METHOD0(prepareFrame, void());
1648 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1649 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1650 MOCK_METHOD0(postFramebuffer, void());
1651 };
1652
1653 StrictMock<OutputPartialMock> mOutput;
1654};
1655
1656TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1657 CompositionRefreshArgs args;
1658
1659 InSequence seq;
1660 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001661 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1662 EXPECT_CALL(mOutput, planComposition());
1663 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001664 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1665 EXPECT_CALL(mOutput, beginFrame());
1666 EXPECT_CALL(mOutput, prepareFrame());
1667 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1668 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1669 EXPECT_CALL(mOutput, postFramebuffer());
1670
1671 mOutput.present(args);
1672}
1673
1674/*
1675 * Output::updateColorProfile()
1676 */
1677
Lloyd Pique17ca7422019-11-14 14:24:10 -08001678struct OutputUpdateColorProfileTest : public testing::Test {
1679 using TestType = OutputUpdateColorProfileTest;
1680
1681 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001682 // Sets up the helper functions called by the function under test to use
1683 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001684 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1685 };
1686
1687 struct Layer {
1688 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001689 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001690 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001691 }
1692
1693 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001694 StrictMock<mock::LayerFE> mLayerFE;
1695 LayerFECompositionState mLayerFEState;
1696 };
1697
1698 OutputUpdateColorProfileTest() {
1699 mOutput.setDisplayColorProfileForTest(
1700 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1701 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1702
1703 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1704 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1705 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1706 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1707 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1708 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1709 }
1710
1711 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1712 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1713 };
1714
1715 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1716 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1717 StrictMock<OutputPartialMock> mOutput;
1718
1719 Layer mLayer1;
1720 Layer mLayer2;
1721 Layer mLayer3;
1722
1723 CompositionRefreshArgs mRefreshArgs;
1724};
1725
1726// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1727// to make it easier to write unit tests.
1728
1729TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1730 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1731 // a simple default color profile without looking at anything else.
1732
Lloyd Pique0a456232020-01-16 17:51:13 -08001733 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001734 EXPECT_CALL(mOutput,
1735 setColorProfile(ColorProfileEq(
1736 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1737 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1738
1739 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1740 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1741
1742 mOutput.updateColorProfile(mRefreshArgs);
1743}
1744
1745struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1746 : public OutputUpdateColorProfileTest {
1747 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001748 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001749 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1750 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1751 }
1752
1753 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1754 : public CallOrderStateMachineHelper<
1755 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1756 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1757 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1758 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1759 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1760 _))
1761 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1762 SetArgPointee<4>(renderIntent)));
1763 EXPECT_CALL(getInstance()->mOutput,
1764 setColorProfile(
1765 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1766 ui::Dataspace::UNKNOWN})));
1767 return nextState<ExecuteState>();
1768 }
1769 };
1770
1771 // Call this member function to start using the mini-DSL defined above.
1772 [[nodiscard]] auto verify() {
1773 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1774 }
1775};
1776
1777TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1778 Native_Unknown_Colorimetric_Set) {
1779 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1780 ui::Dataspace::UNKNOWN,
1781 ui::RenderIntent::COLORIMETRIC)
1782 .execute();
1783}
1784
1785TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1786 DisplayP3_DisplayP3_Enhance_Set) {
1787 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1788 ui::Dataspace::DISPLAY_P3,
1789 ui::RenderIntent::ENHANCE)
1790 .execute();
1791}
1792
1793struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1794 : public OutputUpdateColorProfileTest {
1795 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001796 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001797 EXPECT_CALL(*mDisplayColorProfile,
1798 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1799 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1800 SetArgPointee<3>(ui::ColorMode::NATIVE),
1801 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1802 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1803 }
1804
1805 struct IfColorSpaceAgnosticDataspaceSetToState
1806 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1807 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1808 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1809 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1810 }
1811 };
1812
1813 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1814 : public CallOrderStateMachineHelper<
1815 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1816 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1817 ui::Dataspace dataspace) {
1818 EXPECT_CALL(getInstance()->mOutput,
1819 setColorProfile(ColorProfileEq(
1820 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1821 ui::RenderIntent::COLORIMETRIC, dataspace})));
1822 return nextState<ExecuteState>();
1823 }
1824 };
1825
1826 // Call this member function to start using the mini-DSL defined above.
1827 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1828};
1829
1830TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1831 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1832 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1833 .execute();
1834}
1835
1836TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1837 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1838 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1839 .execute();
1840}
1841
1842struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1843 : public OutputUpdateColorProfileTest {
1844 // Internally the implementation looks through the dataspaces of all the
1845 // visible layers. The topmost one that also has an actual dataspace
1846 // preference set is used to drive subsequent choices.
1847
1848 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1849 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1850 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1851
Lloyd Pique0a456232020-01-16 17:51:13 -08001852 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001853 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1854 }
1855
1856 struct IfTopLayerDataspaceState
1857 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1858 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1859 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1860 return nextState<AndIfMiddleLayerDataspaceState>();
1861 }
1862 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1863 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1864 }
1865 };
1866
1867 struct AndIfMiddleLayerDataspaceState
1868 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1869 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1870 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1871 return nextState<AndIfBottomLayerDataspaceState>();
1872 }
1873 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1874 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1875 }
1876 };
1877
1878 struct AndIfBottomLayerDataspaceState
1879 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1880 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1881 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1882 return nextState<ThenExpectBestColorModeCallUsesState>();
1883 }
1884 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1885 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1886 }
1887 };
1888
1889 struct ThenExpectBestColorModeCallUsesState
1890 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1891 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1892 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1893 getBestColorMode(dataspace, _, _, _, _));
1894 return nextState<ExecuteState>();
1895 }
1896 };
1897
1898 // Call this member function to start using the mini-DSL defined above.
1899 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1900};
1901
1902TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1903 noStrongLayerPrefenceUses_V0_SRGB) {
1904 // If none of the layers indicate a preference, then V0_SRGB is the
1905 // preferred choice (subject to additional checks).
1906 verify().ifTopLayerHasNoPreference()
1907 .andIfMiddleLayerHasNoPreference()
1908 .andIfBottomLayerHasNoPreference()
1909 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1910 .execute();
1911}
1912
1913TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1914 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1915 // If only the topmost layer has a preference, then that is what is chosen.
1916 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1917 .andIfMiddleLayerHasNoPreference()
1918 .andIfBottomLayerHasNoPreference()
1919 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1920 .execute();
1921}
1922
1923TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1924 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1925 // If only the middle layer has a preference, that that is what is chosen.
1926 verify().ifTopLayerHasNoPreference()
1927 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1928 .andIfBottomLayerHasNoPreference()
1929 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1930 .execute();
1931}
1932
1933TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1934 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1935 // If only the middle layer has a preference, that that is what is chosen.
1936 verify().ifTopLayerHasNoPreference()
1937 .andIfMiddleLayerHasNoPreference()
1938 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1939 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1940 .execute();
1941}
1942
1943TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1944 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1945 // If multiple layers have a preference, the topmost value is what is used.
1946 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1947 .andIfMiddleLayerHasNoPreference()
1948 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1949 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1950 .execute();
1951}
1952
1953TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1954 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1955 // If multiple layers have a preference, the topmost value is what is used.
1956 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1957 .andIfMiddleLayerHasNoPreference()
1958 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1959 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1960 .execute();
1961}
1962
1963struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1964 : public OutputUpdateColorProfileTest {
1965 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1966 // values, it overrides the layer dataspace choice.
1967
1968 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1969 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1970 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1971
1972 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1973
Lloyd Pique0a456232020-01-16 17:51:13 -08001974 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001975 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1976 }
1977
1978 struct IfForceOutputColorModeState
1979 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1980 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1981 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1982 return nextState<ThenExpectBestColorModeCallUsesState>();
1983 }
1984 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1985 };
1986
1987 struct ThenExpectBestColorModeCallUsesState
1988 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1989 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1990 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1991 getBestColorMode(dataspace, _, _, _, _));
1992 return nextState<ExecuteState>();
1993 }
1994 };
1995
1996 // Call this member function to start using the mini-DSL defined above.
1997 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1998};
1999
2000TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2001 // By default the layer state is used to set the preferred dataspace
2002 verify().ifNoOverride()
2003 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2004 .execute();
2005}
2006
2007TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2008 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2009 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2010 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2011 .execute();
2012}
2013
2014TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2015 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2016 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2017 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2018 .execute();
2019}
2020
2021// HDR output requires all layers to be compatible with the chosen HDR
2022// dataspace, along with there being proper support.
2023struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2024 OutputUpdateColorProfileTest_Hdr() {
2025 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2026 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002027 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002028 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2029 }
2030
2031 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2032 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2033 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2034 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2035
2036 struct IfTopLayerDataspaceState
2037 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2038 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2039 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2040 return nextState<AndTopLayerCompositionTypeState>();
2041 }
2042 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2043 };
2044
2045 struct AndTopLayerCompositionTypeState
2046 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2047 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2048 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2049 return nextState<AndIfBottomLayerDataspaceState>();
2050 }
2051 };
2052
2053 struct AndIfBottomLayerDataspaceState
2054 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2055 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2056 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2057 return nextState<AndBottomLayerCompositionTypeState>();
2058 }
2059 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2060 return andIfBottomLayerIs(kNonHdrDataspace);
2061 }
2062 };
2063
2064 struct AndBottomLayerCompositionTypeState
2065 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2066 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2067 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2068 return nextState<AndIfHasLegacySupportState>();
2069 }
2070 };
2071
2072 struct AndIfHasLegacySupportState
2073 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2074 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2075 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2076 .WillOnce(Return(legacySupport));
2077 return nextState<ThenExpectBestColorModeCallUsesState>();
2078 }
2079 };
2080
2081 struct ThenExpectBestColorModeCallUsesState
2082 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2083 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2084 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2085 getBestColorMode(dataspace, _, _, _, _));
2086 return nextState<ExecuteState>();
2087 }
2088 };
2089
2090 // Call this member function to start using the mini-DSL defined above.
2091 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2092};
2093
2094TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2095 // If all layers use BT2020_PQ, and there are no other special conditions,
2096 // BT2020_PQ is used.
2097 verify().ifTopLayerIs(BT2020_PQ)
2098 .andTopLayerIsREComposed(false)
2099 .andIfBottomLayerIs(BT2020_PQ)
2100 .andBottomLayerIsREComposed(false)
2101 .andIfLegacySupportFor(BT2020_PQ, false)
2102 .thenExpectBestColorModeCallUses(BT2020_PQ)
2103 .execute();
2104}
2105
2106TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2107 // BT2020_PQ is not used if there is only legacy support for it.
2108 verify().ifTopLayerIs(BT2020_PQ)
2109 .andTopLayerIsREComposed(false)
2110 .andIfBottomLayerIs(BT2020_PQ)
2111 .andBottomLayerIsREComposed(false)
2112 .andIfLegacySupportFor(BT2020_PQ, true)
2113 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2114 .execute();
2115}
2116
2117TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2118 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2119 verify().ifTopLayerIs(BT2020_PQ)
2120 .andTopLayerIsREComposed(false)
2121 .andIfBottomLayerIs(BT2020_PQ)
2122 .andBottomLayerIsREComposed(true)
2123 .andIfLegacySupportFor(BT2020_PQ, false)
2124 .thenExpectBestColorModeCallUses(BT2020_PQ)
2125 .execute();
2126}
2127
2128TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2129 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2130 verify().ifTopLayerIs(BT2020_PQ)
2131 .andTopLayerIsREComposed(true)
2132 .andIfBottomLayerIs(BT2020_PQ)
2133 .andBottomLayerIsREComposed(false)
2134 .andIfLegacySupportFor(BT2020_PQ, false)
2135 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2136 .execute();
2137}
2138
2139TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2140 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2141 // are no other special conditions.
2142 verify().ifTopLayerIs(BT2020_PQ)
2143 .andTopLayerIsREComposed(false)
2144 .andIfBottomLayerIs(BT2020_HLG)
2145 .andBottomLayerIsREComposed(false)
2146 .andIfLegacySupportFor(BT2020_PQ, false)
2147 .thenExpectBestColorModeCallUses(BT2020_PQ)
2148 .execute();
2149}
2150
2151TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2152 // BT2020_PQ is not used if there is only legacy support for it.
2153 verify().ifTopLayerIs(BT2020_PQ)
2154 .andTopLayerIsREComposed(false)
2155 .andIfBottomLayerIs(BT2020_HLG)
2156 .andBottomLayerIsREComposed(false)
2157 .andIfLegacySupportFor(BT2020_PQ, true)
2158 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2159 .execute();
2160}
2161
2162TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2163 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2164 verify().ifTopLayerIs(BT2020_PQ)
2165 .andTopLayerIsREComposed(false)
2166 .andIfBottomLayerIs(BT2020_HLG)
2167 .andBottomLayerIsREComposed(true)
2168 .andIfLegacySupportFor(BT2020_PQ, false)
2169 .thenExpectBestColorModeCallUses(BT2020_PQ)
2170 .execute();
2171}
2172
2173TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2174 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2175 verify().ifTopLayerIs(BT2020_PQ)
2176 .andTopLayerIsREComposed(true)
2177 .andIfBottomLayerIs(BT2020_HLG)
2178 .andBottomLayerIsREComposed(false)
2179 .andIfLegacySupportFor(BT2020_PQ, false)
2180 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2185 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2186 // used if there are no other special conditions.
2187 verify().ifTopLayerIs(BT2020_HLG)
2188 .andTopLayerIsREComposed(false)
2189 .andIfBottomLayerIs(BT2020_PQ)
2190 .andBottomLayerIsREComposed(false)
2191 .andIfLegacySupportFor(BT2020_PQ, false)
2192 .thenExpectBestColorModeCallUses(BT2020_PQ)
2193 .execute();
2194}
2195
2196TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2197 // BT2020_PQ is not used if there is only legacy support for it.
2198 verify().ifTopLayerIs(BT2020_HLG)
2199 .andTopLayerIsREComposed(false)
2200 .andIfBottomLayerIs(BT2020_PQ)
2201 .andBottomLayerIsREComposed(false)
2202 .andIfLegacySupportFor(BT2020_PQ, true)
2203 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2204 .execute();
2205}
2206
2207TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2208 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2209 verify().ifTopLayerIs(BT2020_HLG)
2210 .andTopLayerIsREComposed(false)
2211 .andIfBottomLayerIs(BT2020_PQ)
2212 .andBottomLayerIsREComposed(true)
2213 .andIfLegacySupportFor(BT2020_PQ, false)
2214 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2215 .execute();
2216}
2217
2218TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2219 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2220 verify().ifTopLayerIs(BT2020_HLG)
2221 .andTopLayerIsREComposed(true)
2222 .andIfBottomLayerIs(BT2020_PQ)
2223 .andBottomLayerIsREComposed(false)
2224 .andIfLegacySupportFor(BT2020_PQ, false)
2225 .thenExpectBestColorModeCallUses(BT2020_PQ)
2226 .execute();
2227}
2228
2229TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2230 // If all layers use HLG then HLG is used if there are no other special
2231 // conditions.
2232 verify().ifTopLayerIs(BT2020_HLG)
2233 .andTopLayerIsREComposed(false)
2234 .andIfBottomLayerIs(BT2020_HLG)
2235 .andBottomLayerIsREComposed(false)
2236 .andIfLegacySupportFor(BT2020_HLG, false)
2237 .thenExpectBestColorModeCallUses(BT2020_HLG)
2238 .execute();
2239}
2240
2241TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2242 // BT2020_HLG is not used if there is legacy support for it.
2243 verify().ifTopLayerIs(BT2020_HLG)
2244 .andTopLayerIsREComposed(false)
2245 .andIfBottomLayerIs(BT2020_HLG)
2246 .andBottomLayerIsREComposed(false)
2247 .andIfLegacySupportFor(BT2020_HLG, true)
2248 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2249 .execute();
2250}
2251
2252TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2253 // BT2020_HLG is used even if the bottom layer is client composed.
2254 verify().ifTopLayerIs(BT2020_HLG)
2255 .andTopLayerIsREComposed(false)
2256 .andIfBottomLayerIs(BT2020_HLG)
2257 .andBottomLayerIsREComposed(true)
2258 .andIfLegacySupportFor(BT2020_HLG, false)
2259 .thenExpectBestColorModeCallUses(BT2020_HLG)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2264 // BT2020_HLG is used even if the top layer is client composed.
2265 verify().ifTopLayerIs(BT2020_HLG)
2266 .andTopLayerIsREComposed(true)
2267 .andIfBottomLayerIs(BT2020_HLG)
2268 .andBottomLayerIsREComposed(false)
2269 .andIfLegacySupportFor(BT2020_HLG, false)
2270 .thenExpectBestColorModeCallUses(BT2020_HLG)
2271 .execute();
2272}
2273
2274TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2275 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2276 verify().ifTopLayerIs(BT2020_PQ)
2277 .andTopLayerIsREComposed(false)
2278 .andIfBottomLayerIsNotHdr()
2279 .andBottomLayerIsREComposed(false)
2280 .andIfLegacySupportFor(BT2020_PQ, false)
2281 .thenExpectBestColorModeCallUses(BT2020_PQ)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2286 // If all layers use HLG then HLG is used if there are no other special
2287 // conditions.
2288 verify().ifTopLayerIs(BT2020_HLG)
2289 .andTopLayerIsREComposed(false)
2290 .andIfBottomLayerIsNotHdr()
2291 .andBottomLayerIsREComposed(true)
2292 .andIfLegacySupportFor(BT2020_HLG, false)
2293 .thenExpectBestColorModeCallUses(BT2020_HLG)
2294 .execute();
2295}
2296
2297struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2298 : public OutputUpdateColorProfileTest {
2299 // The various values for CompositionRefreshArgs::outputColorSetting affect
2300 // the chosen renderIntent, along with whether the preferred dataspace is an
2301 // HDR dataspace or not.
2302
2303 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2304 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2305 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2306 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002307 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002308 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2309 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2310 .WillRepeatedly(Return(false));
2311 }
2312
2313 // The tests here involve enough state and GMock setup that using a mini-DSL
2314 // makes the tests much more readable, and allows the test to focus more on
2315 // the intent than on some of the details.
2316
2317 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2318 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2319
2320 struct IfDataspaceChosenState
2321 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2322 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2323 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2324 return nextState<AndOutputColorSettingState>();
2325 }
2326 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2327 return ifDataspaceChosenIs(kNonHdrDataspace);
2328 }
2329 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2330 };
2331
2332 struct AndOutputColorSettingState
2333 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2334 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2335 getInstance()->mRefreshArgs.outputColorSetting = setting;
2336 return nextState<ThenExpectBestColorModeCallUsesState>();
2337 }
2338 };
2339
2340 struct ThenExpectBestColorModeCallUsesState
2341 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2342 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2343 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2344 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2345 _, _));
2346 return nextState<ExecuteState>();
2347 }
2348 };
2349
2350 // Tests call one of these two helper member functions to start using the
2351 // mini-DSL defined above.
2352 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2353};
2354
2355TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2356 Managed_NonHdr_Prefers_Colorimetric) {
2357 verify().ifDataspaceChosenIsNonHdr()
2358 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2359 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2360 .execute();
2361}
2362
2363TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2364 Managed_Hdr_Prefers_ToneMapColorimetric) {
2365 verify().ifDataspaceChosenIsHdr()
2366 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2367 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2372 verify().ifDataspaceChosenIsNonHdr()
2373 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2374 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2375 .execute();
2376}
2377
2378TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2379 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2380 verify().ifDataspaceChosenIsHdr()
2381 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2382 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2383 .execute();
2384}
2385
2386TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2387 verify().ifDataspaceChosenIsNonHdr()
2388 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2389 .thenExpectBestColorModeCallUses(
2390 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2391 .execute();
2392}
2393
2394TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2395 verify().ifDataspaceChosenIsHdr()
2396 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2397 .thenExpectBestColorModeCallUses(
2398 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2399 .execute();
2400}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002401
2402/*
2403 * Output::beginFrame()
2404 */
2405
Lloyd Piquee5965952019-11-18 16:16:32 -08002406struct OutputBeginFrameTest : public ::testing::Test {
2407 using TestType = OutputBeginFrameTest;
2408
2409 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002410 // Sets up the helper functions called by the function under test to use
2411 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002412 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2413 };
2414
2415 OutputBeginFrameTest() {
2416 mOutput.setDisplayColorProfileForTest(
2417 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2418 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2419 }
2420
2421 struct IfGetDirtyRegionExpectationState
2422 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2423 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2424 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2425 .WillOnce(Return(dirtyRegion));
2426 return nextState<AndIfGetOutputLayerCountExpectationState>();
2427 }
2428 };
2429
2430 struct AndIfGetOutputLayerCountExpectationState
2431 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2432 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2433 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2434 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2435 }
2436 };
2437
2438 struct AndIfLastCompositionHadVisibleLayersState
2439 : public CallOrderStateMachineHelper<TestType,
2440 AndIfLastCompositionHadVisibleLayersState> {
2441 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2442 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2443 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2444 }
2445 };
2446
2447 struct ThenExpectRenderSurfaceBeginFrameCallState
2448 : public CallOrderStateMachineHelper<TestType,
2449 ThenExpectRenderSurfaceBeginFrameCallState> {
2450 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2451 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2452 return nextState<ExecuteState>();
2453 }
2454 };
2455
2456 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2457 [[nodiscard]] auto execute() {
2458 getInstance()->mOutput.beginFrame();
2459 return nextState<CheckPostconditionHadVisibleLayersState>();
2460 }
2461 };
2462
2463 struct CheckPostconditionHadVisibleLayersState
2464 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2465 void checkPostconditionHadVisibleLayers(bool expected) {
2466 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2467 }
2468 };
2469
2470 // Tests call one of these two helper member functions to start using the
2471 // mini-DSL defined above.
2472 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2473
2474 static const Region kEmptyRegion;
2475 static const Region kNotEmptyRegion;
2476
2477 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2478 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2479 StrictMock<OutputPartialMock> mOutput;
2480};
2481
2482const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2483const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2484
2485TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2486 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2487 .andIfGetOutputLayerCountReturns(1u)
2488 .andIfLastCompositionHadVisibleLayersIs(true)
2489 .thenExpectRenderSurfaceBeginFrameCall(true)
2490 .execute()
2491 .checkPostconditionHadVisibleLayers(true);
2492}
2493
2494TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2495 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2496 .andIfGetOutputLayerCountReturns(0u)
2497 .andIfLastCompositionHadVisibleLayersIs(true)
2498 .thenExpectRenderSurfaceBeginFrameCall(true)
2499 .execute()
2500 .checkPostconditionHadVisibleLayers(false);
2501}
2502
2503TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2504 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2505 .andIfGetOutputLayerCountReturns(1u)
2506 .andIfLastCompositionHadVisibleLayersIs(false)
2507 .thenExpectRenderSurfaceBeginFrameCall(true)
2508 .execute()
2509 .checkPostconditionHadVisibleLayers(true);
2510}
2511
2512TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2513 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2514 .andIfGetOutputLayerCountReturns(0u)
2515 .andIfLastCompositionHadVisibleLayersIs(false)
2516 .thenExpectRenderSurfaceBeginFrameCall(false)
2517 .execute()
2518 .checkPostconditionHadVisibleLayers(false);
2519}
2520
2521TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2522 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2523 .andIfGetOutputLayerCountReturns(1u)
2524 .andIfLastCompositionHadVisibleLayersIs(true)
2525 .thenExpectRenderSurfaceBeginFrameCall(false)
2526 .execute()
2527 .checkPostconditionHadVisibleLayers(true);
2528}
2529
2530TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2531 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2532 .andIfGetOutputLayerCountReturns(0u)
2533 .andIfLastCompositionHadVisibleLayersIs(true)
2534 .thenExpectRenderSurfaceBeginFrameCall(false)
2535 .execute()
2536 .checkPostconditionHadVisibleLayers(true);
2537}
2538
2539TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2540 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2541 .andIfGetOutputLayerCountReturns(1u)
2542 .andIfLastCompositionHadVisibleLayersIs(false)
2543 .thenExpectRenderSurfaceBeginFrameCall(false)
2544 .execute()
2545 .checkPostconditionHadVisibleLayers(false);
2546}
2547
2548TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2549 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2550 .andIfGetOutputLayerCountReturns(0u)
2551 .andIfLastCompositionHadVisibleLayersIs(false)
2552 .thenExpectRenderSurfaceBeginFrameCall(false)
2553 .execute()
2554 .checkPostconditionHadVisibleLayers(false);
2555}
2556
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002557/*
2558 * Output::devOptRepaintFlash()
2559 */
2560
Lloyd Piquedb462d82019-11-19 17:58:46 -08002561struct OutputDevOptRepaintFlashTest : public testing::Test {
2562 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002563 // Sets up the helper functions called by the function under test to use
2564 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002565 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002566 MOCK_METHOD2(composeSurfaces,
2567 std::optional<base::unique_fd>(
2568 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002569 MOCK_METHOD0(postFramebuffer, void());
2570 MOCK_METHOD0(prepareFrame, void());
2571 };
2572
2573 OutputDevOptRepaintFlashTest() {
2574 mOutput.setDisplayColorProfileForTest(
2575 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2576 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2577 }
2578
2579 static const Region kEmptyRegion;
2580 static const Region kNotEmptyRegion;
2581
2582 StrictMock<OutputPartialMock> mOutput;
2583 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2584 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2585 CompositionRefreshArgs mRefreshArgs;
2586};
2587
2588const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2589const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2590
2591TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2592 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2593 mRefreshArgs.repaintEverything = true;
2594 mOutput.mState.isEnabled = true;
2595
2596 mOutput.devOptRepaintFlash(mRefreshArgs);
2597}
2598
2599TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2600 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2601 mRefreshArgs.repaintEverything = true;
2602 mOutput.mState.isEnabled = false;
2603
2604 InSequence seq;
2605 EXPECT_CALL(mOutput, postFramebuffer());
2606 EXPECT_CALL(mOutput, prepareFrame());
2607
2608 mOutput.devOptRepaintFlash(mRefreshArgs);
2609}
2610
2611TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2612 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2613 mRefreshArgs.repaintEverything = true;
2614 mOutput.mState.isEnabled = true;
2615
2616 InSequence seq;
2617 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2618 EXPECT_CALL(mOutput, postFramebuffer());
2619 EXPECT_CALL(mOutput, prepareFrame());
2620
2621 mOutput.devOptRepaintFlash(mRefreshArgs);
2622}
2623
2624TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2625 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2626 mRefreshArgs.repaintEverything = false;
2627 mOutput.mState.isEnabled = true;
2628
2629 InSequence seq;
2630 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002631 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002632 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2633 EXPECT_CALL(mOutput, postFramebuffer());
2634 EXPECT_CALL(mOutput, prepareFrame());
2635
2636 mOutput.devOptRepaintFlash(mRefreshArgs);
2637}
2638
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002639/*
2640 * Output::finishFrame()
2641 */
2642
Lloyd Pique03561a62019-11-19 18:34:52 -08002643struct OutputFinishFrameTest : public testing::Test {
2644 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002645 // Sets up the helper functions called by the function under test to use
2646 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002647 MOCK_METHOD2(composeSurfaces,
2648 std::optional<base::unique_fd>(
2649 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002650 MOCK_METHOD0(postFramebuffer, void());
2651 };
2652
2653 OutputFinishFrameTest() {
2654 mOutput.setDisplayColorProfileForTest(
2655 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2656 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2657 }
2658
2659 StrictMock<OutputPartialMock> mOutput;
2660 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2661 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2662 CompositionRefreshArgs mRefreshArgs;
2663};
2664
2665TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2666 mOutput.mState.isEnabled = false;
2667
2668 mOutput.finishFrame(mRefreshArgs);
2669}
2670
2671TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2672 mOutput.mState.isEnabled = true;
2673
2674 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002675 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002676
2677 mOutput.finishFrame(mRefreshArgs);
2678}
2679
2680TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2681 mOutput.mState.isEnabled = true;
2682
2683 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002684 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002685 .WillOnce(Return(ByMove(base::unique_fd())));
2686 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2687
2688 mOutput.finishFrame(mRefreshArgs);
2689}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002690
2691/*
2692 * Output::postFramebuffer()
2693 */
2694
Lloyd Pique07178e32019-11-19 19:15:26 -08002695struct OutputPostFramebufferTest : public testing::Test {
2696 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002697 // Sets up the helper functions called by the function under test to use
2698 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002699 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2700 };
2701
2702 struct Layer {
2703 Layer() {
2704 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2705 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2706 }
2707
2708 StrictMock<mock::OutputLayer> outputLayer;
2709 StrictMock<mock::LayerFE> layerFE;
2710 StrictMock<HWC2::mock::Layer> hwc2Layer;
2711 };
2712
2713 OutputPostFramebufferTest() {
2714 mOutput.setDisplayColorProfileForTest(
2715 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2716 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2717
2718 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2719 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2720 .WillRepeatedly(Return(&mLayer1.outputLayer));
2721 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2722 .WillRepeatedly(Return(&mLayer2.outputLayer));
2723 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2724 .WillRepeatedly(Return(&mLayer3.outputLayer));
2725 }
2726
2727 StrictMock<OutputPartialMock> mOutput;
2728 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2729 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2730
2731 Layer mLayer1;
2732 Layer mLayer2;
2733 Layer mLayer3;
2734};
2735
2736TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2737 mOutput.mState.isEnabled = false;
2738
2739 mOutput.postFramebuffer();
2740}
2741
2742TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2743 mOutput.mState.isEnabled = true;
2744
2745 compositionengine::Output::FrameFences frameFences;
2746
2747 // This should happen even if there are no output layers.
2748 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2749
2750 // For this test in particular we want to make sure the call expectations
2751 // setup below are satisfied in the specific order.
2752 InSequence seq;
2753
2754 EXPECT_CALL(*mRenderSurface, flip());
2755 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2756 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2757
2758 mOutput.postFramebuffer();
2759}
2760
2761TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2762 // Simulate getting release fences from each layer, and ensure they are passed to the
2763 // front-end layer interface for each layer correctly.
2764
2765 mOutput.mState.isEnabled = true;
2766
2767 // Create three unique fence instances
2768 sp<Fence> layer1Fence = new Fence();
2769 sp<Fence> layer2Fence = new Fence();
2770 sp<Fence> layer3Fence = new Fence();
2771
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002772 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002773 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2774 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2775 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2776
2777 EXPECT_CALL(*mRenderSurface, flip());
2778 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2779 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2780
2781 // Compare the pointers values of each fence to make sure the correct ones
2782 // are passed. This happens to work with the current implementation, but
2783 // would not survive certain calls like Fence::merge() which would return a
2784 // new instance.
2785 EXPECT_CALL(mLayer1.layerFE,
2786 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2787 EXPECT_CALL(mLayer2.layerFE,
2788 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2789 EXPECT_CALL(mLayer3.layerFE,
2790 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2791
2792 mOutput.postFramebuffer();
2793}
2794
2795TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2796 mOutput.mState.isEnabled = true;
2797 mOutput.mState.usesClientComposition = true;
2798
2799 sp<Fence> clientTargetAcquireFence = new Fence();
2800 sp<Fence> layer1Fence = new Fence();
2801 sp<Fence> layer2Fence = new Fence();
2802 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002803 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002804 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2805 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2806 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2807 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2808
2809 EXPECT_CALL(*mRenderSurface, flip());
2810 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2811 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2812
2813 // Fence::merge is called, and since none of the fences are actually valid,
2814 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2815 // This is the best we can do without creating a real kernel fence object.
2816 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2817 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2818 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2819
2820 mOutput.postFramebuffer();
2821}
2822
2823TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2824 mOutput.mState.isEnabled = true;
2825 mOutput.mState.usesClientComposition = true;
2826
2827 // This should happen even if there are no (current) output layers.
2828 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2829
2830 // Load up the released layers with some mock instances
2831 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2832 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2833 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2834 Output::ReleasedLayers layers;
2835 layers.push_back(releasedLayer1);
2836 layers.push_back(releasedLayer2);
2837 layers.push_back(releasedLayer3);
2838 mOutput.setReleasedLayers(std::move(layers));
2839
2840 // Set up a fake present fence
2841 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002842 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002843 frameFences.presentFence = presentFence;
2844
2845 EXPECT_CALL(*mRenderSurface, flip());
2846 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2847 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2848
2849 // Each released layer should be given the presentFence.
2850 EXPECT_CALL(*releasedLayer1,
2851 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2852 EXPECT_CALL(*releasedLayer2,
2853 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2854 EXPECT_CALL(*releasedLayer3,
2855 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2856
2857 mOutput.postFramebuffer();
2858
2859 // After the call the list of released layers should have been cleared.
2860 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2861}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002862
2863/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002864 * Output::composeSurfaces()
2865 */
2866
2867struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002868 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002869
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002870 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002871 // Sets up the helper functions called by the function under test to use
2872 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002873 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002874 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002875 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002876 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002877 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002878 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2879 };
2880
2881 OutputComposeSurfacesTest() {
2882 mOutput.setDisplayColorProfileForTest(
2883 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2884 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002885 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002886
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002887 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2888 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002889 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002890 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002891 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002892 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002893 mOutput.mState.dataspace = kDefaultOutputDataspace;
2894 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2895 mOutput.mState.isSecure = false;
2896 mOutput.mState.needsFiltering = false;
2897 mOutput.mState.usesClientComposition = true;
2898 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002899 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002900 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002901
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002902 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002903 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002904 EXPECT_CALL(mCompositionEngine, getTimeStats())
2905 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002906 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2907 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002908 }
2909
Lloyd Pique6818fa52019-12-03 12:32:13 -08002910 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2911 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002912 getInstance()->mReadyFence =
2913 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002914 return nextState<FenceCheckState>();
2915 }
2916 };
2917
2918 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2919 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2920
2921 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2922 };
2923
2924 // Call this member function to start using the mini-DSL defined above.
2925 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2926
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002927 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2928 static constexpr uint32_t kDefaultOutputOrientationFlags =
2929 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002930 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2931 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2932 static constexpr float kDefaultMaxLuminance = 0.9f;
2933 static constexpr float kDefaultAvgLuminance = 0.7f;
2934 static constexpr float kDefaultMinLuminance = 0.1f;
2935
2936 static const Rect kDefaultOutputFrame;
2937 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002938 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002939 static const mat4 kDefaultColorTransformMat;
2940
2941 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002942 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002943 static const HdrCapabilities kHdrCapabilities;
2944
Lloyd Pique56eba802019-08-28 15:45:25 -07002945 StrictMock<mock::CompositionEngine> mCompositionEngine;
2946 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002947 // TODO: make this is a proper mock.
2948 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002949 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2950 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002951 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002952 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002953
2954 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002955};
2956
2957const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2958const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002959const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002960const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002961const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002962const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2963const HdrCapabilities OutputComposeSurfacesTest::
2964 kHdrCapabilities{{},
2965 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2966 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2967 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002968
Lloyd Piquea76ce462020-01-14 13:06:37 -08002969TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002970 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002971
Lloyd Piquee9eff972020-05-05 12:36:44 -07002972 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002973 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002974
Lloyd Piquea76ce462020-01-14 13:06:37 -08002975 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2976
Lloyd Pique6818fa52019-12-03 12:32:13 -08002977 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002978}
2979
Lloyd Piquee9eff972020-05-05 12:36:44 -07002980TEST_F(OutputComposeSurfacesTest,
2981 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2982 mOutput.mState.usesClientComposition = false;
2983 mOutput.mState.flipClientTarget = true;
2984
Lloyd Pique6818fa52019-12-03 12:32:13 -08002985 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002986 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002987
2988 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2989 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2990
2991 verify().execute().expectAFenceWasReturned();
2992}
2993
2994TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2995 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002996 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002997
2998 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2999
3000 verify().execute().expectNoFenceWasReturned();
3001}
3002
3003TEST_F(OutputComposeSurfacesTest,
3004 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3005 mOutput.mState.usesClientComposition = false;
3006 mOutput.mState.flipClientTarget = true;
3007
3008 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003009 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003010
Lloyd Pique6818fa52019-12-03 12:32:13 -08003011 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003012
Lloyd Pique6818fa52019-12-03 12:32:13 -08003013 verify().execute().expectNoFenceWasReturned();
3014}
Lloyd Pique56eba802019-08-28 15:45:25 -07003015
Lloyd Pique6818fa52019-12-03 12:32:13 -08003016TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3017 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3018 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3019 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003020 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003021 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003022 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003023 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3024 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003025
Lloyd Pique6818fa52019-12-03 12:32:13 -08003026 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003027 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003028 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003029
Lloyd Pique6818fa52019-12-03 12:32:13 -08003030 verify().execute().expectAFenceWasReturned();
3031}
Lloyd Pique56eba802019-08-28 15:45:25 -07003032
Lloyd Pique6818fa52019-12-03 12:32:13 -08003033TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003034 LayerFE::LayerSettings r1;
3035 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003036
3037 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3038 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3039
3040 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3041 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3042 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003043 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003044 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003045 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003046 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3047 .WillRepeatedly(
3048 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003049 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003050 clientCompositionLayers.emplace_back(r2);
3051 }));
3052
3053 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003054 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3055 .WillRepeatedly(Return(NO_ERROR));
3056
3057 verify().execute().expectAFenceWasReturned();
3058}
3059
3060TEST_F(OutputComposeSurfacesTest,
3061 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3062 LayerFE::LayerSettings r1;
3063 LayerFE::LayerSettings r2;
3064
3065 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3066 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3067 const constexpr uint32_t kInternalLayerStack = 1234;
3068 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3069
3070 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3071 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3072 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3073 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3074 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3075 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3076 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3077 .WillRepeatedly(
3078 Invoke([&](const Region&,
3079 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3080 clientCompositionLayers.emplace_back(r2);
3081 }));
3082
3083 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003084 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003085 .WillRepeatedly(Return(NO_ERROR));
3086
3087 verify().execute().expectAFenceWasReturned();
3088}
3089
Vishnu Nair9b079a22020-01-21 14:36:08 -08003090TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3091 mOutput.cacheClientCompositionRequests(0);
3092 LayerFE::LayerSettings r1;
3093 LayerFE::LayerSettings r2;
3094
3095 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3096 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3097
3098 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3099 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3100 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003101 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003102 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3103 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3104 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3105 .WillRepeatedly(Return());
3106
3107 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003108 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003109 .Times(2)
3110 .WillOnce(Return(NO_ERROR));
3111
3112 verify().execute().expectAFenceWasReturned();
3113 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3114
3115 verify().execute().expectAFenceWasReturned();
3116 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3117}
3118
3119TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3120 mOutput.cacheClientCompositionRequests(3);
3121 LayerFE::LayerSettings r1;
3122 LayerFE::LayerSettings r2;
3123
3124 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3125 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3126
3127 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3128 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3129 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003130 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003131 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3132 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3133 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3134 .WillRepeatedly(Return());
3135
3136 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003137 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003138 .WillOnce(Return(NO_ERROR));
3139 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3140
3141 verify().execute().expectAFenceWasReturned();
3142 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3143
3144 // We do not expect another call to draw layers.
3145 verify().execute().expectAFenceWasReturned();
3146 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3147}
3148
3149TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3150 LayerFE::LayerSettings r1;
3151 LayerFE::LayerSettings r2;
3152
3153 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3154 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3155
3156 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3157 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3158 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003159 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003160 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3161 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3162 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3163 .WillRepeatedly(Return());
3164
3165 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3166 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3167 .WillOnce(Return(mOutputBuffer))
3168 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003169 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003170 .WillRepeatedly(Return(NO_ERROR));
3171
3172 verify().execute().expectAFenceWasReturned();
3173 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3174
3175 verify().execute().expectAFenceWasReturned();
3176 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3177}
3178
3179TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3180 LayerFE::LayerSettings r1;
3181 LayerFE::LayerSettings r2;
3182 LayerFE::LayerSettings r3;
3183
3184 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3185 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3186 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3187
3188 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3189 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3190 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003191 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003192 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3193 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3194 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3195 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3196 .WillRepeatedly(Return());
3197
3198 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003199 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003200 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003201 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003202 .WillOnce(Return(NO_ERROR));
3203
3204 verify().execute().expectAFenceWasReturned();
3205 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3206
3207 verify().execute().expectAFenceWasReturned();
3208 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3209}
3210
Lloyd Pique6818fa52019-12-03 12:32:13 -08003211struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3212 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3213 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003214 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003215 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003216 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003217 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3218 .WillRepeatedly(Return());
3219 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3220 }
3221
3222 struct MixedCompositionState
3223 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3224 auto ifMixedCompositionIs(bool used) {
3225 getInstance()->mOutput.mState.usesDeviceComposition = used;
3226 return nextState<OutputUsesHdrState>();
3227 }
3228 };
3229
3230 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3231 auto andIfUsesHdr(bool used) {
3232 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3233 .WillOnce(Return(used));
3234 return nextState<SkipColorTransformState>();
3235 }
3236 };
3237
3238 struct SkipColorTransformState
3239 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3240 auto andIfSkipColorTransform(bool skip) {
3241 // May be called zero or one times.
3242 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3243 .WillRepeatedly(Return(skip));
3244 return nextState<ExpectDisplaySettingsState>();
3245 }
3246 };
3247
3248 struct ExpectDisplaySettingsState
3249 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3250 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003251 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003252 .WillOnce(Return(NO_ERROR));
3253 return nextState<ExecuteState>();
3254 }
3255 };
3256
3257 // Call this member function to start using the mini-DSL defined above.
3258 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3259};
3260
3261TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3262 verify().ifMixedCompositionIs(true)
3263 .andIfUsesHdr(true)
3264 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003265 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003266 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003267 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003268 .execute()
3269 .expectAFenceWasReturned();
3270}
3271
3272TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3273 verify().ifMixedCompositionIs(true)
3274 .andIfUsesHdr(false)
3275 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003276 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003277 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003278 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003279 .execute()
3280 .expectAFenceWasReturned();
3281}
3282
3283TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3284 verify().ifMixedCompositionIs(false)
3285 .andIfUsesHdr(true)
3286 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003287 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003288 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003289 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003290 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003291 .execute()
3292 .expectAFenceWasReturned();
3293}
3294
3295TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3296 verify().ifMixedCompositionIs(false)
3297 .andIfUsesHdr(false)
3298 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003299 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003300 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003301 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003302 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003303 .execute()
3304 .expectAFenceWasReturned();
3305}
3306
3307TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3308 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3309 verify().ifMixedCompositionIs(false)
3310 .andIfUsesHdr(true)
3311 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003312 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003313 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003314 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315 .execute()
3316 .expectAFenceWasReturned();
3317}
3318
3319struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3320 struct Layer {
3321 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003322 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3323 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003324 }
3325
3326 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003327 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003328 LayerFECompositionState mLayerFEState;
3329 };
3330
3331 OutputComposeSurfacesTest_HandlesProtectedContent() {
3332 mLayer1.mLayerFEState.hasProtectedContent = false;
3333 mLayer2.mLayerFEState.hasProtectedContent = false;
3334
3335 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3336 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3337 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3338 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3339 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3340
3341 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3342
3343 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3344
3345 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003346 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003347 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3348 .WillRepeatedly(Return());
3349 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003350 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003351 .WillRepeatedly(Return(NO_ERROR));
3352 }
3353
3354 Layer mLayer1;
3355 Layer mLayer2;
3356};
3357
3358TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3359 mOutput.mState.isSecure = false;
3360 mLayer2.mLayerFEState.hasProtectedContent = true;
3361 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003362 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3363 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003364
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003365 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003366}
3367
3368TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3369 mOutput.mState.isSecure = true;
3370 mLayer2.mLayerFEState.hasProtectedContent = true;
3371 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3372
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003373 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003374}
3375
3376TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3377 mOutput.mState.isSecure = true;
3378 mLayer2.mLayerFEState.hasProtectedContent = false;
3379 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3380 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3381 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3382 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3383 EXPECT_CALL(*mRenderSurface, setProtected(false));
3384
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003385 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003386}
3387
3388TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3389 mOutput.mState.isSecure = true;
3390 mLayer2.mLayerFEState.hasProtectedContent = true;
3391 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3392
3393 // For this test, we also check the call order of key functions.
3394 InSequence seq;
3395
3396 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3397 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3398 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3399 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3400 EXPECT_CALL(*mRenderSurface, setProtected(true));
3401 // Must happen after setting the protected content state.
3402 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003403 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003405 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406}
3407
3408TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3409 mOutput.mState.isSecure = true;
3410 mLayer2.mLayerFEState.hasProtectedContent = true;
3411 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3412 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3413 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3414
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003415 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003416}
3417
3418TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3419 mOutput.mState.isSecure = true;
3420 mLayer2.mLayerFEState.hasProtectedContent = true;
3421 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3422 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3423 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3424 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3425
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003426 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003427}
3428
3429TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3430 mOutput.mState.isSecure = true;
3431 mLayer2.mLayerFEState.hasProtectedContent = true;
3432 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3433 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3434 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3435 EXPECT_CALL(*mRenderSurface, setProtected(true));
3436
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003437 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003438}
3439
3440TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3441 mOutput.mState.isSecure = true;
3442 mLayer2.mLayerFEState.hasProtectedContent = true;
3443 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3444 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3445 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3446 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3447
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003448 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003449}
3450
3451struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3452 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3453 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3454 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3455 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003456 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003457 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3458 .WillRepeatedly(Return());
3459 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3460 }
3461};
3462
3463TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3464 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3465
3466 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003467 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468
3469 // For this test, we also check the call order of key functions.
3470 InSequence seq;
3471
3472 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003473 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003474
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003475 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3476}
3477
3478struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3479 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3480 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3481 mLayer.layerFEState.backgroundBlurRadius = 10;
3482 mOutput.editState().isEnabled = true;
3483
Snild Dolkow9e217d62020-04-22 15:53:42 +02003484 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003485 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3486 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3487 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003488 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003489 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3490 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3491 .WillRepeatedly(Return(&mLayer.outputLayer));
3492 }
3493
3494 NonInjectedLayer mLayer;
3495 compositionengine::CompositionRefreshArgs mRefreshArgs;
3496};
3497
3498TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3499 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003500 mOutput.updateCompositionState(mRefreshArgs);
3501 mOutput.planComposition();
3502 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003503
3504 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3505 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3506}
3507
3508TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3509 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003510 mOutput.updateCompositionState(mRefreshArgs);
3511 mOutput.planComposition();
3512 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003513
3514 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3515 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003516}
3517
3518/*
3519 * Output::generateClientCompositionRequests()
3520 */
3521
3522struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003523 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003524 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003525 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003526 bool supportsProtectedContent, Region& clearRegion,
3527 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003528 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003529 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003530 }
3531 };
3532
Lloyd Piquea4863342019-12-04 18:45:02 -08003533 struct Layer {
3534 Layer() {
3535 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3536 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003537 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003538 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003539 }
3540
3541 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003542 StrictMock<mock::LayerFE> mLayerFE;
3543 LayerFECompositionState mLayerFEState;
3544 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003545 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003546 };
3547
Lloyd Pique56eba802019-08-28 15:45:25 -07003548 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003549 mOutput.mState.needsFiltering = false;
3550
Lloyd Pique56eba802019-08-28 15:45:25 -07003551 mOutput.setDisplayColorProfileForTest(
3552 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3553 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3554 }
3555
Lloyd Pique56eba802019-08-28 15:45:25 -07003556 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3557 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003558 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003559};
3560
Lloyd Piquea4863342019-12-04 18:45:02 -08003561struct GenerateClientCompositionRequestsTest_ThreeLayers
3562 : public GenerateClientCompositionRequestsTest {
3563 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003564 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3565 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3566 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003567 mOutput.mState.transform =
3568 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3569 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003570 mOutput.mState.needsFiltering = false;
3571 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003572
Lloyd Piquea4863342019-12-04 18:45:02 -08003573 for (size_t i = 0; i < mLayers.size(); i++) {
3574 mLayers[i].mOutputLayerState.clearClientTarget = false;
3575 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3576 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003577 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003578 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003579 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3580 mLayers[i].mLayerSettings.alpha = 1.0f;
3581 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003582
Lloyd Piquea4863342019-12-04 18:45:02 -08003583 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3584 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3585 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3586 .WillRepeatedly(Return(true));
3587 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3588 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003589
Lloyd Piquea4863342019-12-04 18:45:02 -08003590 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3591 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003592
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003593 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003594 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003595
Lloyd Piquea4863342019-12-04 18:45:02 -08003596 static const Rect kDisplayFrame;
3597 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003598 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003599
Lloyd Piquea4863342019-12-04 18:45:02 -08003600 std::array<Layer, 3> mLayers;
3601};
Lloyd Pique56eba802019-08-28 15:45:25 -07003602
Lloyd Piquea4863342019-12-04 18:45:02 -08003603const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3604const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003605const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3606 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003607
Lloyd Piquea4863342019-12-04 18:45:02 -08003608TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3609 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3610 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3611 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003612
Lloyd Piquea4863342019-12-04 18:45:02 -08003613 Region accumClearRegion(Rect(10, 11, 12, 13));
3614 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3615 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003616 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003617 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003618}
3619
Lloyd Piquea4863342019-12-04 18:45:02 -08003620TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3621 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3622 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3623 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3624
3625 Region accumClearRegion(Rect(10, 11, 12, 13));
3626 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3627 accumClearRegion, kDisplayDataspace);
3628 EXPECT_EQ(0u, requests.size());
3629 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3630}
3631
3632TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003633 LayerFE::LayerSettings mShadowSettings;
3634 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003635
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003636 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3637 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3638 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3639 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3640 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3641 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3642 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003643
3644 Region accumClearRegion(Rect(10, 11, 12, 13));
3645 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3646 accumClearRegion, kDisplayDataspace);
3647 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003648 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3649 EXPECT_EQ(mShadowSettings, requests[1]);
3650 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003651
3652 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3653
3654 // Check that a timestamp was set for the layers that generated requests
3655 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3656 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3657 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3658}
3659
3660TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3661 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3662 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3663 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3664 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3665
3666 mLayers[0].mOutputLayerState.clearClientTarget = false;
3667 mLayers[1].mOutputLayerState.clearClientTarget = false;
3668 mLayers[2].mOutputLayerState.clearClientTarget = false;
3669
3670 mLayers[0].mLayerFEState.isOpaque = true;
3671 mLayers[1].mLayerFEState.isOpaque = true;
3672 mLayers[2].mLayerFEState.isOpaque = true;
3673
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003674 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3675 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003676
3677 Region accumClearRegion(Rect(10, 11, 12, 13));
3678 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3679 accumClearRegion, kDisplayDataspace);
3680 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003681 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003682
3683 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3684}
3685
3686TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3687 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3688 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3689 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3690 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3691
3692 mLayers[0].mOutputLayerState.clearClientTarget = true;
3693 mLayers[1].mOutputLayerState.clearClientTarget = true;
3694 mLayers[2].mOutputLayerState.clearClientTarget = true;
3695
3696 mLayers[0].mLayerFEState.isOpaque = false;
3697 mLayers[1].mLayerFEState.isOpaque = false;
3698 mLayers[2].mLayerFEState.isOpaque = false;
3699
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003700 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3701 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003702
3703 Region accumClearRegion(Rect(10, 11, 12, 13));
3704 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3705 accumClearRegion, kDisplayDataspace);
3706 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003707 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003708
3709 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3710}
3711
3712TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003713 // If client composition is performed with some layers set to use device
3714 // composition, device layers after the first layer (device or client) will
3715 // clear the frame buffer if they are opaque and if that layer has a flag
3716 // set to do so. The first layer is skipped as the frame buffer is already
3717 // expected to be clear.
3718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3720 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3721 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003722
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 mLayers[0].mOutputLayerState.clearClientTarget = true;
3724 mLayers[1].mOutputLayerState.clearClientTarget = true;
3725 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003726
Lloyd Piquea4863342019-12-04 18:45:02 -08003727 mLayers[0].mLayerFEState.isOpaque = true;
3728 mLayers[1].mLayerFEState.isOpaque = true;
3729 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003730 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003731 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003732
3733 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3734 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003735 false, /* needs filtering */
3736 false, /* secure */
3737 false, /* supports protected content */
3738 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003739 kDisplayViewport,
3740 kDisplayDataspace,
3741 false /* realContentIsVisible */,
3742 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003743 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003744 };
3745 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3746 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003747 false, /* needs filtering */
3748 false, /* secure */
3749 false, /* supports protected content */
3750 accumClearRegion,
3751 kDisplayViewport,
3752 kDisplayDataspace,
3753 true /* realContentIsVisible */,
3754 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003755 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003756 };
3757
3758 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3759 mBlackoutSettings.source.buffer.buffer = nullptr;
3760 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3761 mBlackoutSettings.alpha = 0.f;
3762 mBlackoutSettings.disableBlending = true;
3763
3764 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3765 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3766 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3767 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3768
Lloyd Piquea4863342019-12-04 18:45:02 -08003769 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3770 accumClearRegion, kDisplayDataspace);
3771 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003772
Lloyd Piquea4863342019-12-04 18:45:02 -08003773 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003774 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003775
Vishnu Nair9b079a22020-01-21 14:36:08 -08003776 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003777
Lloyd Piquea4863342019-12-04 18:45:02 -08003778 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3779}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003780
Lloyd Piquea4863342019-12-04 18:45:02 -08003781TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3782 clippedVisibleRegionUsedToGenerateRequest) {
3783 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3784 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3785 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003786
Lloyd Piquea4863342019-12-04 18:45:02 -08003787 Region accumClearRegion(Rect(10, 11, 12, 13));
3788
3789 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3790 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003791 false, /* needs filtering */
3792 false, /* secure */
3793 false, /* supports protected content */
3794 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003795 kDisplayViewport,
3796 kDisplayDataspace,
3797 true /* realContentIsVisible */,
3798 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003799 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003800 };
3801 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3802 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003803 false, /* needs filtering */
3804 false, /* secure */
3805 false, /* supports protected content */
3806 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003807 kDisplayViewport,
3808 kDisplayDataspace,
3809 true /* realContentIsVisible */,
3810 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003811 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003812 };
3813 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3814 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003815 false, /* needs filtering */
3816 false, /* secure */
3817 false, /* supports protected content */
3818 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003819 kDisplayViewport,
3820 kDisplayDataspace,
3821 true /* realContentIsVisible */,
3822 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003823 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003824 };
3825
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003826 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3827 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3828 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3829 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3830 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3831 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003832
3833 static_cast<void>(
3834 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3835 accumClearRegion, kDisplayDataspace));
3836}
3837
3838TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3839 perLayerNeedsFilteringUsedToGenerateRequests) {
3840 mOutput.mState.needsFiltering = false;
3841 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3842
3843 Region accumClearRegion(Rect(10, 11, 12, 13));
3844
3845 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3846 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003847 true, /* needs filtering */
3848 false, /* secure */
3849 false, /* supports protected content */
3850 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003851 kDisplayViewport,
3852 kDisplayDataspace,
3853 true /* realContentIsVisible */,
3854 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003855 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003856 };
3857 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3858 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003859 false, /* needs filtering */
3860 false, /* secure */
3861 false, /* supports protected content */
3862 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003863 kDisplayViewport,
3864 kDisplayDataspace,
3865 true /* realContentIsVisible */,
3866 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003867 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003868 };
3869 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3870 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003871 false, /* needs filtering */
3872 false, /* secure */
3873 false, /* supports protected content */
3874 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003875 kDisplayViewport,
3876 kDisplayDataspace,
3877 true /* realContentIsVisible */,
3878 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003879 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003880 };
3881
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003882 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3883 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3884 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3885 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3886 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3887 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003888
3889 static_cast<void>(
3890 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3891 accumClearRegion, kDisplayDataspace));
3892}
3893
3894TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3895 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3896 mOutput.mState.needsFiltering = true;
3897 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3898
3899 Region accumClearRegion(Rect(10, 11, 12, 13));
3900
3901 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3902 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003903 true, /* needs filtering */
3904 false, /* secure */
3905 false, /* supports protected content */
3906 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003907 kDisplayViewport,
3908 kDisplayDataspace,
3909 true /* realContentIsVisible */,
3910 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003911 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003912
Lloyd Piquea4863342019-12-04 18:45:02 -08003913 };
3914 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3915 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003916 true, /* needs filtering */
3917 false, /* secure */
3918 false, /* supports protected content */
3919 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003920 kDisplayViewport,
3921 kDisplayDataspace,
3922 true /* realContentIsVisible */,
3923 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003924 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003925 };
3926 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3927 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003928 true, /* needs filtering */
3929 false, /* secure */
3930 false, /* supports protected content */
3931 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003932 kDisplayViewport,
3933 kDisplayDataspace,
3934 true /* realContentIsVisible */,
3935 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003936 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003937 };
3938
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003939 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3940 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3941 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3942 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3943 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3944 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003945
3946 static_cast<void>(
3947 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3948 accumClearRegion, kDisplayDataspace));
3949}
3950
3951TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3952 wholeOutputSecurityUsedToGenerateRequests) {
3953 mOutput.mState.isSecure = true;
3954
3955 Region accumClearRegion(Rect(10, 11, 12, 13));
3956
3957 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3958 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003959 false, /* needs filtering */
3960 true, /* secure */
3961 false, /* supports protected content */
3962 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003963 kDisplayViewport,
3964 kDisplayDataspace,
3965 true /* realContentIsVisible */,
3966 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003967 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003968 };
3969 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3970 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003971 false, /* needs filtering */
3972 true, /* secure */
3973 false, /* supports protected content */
3974 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003975 kDisplayViewport,
3976 kDisplayDataspace,
3977 true /* realContentIsVisible */,
3978 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003979 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003980 };
3981 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3982 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003983 false, /* needs filtering */
3984 true, /* secure */
3985 false, /* supports protected content */
3986 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003987 kDisplayViewport,
3988 kDisplayDataspace,
3989 true /* realContentIsVisible */,
3990 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003991 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003992 };
3993
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003994 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3995 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3996 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3997 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3998 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3999 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004000
4001 static_cast<void>(
4002 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4003 accumClearRegion, kDisplayDataspace));
4004}
4005
4006TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4007 protectedContentSupportUsedToGenerateRequests) {
4008 Region accumClearRegion(Rect(10, 11, 12, 13));
4009
4010 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4011 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004012 false, /* needs filtering */
4013 false, /* secure */
4014 true, /* supports protected content */
4015 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004016 kDisplayViewport,
4017 kDisplayDataspace,
4018 true /* realContentIsVisible */,
4019 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004020 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004021 };
4022 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4023 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004024 false, /* needs filtering */
4025 false, /* secure */
4026 true, /* supports protected content */
4027 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004028 kDisplayViewport,
4029 kDisplayDataspace,
4030 true /* realContentIsVisible */,
4031 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004032 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004033 };
4034 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4035 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004036 false, /* needs filtering */
4037 false, /* secure */
4038 true, /* supports protected content */
4039 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004040 kDisplayViewport,
4041 kDisplayDataspace,
4042 true /* realContentIsVisible */,
4043 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004044 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004045 };
4046
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004047 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
4048 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4049 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
4050 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4051 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
4052 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004053
4054 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4055 accumClearRegion,
4056 kDisplayDataspace));
4057}
4058
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004059TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004060 InjectedLayer layer1;
4061 InjectedLayer layer2;
4062 InjectedLayer layer3;
4063
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004064 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004065 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004066 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004067 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004068 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004069 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08004070 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004071
Lloyd Piquede196652020-01-22 17:29:58 -08004072 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004073
Lloyd Piquede196652020-01-22 17:29:58 -08004074 injectOutputLayer(layer1);
4075 injectOutputLayer(layer2);
4076 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004077
4078 mOutput->editState().isEnabled = true;
4079
4080 CompositionRefreshArgs args;
4081 args.updatingGeometryThisFrame = false;
4082 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004083 mOutput->updateCompositionState(args);
4084 mOutput->planComposition();
4085 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004086}
4087
Lucas Dupinc3800b82020-10-02 16:24:48 -07004088TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4089 InjectedLayer layer1;
4090 InjectedLayer layer2;
4091 InjectedLayer layer3;
4092
4093 // Layer requesting blur, or below, should request client composition.
4094 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4095 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
4096 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4097 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
4098 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4099 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
4100
4101 BlurRegion region;
4102 layer2.layerFEState.blurRegions.push_back(region);
4103
4104 injectOutputLayer(layer1);
4105 injectOutputLayer(layer2);
4106 injectOutputLayer(layer3);
4107
4108 mOutput->editState().isEnabled = true;
4109
4110 CompositionRefreshArgs args;
4111 args.updatingGeometryThisFrame = false;
4112 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004113 mOutput->updateCompositionState(args);
4114 mOutput->planComposition();
4115 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004116}
4117
Lloyd Piquea4863342019-12-04 18:45:02 -08004118TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4119 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4120 // one layer on the left covering the left side of the output, and one layer
4121 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004122
4123 const Rect kPortraitFrame(0, 0, 1000, 2000);
4124 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004125 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004126 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004127 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004128
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004129 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4130 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4131 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004132 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4133 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004134 mOutput.mState.needsFiltering = false;
4135 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004136
Lloyd Piquea4863342019-12-04 18:45:02 -08004137 Layer leftLayer;
4138 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004139
Lloyd Piquea4863342019-12-04 18:45:02 -08004140 leftLayer.mOutputLayerState.clearClientTarget = false;
4141 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4142 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004143 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004144
Lloyd Piquea4863342019-12-04 18:45:02 -08004145 rightLayer.mOutputLayerState.clearClientTarget = false;
4146 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4147 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004148 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004149
4150 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4151 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4152 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4153 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4154 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4155
4156 Region accumClearRegion(Rect(10, 11, 12, 13));
4157
4158 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4159 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004160 false, /* needs filtering */
4161 true, /* secure */
4162 true, /* supports protected content */
4163 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004164 kPortraitViewport,
4165 kOutputDataspace,
4166 true /* realContentIsVisible */,
4167 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004168 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004169 };
4170
4171 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4172 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004173 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4174 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004175
4176 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4177 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004178 false, /* needs filtering */
4179 true, /* secure */
4180 true, /* supports protected content */
4181 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004182 kPortraitViewport,
4183 kOutputDataspace,
4184 true /* realContentIsVisible */,
4185 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004186 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004187 };
4188
4189 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4190 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004191 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4192 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004193
4194 constexpr bool supportsProtectedContent = true;
4195 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4196 accumClearRegion, kOutputDataspace);
4197 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004198 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4199 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004200}
4201
Vishnu Naira483b4a2019-12-12 15:07:52 -08004202TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4203 shadowRegionOnlyVisibleSkipsContentComposition) {
4204 const Rect kContentWithShadow(40, 40, 70, 90);
4205 const Rect kContent(50, 50, 60, 80);
4206 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4207 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4208
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004209 Region accumClearRegion(Rect(10, 11, 12, 13));
4210 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4211 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004212 false, /* needs filtering */
4213 false, /* secure */
4214 false, /* supports protected content */
4215 accumClearRegion,
4216 kDisplayViewport,
4217 kDisplayDataspace,
4218 false /* realContentIsVisible */,
4219 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004220 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004221 };
4222
Vishnu Nair9b079a22020-01-21 14:36:08 -08004223 LayerFE::LayerSettings mShadowSettings;
4224 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004225
4226 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4227 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4228
4229 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4230 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004231 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4232 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004233
Vishnu Naira483b4a2019-12-12 15:07:52 -08004234 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4235 accumClearRegion, kDisplayDataspace);
4236 ASSERT_EQ(1u, requests.size());
4237
Vishnu Nair9b079a22020-01-21 14:36:08 -08004238 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004239}
4240
4241TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4242 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4243 const Rect kContentWithShadow(40, 40, 70, 90);
4244 const Rect kContent(50, 50, 60, 80);
4245 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4246 const Region kPartialContentWithPartialShadowRegion =
4247 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4248
Vishnu Nair9b079a22020-01-21 14:36:08 -08004249 LayerFE::LayerSettings mShadowSettings;
4250 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004251
4252 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4253 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4254
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004255 Region accumClearRegion(Rect(10, 11, 12, 13));
4256 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4257 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004258 false, /* needs filtering */
4259 false, /* secure */
4260 false, /* supports protected content */
4261 accumClearRegion,
4262 kDisplayViewport,
4263 kDisplayDataspace,
4264 true /* realContentIsVisible */,
4265 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004266 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004267 };
4268
Vishnu Naira483b4a2019-12-12 15:07:52 -08004269 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4270 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004271 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4272 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4273 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004274
Vishnu Naira483b4a2019-12-12 15:07:52 -08004275 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4276 accumClearRegion, kDisplayDataspace);
4277 ASSERT_EQ(2u, requests.size());
4278
Vishnu Nair9b079a22020-01-21 14:36:08 -08004279 EXPECT_EQ(mShadowSettings, requests[0]);
4280 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004281}
4282
Lloyd Pique32cbe282018-10-19 13:09:22 -07004283} // namespace
4284} // namespace android::compositionengine