blob: e80100cc6e20f633dd2590a9a6bd7eadd1d3ab5b [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
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070027#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070028#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <ui/Rect.h>
30#include <ui/Region.h>
31
Alec Mouria90a5702021-04-16 16:36:21 +000032#include <cmath>
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"
Alec Mouria90a5702021-04-16 16:36:21 +000037#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070038
39namespace android::compositionengine {
40namespace {
41
Lloyd Pique56eba802019-08-28 15:45:25 -070042using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080043using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080044using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080045using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080046using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080047using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080048using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080049using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080050using testing::Invoke;
51using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080052using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080053using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080054using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080055using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070056using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070057using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080058using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070059using testing::StrictMock;
60
Lloyd Pique56eba802019-08-28 15:45:25 -070061constexpr auto TR_IDENT = 0u;
62constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080063constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070064
Lloyd Pique3eb1b212019-03-07 21:15:40 -080065const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080066const mat4 kNonIdentityHalf = mat4() * 0.5f;
67const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080068
Lloyd Pique17ca7422019-11-14 14:24:10 -080069constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
70 static_cast<OutputColorSetting>(0x100);
71
Lloyd Piquefaa3f192019-11-14 14:05:09 -080072struct OutputPartialMockBase : public impl::Output {
73 // compositionengine::Output overrides
74 const OutputCompositionState& getState() const override { return mState; }
75 OutputCompositionState& editState() override { return mState; }
76
77 // Use mocks for all the remaining virtual functions
78 // not implemented by the base implementation class.
79 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
80 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080081 MOCK_METHOD2(ensureOutputLayer,
82 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080083 MOCK_METHOD0(finalizePendingOutputLayers, void());
84 MOCK_METHOD0(clearOutputLayers, void());
85 MOCK_CONST_METHOD1(dumpState, void(std::string&));
86 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080087 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080088 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
89
90 impl::OutputCompositionState mState;
91};
92
Lloyd Piquede196652020-01-22 17:29:58 -080093struct InjectedLayer {
94 InjectedLayer() {
95 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
96 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
97 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
98
99 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800100 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
101 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800102 }
103
104 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
105 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
106 LayerFECompositionState layerFEState;
107 impl::OutputLayerCompositionState outputLayerState;
108};
109
110struct NonInjectedLayer {
111 NonInjectedLayer() {
112 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
113 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
114 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
115
116 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800117 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
118 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800119 }
120
121 mock::OutputLayer outputLayer;
122 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
123 LayerFECompositionState layerFEState;
124 impl::OutputLayerCompositionState outputLayerState;
125};
126
Lloyd Pique66d68602019-02-13 14:23:31 -0800127struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700128 class Output : public impl::Output {
129 public:
130 using impl::Output::injectOutputLayerForTest;
131 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
132 };
133
134 static std::shared_ptr<Output> createOutput(
135 const compositionengine::CompositionEngine& compositionEngine) {
136 return impl::createOutputTemplated<Output>(compositionEngine);
137 }
138
Lloyd Pique31cb2942018-10-19 17:23:03 -0700139 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700140 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700141 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700142 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800143
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200144 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700145 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700146
Lloyd Piquede196652020-01-22 17:29:58 -0800147 void injectOutputLayer(InjectedLayer& layer) {
148 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
149 }
150
151 void injectNullOutputLayer() {
152 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
153 }
154
Lloyd Piqueef958122019-02-05 18:00:12 -0800155 static const Rect kDefaultDisplaySize;
156
Lloyd Pique32cbe282018-10-19 13:09:22 -0700157 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700158 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700159 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700160 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161};
162
Lloyd Piqueef958122019-02-05 18:00:12 -0800163const Rect OutputTest::kDefaultDisplaySize{100, 200};
164
Lloyd Pique17ca7422019-11-14 14:24:10 -0800165using ColorProfile = compositionengine::Output::ColorProfile;
166
167void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
168 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
169 toString(profile.mode).c_str(), profile.mode,
170 toString(profile.dataspace).c_str(), profile.dataspace,
171 toString(profile.renderIntent).c_str(), profile.renderIntent,
172 toString(profile.colorSpaceAgnosticDataspace).c_str(),
173 profile.colorSpaceAgnosticDataspace);
174}
175
176// Checks for a ColorProfile match
177MATCHER_P(ColorProfileEq, expected, "") {
178 std::string buf;
179 buf.append("ColorProfiles are not equal\n");
180 dumpColorProfile(expected, buf, "expected value");
181 dumpColorProfile(arg, buf, "actual value");
182 *result_listener << buf;
183
184 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
185 (expected.renderIntent == arg.renderIntent) &&
186 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
187}
188
Lloyd Pique66d68602019-02-13 14:23:31 -0800189/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700190 * Basic construction
191 */
192
Lloyd Pique31cb2942018-10-19 17:23:03 -0700193TEST_F(OutputTest, canInstantiateOutput) {
194 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700195 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700196 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
197
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700198 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700199
200 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700201 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700202
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700203 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
204
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700207
Lloyd Pique66d68602019-02-13 14:23:31 -0800208/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700209 * Output::setCompositionEnabled()
210 */
211
212TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700213 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700215 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700216
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 EXPECT_TRUE(mOutput->getState().isEnabled);
218 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219}
220
221TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 EXPECT_TRUE(mOutput->getState().isEnabled);
227 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228}
229
230TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 EXPECT_FALSE(mOutput->getState().isEnabled);
236 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237}
238
Lloyd Pique66d68602019-02-13 14:23:31 -0800239/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240 * Output::setProjection()
241 */
242
Marin Shalamanov209ae612020-10-01 00:17:39 +0200243TEST_F(OutputTest, setProjectionWorks) {
244 const Rect displayRect{0, 0, 1000, 2000};
245 mOutput->editState().displaySpace.bounds = displayRect;
246 mOutput->editState().framebufferSpace.bounds = displayRect;
247
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200248 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200249 const Rect frame{50, 60, 100, 100};
250 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700251
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200252 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700253
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200254 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200255 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
256 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200257
258 const auto state = mOutput->getState();
259 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
260 EXPECT_EQ(viewport, state.layerStackSpace.content);
261 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
262
263 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
264 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
265 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
266
267 EXPECT_EQ(displayRect, state.displaySpace.bounds);
268 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
269 EXPECT_EQ(orientation, state.displaySpace.orientation);
270
271 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
272 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
273 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
274
275 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700276
277 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200278}
279
280TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
281 const Rect displayRect{0, 0, 1000, 2000};
282 const Rect framebufferRect{0, 0, 500, 1000};
283 mOutput->editState().displaySpace.bounds = displayRect;
284 mOutput->editState().framebufferSpace.bounds = framebufferRect;
285
286 const ui::Rotation orientation = ui::ROTATION_90;
287 const Rect frame{50, 60, 100, 100};
288 const Rect viewport{10, 20, 30, 40};
289
290 mOutput->setProjection(orientation, viewport, frame);
291
292 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
293 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
294 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
295
296 const auto state = mOutput->getState();
297 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
298 EXPECT_EQ(viewport, state.layerStackSpace.content);
299 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
300
301 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
302 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
303 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
304
305 EXPECT_EQ(displayRect, state.displaySpace.bounds);
306 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
307 EXPECT_EQ(orientation, state.displaySpace.orientation);
308
309 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
310 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
311 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
312
313 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700314}
315
Lloyd Pique66d68602019-02-13 14:23:31 -0800316/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200317 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700318 */
319
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200320TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
321 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
322 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
323 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
324 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
325 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
326 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
327 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
328 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
329 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
330 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700331
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200332 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700333
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200334 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700335
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200336 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700337
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200338 const auto state = mOutput->getState();
339
340 const Rect displayRect(newDisplaySize);
341 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
342 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
343 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200344
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200345 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200346 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200347
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200348 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200349 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200350
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200351 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200352 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
353
354 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
355
356 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700357}
358
Lloyd Pique66d68602019-02-13 14:23:31 -0800359/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700360 * Output::setLayerStackFilter()
361 */
362
363TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700364 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700365 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700366
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 EXPECT_TRUE(mOutput->getState().layerStackInternal);
368 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700369
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700370 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700371}
372
Lloyd Pique66d68602019-02-13 14:23:31 -0800373/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700374 * Output::setColorTransform
375 */
376
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800377TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700378 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700379
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800380 // If no colorTransformMatrix is set the update should be skipped.
381 CompositionRefreshArgs refreshArgs;
382 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700383
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700384 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700385
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800386 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700387 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800388
389 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800391}
Lloyd Piqueef958122019-02-05 18:00:12 -0800392
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800393TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700394 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700395
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800396 // Attempting to set the same colorTransformMatrix that is already set should
397 // also skip the update.
398 CompositionRefreshArgs refreshArgs;
399 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700400
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700401 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700402
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800403 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700404 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800405
406 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700407 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800408}
409
410TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700411 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800412
413 // Setting a different colorTransformMatrix should perform the update.
414 CompositionRefreshArgs refreshArgs;
415 refreshArgs.colorTransformMatrix = kIdentity;
416
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700417 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800418
419 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700420 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800421
422 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700423 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800424}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700425
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800426TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700427 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700428
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800429 // Setting a different colorTransformMatrix should perform the update.
430 CompositionRefreshArgs refreshArgs;
431 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700432
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700433 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800434
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700436 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437
438 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700439 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440}
441
442TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800444
445 // Setting a different colorTransformMatrix should perform the update.
446 CompositionRefreshArgs refreshArgs;
447 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
448
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450
451 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700452 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453
454 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456}
457
Lloyd Pique66d68602019-02-13 14:23:31 -0800458/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800459 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460 */
461
Lloyd Pique17ca7422019-11-14 14:24:10 -0800462using OutputSetColorProfileTest = OutputTest;
463
464TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800465 using ColorProfile = Output::ColorProfile;
466
Lloyd Piquef5275482019-01-29 18:42:42 -0800467 EXPECT_CALL(*mDisplayColorProfile,
468 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
469 ui::Dataspace::UNKNOWN))
470 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800471 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700472
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
474 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
475 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
478 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
479 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
480 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800481
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800483}
484
Lloyd Pique17ca7422019-11-14 14:24:10 -0800485TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800486 using ColorProfile = Output::ColorProfile;
487
Lloyd Piquef5275482019-01-29 18:42:42 -0800488 EXPECT_CALL(*mDisplayColorProfile,
489 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
490 ui::Dataspace::UNKNOWN))
491 .WillOnce(Return(ui::Dataspace::UNKNOWN));
492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
494 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
495 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
496 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800497
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
499 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
500 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800501
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700503}
504
Lloyd Pique66d68602019-02-13 14:23:31 -0800505/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700506 * Output::setRenderSurface()
507 */
508
509TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
510 const ui::Size newDisplaySize{640, 480};
511
512 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
513 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
514
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700516
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200517 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700518}
519
Lloyd Pique66d68602019-02-13 14:23:31 -0800520/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000521 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700522 */
523
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000524TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
525 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200526 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700527 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700528
529 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700530 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700531
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000532 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533 }
534}
535
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000536TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
537 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200538 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700539 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700540
541 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700543
544 // The dirtyRegion should be clipped to the display bounds.
545 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
546 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700547}
548
Lloyd Pique66d68602019-02-13 14:23:31 -0800549/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800550 * Output::belongsInOutput()
551 */
552
553TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
554 const uint32_t layerStack1 = 123u;
555 const uint32_t layerStack2 = 456u;
556
557 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800559
Lloyd Piquec6687342019-03-07 21:34:57 -0800560 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
562 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800563
Lloyd Piqueef36b002019-01-23 17:52:04 -0800564 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700565 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
566 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
567 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
568 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800569
570 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700571 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800572
573 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
575 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
576 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
577 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800578}
579
Lloyd Piquede196652020-01-22 17:29:58 -0800580TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
581 NonInjectedLayer layer;
582 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800583
Lloyd Piquede196652020-01-22 17:29:58 -0800584 // If the layer has no composition state, it does not belong to any output.
585 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
586 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
587}
588
589TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
590 NonInjectedLayer layer;
591 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800592
593 const uint32_t layerStack1 = 123u;
594 const uint32_t layerStack2 = 456u;
595
596 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700597 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800598
Lloyd Pique66c20c42019-03-07 21:44:02 -0800599 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800600 layer.layerFEState.layerStackId = std::nullopt;
601 layer.layerFEState.internalOnly = false;
602 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800603
Lloyd Piquede196652020-01-22 17:29:58 -0800604 layer.layerFEState.layerStackId = std::nullopt;
605 layer.layerFEState.internalOnly = true;
606 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800607
608 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800609 layer.layerFEState.layerStackId = layerStack1;
610 layer.layerFEState.internalOnly = false;
611 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800612
Lloyd Piquede196652020-01-22 17:29:58 -0800613 layer.layerFEState.layerStackId = layerStack1;
614 layer.layerFEState.internalOnly = true;
615 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800616
Lloyd Piquede196652020-01-22 17:29:58 -0800617 layer.layerFEState.layerStackId = layerStack2;
618 layer.layerFEState.internalOnly = true;
619 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800620
Lloyd Piquede196652020-01-22 17:29:58 -0800621 layer.layerFEState.layerStackId = layerStack2;
622 layer.layerFEState.internalOnly = false;
623 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800624
625 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700626 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800627
Lloyd Pique66c20c42019-03-07 21:44:02 -0800628 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800629 layer.layerFEState.layerStackId = layerStack1;
630 layer.layerFEState.internalOnly = false;
631 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800632
Lloyd Piquede196652020-01-22 17:29:58 -0800633 layer.layerFEState.layerStackId = layerStack1;
634 layer.layerFEState.internalOnly = true;
635 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800636
Lloyd Piquede196652020-01-22 17:29:58 -0800637 layer.layerFEState.layerStackId = layerStack2;
638 layer.layerFEState.internalOnly = true;
639 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800640
Lloyd Piquede196652020-01-22 17:29:58 -0800641 layer.layerFEState.layerStackId = layerStack2;
642 layer.layerFEState.internalOnly = false;
643 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800644}
645
Lloyd Pique66d68602019-02-13 14:23:31 -0800646/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800647 * Output::getOutputLayerForLayer()
648 */
649
650TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800651 InjectedLayer layer1;
652 InjectedLayer layer2;
653 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800654
Lloyd Piquede196652020-01-22 17:29:58 -0800655 injectOutputLayer(layer1);
656 injectNullOutputLayer();
657 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800658
659 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800660 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
661 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800662
663 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800664 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
665 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
666 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800667
668 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800669 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
670 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
671 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800672}
673
Lloyd Pique66d68602019-02-13 14:23:31 -0800674/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800675 * Output::setReleasedLayers()
676 */
677
678using OutputSetReleasedLayersTest = OutputTest;
679
680TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
681 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
682 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
683 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
684
685 Output::ReleasedLayers layers;
686 layers.push_back(layer1FE);
687 layers.push_back(layer2FE);
688 layers.push_back(layer3FE);
689
690 mOutput->setReleasedLayers(std::move(layers));
691
692 const auto& setLayers = mOutput->getReleasedLayersForTest();
693 ASSERT_EQ(3u, setLayers.size());
694 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
695 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
696 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
697}
698
699/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800700 * Output::updateLayerStateFromFE()
701 */
702
Lloyd Piquede196652020-01-22 17:29:58 -0800703using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800704
705TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
706 CompositionRefreshArgs refreshArgs;
707
708 mOutput->updateLayerStateFromFE(refreshArgs);
709}
710
Lloyd Piquede196652020-01-22 17:29:58 -0800711TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
712 InjectedLayer layer1;
713 InjectedLayer layer2;
714 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800715
Lloyd Piquede196652020-01-22 17:29:58 -0800716 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
717 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
718 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
719
720 injectOutputLayer(layer1);
721 injectOutputLayer(layer2);
722 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800723
724 CompositionRefreshArgs refreshArgs;
725 refreshArgs.updatingGeometryThisFrame = false;
726
727 mOutput->updateLayerStateFromFE(refreshArgs);
728}
729
Lloyd Piquede196652020-01-22 17:29:58 -0800730TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
731 InjectedLayer layer1;
732 InjectedLayer layer2;
733 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800734
Lloyd Piquede196652020-01-22 17:29:58 -0800735 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
736 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
737 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
738
739 injectOutputLayer(layer1);
740 injectOutputLayer(layer2);
741 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800742
743 CompositionRefreshArgs refreshArgs;
744 refreshArgs.updatingGeometryThisFrame = true;
745
746 mOutput->updateLayerStateFromFE(refreshArgs);
747}
748
749/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800750 * Output::updateAndWriteCompositionState()
751 */
752
Lloyd Piquede196652020-01-22 17:29:58 -0800753using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800754
755TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
756 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800757
758 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800759 mOutput->updateCompositionState(args);
760 mOutput->planComposition();
761 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800762}
763
Lloyd Piqueef63b612019-11-14 13:19:56 -0800764TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800765 InjectedLayer layer1;
766 InjectedLayer layer2;
767 InjectedLayer layer3;
768
Lloyd Piqueef63b612019-11-14 13:19:56 -0800769 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800770
Lloyd Piquede196652020-01-22 17:29:58 -0800771 injectOutputLayer(layer1);
772 injectOutputLayer(layer2);
773 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800774
775 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800776 mOutput->updateCompositionState(args);
777 mOutput->planComposition();
778 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800779}
780
781TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800782 InjectedLayer layer1;
783 InjectedLayer layer2;
784 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800785
Snild Dolkow9e217d62020-04-22 15:53:42 +0200786 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800787 EXPECT_CALL(*layer1.outputLayer,
788 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200789 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800790 EXPECT_CALL(*layer2.outputLayer,
791 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200792 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800793 EXPECT_CALL(*layer3.outputLayer,
794 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800795
796 injectOutputLayer(layer1);
797 injectOutputLayer(layer2);
798 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800799
800 mOutput->editState().isEnabled = true;
801
802 CompositionRefreshArgs args;
803 args.updatingGeometryThisFrame = false;
804 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200805 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800806 mOutput->updateCompositionState(args);
807 mOutput->planComposition();
808 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800809}
810
811TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800812 InjectedLayer layer1;
813 InjectedLayer layer2;
814 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800815
Snild Dolkow9e217d62020-04-22 15:53:42 +0200816 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800817 EXPECT_CALL(*layer1.outputLayer,
818 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200819 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800820 EXPECT_CALL(*layer2.outputLayer,
821 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200822 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800823 EXPECT_CALL(*layer3.outputLayer,
824 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800825
826 injectOutputLayer(layer1);
827 injectOutputLayer(layer2);
828 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800829
830 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800831
832 CompositionRefreshArgs args;
833 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800834 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800835 mOutput->updateCompositionState(args);
836 mOutput->planComposition();
837 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800838}
839
840TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800841 InjectedLayer layer1;
842 InjectedLayer layer2;
843 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800844
Snild Dolkow9e217d62020-04-22 15:53:42 +0200845 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800846 EXPECT_CALL(*layer1.outputLayer,
847 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200848 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800849 EXPECT_CALL(*layer2.outputLayer,
850 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200851 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800852 EXPECT_CALL(*layer3.outputLayer,
853 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800854
855 injectOutputLayer(layer1);
856 injectOutputLayer(layer2);
857 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800858
859 mOutput->editState().isEnabled = true;
860
861 CompositionRefreshArgs args;
862 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800863 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800864 mOutput->updateCompositionState(args);
865 mOutput->planComposition();
866 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800867}
868
869/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800870 * Output::prepareFrame()
871 */
872
873struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800874 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800875 // Sets up the helper functions called by the function under test to use
876 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800877 MOCK_METHOD0(chooseCompositionStrategy, void());
878 };
879
880 OutputPrepareFrameTest() {
881 mOutput.setDisplayColorProfileForTest(
882 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
883 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
884 }
885
886 StrictMock<mock::CompositionEngine> mCompositionEngine;
887 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
888 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700889 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800890};
891
892TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
893 mOutput.editState().isEnabled = false;
894
895 mOutput.prepareFrame();
896}
897
898TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
899 mOutput.editState().isEnabled = true;
900 mOutput.editState().usesClientComposition = false;
901 mOutput.editState().usesDeviceComposition = true;
902
903 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Dan Stoza47437bb2021-01-15 16:21:07 -0800904 if (mOutput.plannerEnabled()) {
905 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
906 }
Lloyd Pique66d68602019-02-13 14:23:31 -0800907 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
908
909 mOutput.prepareFrame();
910}
911
912// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
913// base chooseCompositionStrategy() is invoked.
914TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700915 mOutput->editState().isEnabled = true;
916 mOutput->editState().usesClientComposition = false;
917 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800918
919 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
920
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700921 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800922
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700923 EXPECT_TRUE(mOutput->getState().usesClientComposition);
924 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800925}
926
Lloyd Pique56eba802019-08-28 15:45:25 -0700927/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800928 * Output::prepare()
929 */
930
931struct OutputPrepareTest : public testing::Test {
932 struct OutputPartialMock : public OutputPartialMockBase {
933 // Sets up the helper functions called by the function under test to use
934 // mock implementations.
935 MOCK_METHOD2(rebuildLayerStacks,
936 void(const compositionengine::CompositionRefreshArgs&,
937 compositionengine::LayerFESet&));
938 };
939
940 StrictMock<OutputPartialMock> mOutput;
941 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800942 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800943};
944
945TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
946 InSequence seq;
947 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
948
949 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
950}
951
952/*
953 * Output::rebuildLayerStacks()
954 */
955
956struct OutputRebuildLayerStacksTest : public testing::Test {
957 struct OutputPartialMock : public OutputPartialMockBase {
958 // Sets up the helper functions called by the function under test to use
959 // mock implementations.
960 MOCK_METHOD2(collectVisibleLayers,
961 void(const compositionengine::CompositionRefreshArgs&,
962 compositionengine::Output::CoverageState&));
963 };
964
965 OutputRebuildLayerStacksTest() {
966 mOutput.mState.isEnabled = true;
967 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200968 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800969
970 mRefreshArgs.updatingOutputGeometryThisFrame = true;
971
972 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
973
974 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
975 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
976 }
977
978 void setTestCoverageValues(const CompositionRefreshArgs&,
979 compositionengine::Output::CoverageState& state) {
980 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
981 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
982 state.dirtyRegion = mCoverageDirtyRegionToSet;
983 }
984
985 static const ui::Transform kIdentityTransform;
986 static const ui::Transform kRotate90Transform;
987 static const Rect kOutputBounds;
988
989 StrictMock<OutputPartialMock> mOutput;
990 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800991 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800992 Region mCoverageAboveCoveredLayersToSet;
993 Region mCoverageAboveOpaqueLayersToSet;
994 Region mCoverageDirtyRegionToSet;
995};
996
997const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
998const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
999const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1000
1001TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1002 mOutput.mState.isEnabled = false;
1003
1004 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1005}
1006
1007TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1008 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1009
1010 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1011}
1012
1013TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1014 mOutput.mState.transform = kIdentityTransform;
1015
1016 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1017
1018 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1019
1020 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1021}
1022
1023TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1024 mOutput.mState.transform = kIdentityTransform;
1025
1026 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1027
1028 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1029
1030 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1031}
1032
1033TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1034 mOutput.mState.transform = kRotate90Transform;
1035
1036 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1037
1038 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1039
1040 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1041}
1042
1043TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1044 mOutput.mState.transform = kRotate90Transform;
1045
1046 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1047
1048 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1049
1050 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1051}
1052
1053TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1054 mOutput.mState.transform = kIdentityTransform;
1055 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1056
1057 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1058
1059 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1060
1061 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1062}
1063
1064TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1065 mOutput.mState.transform = kRotate90Transform;
1066 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1067
1068 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1069
1070 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1071
1072 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1073}
1074
1075/*
1076 * Output::collectVisibleLayers()
1077 */
1078
Lloyd Pique1ef93222019-11-21 16:41:53 -08001079struct OutputCollectVisibleLayersTest : public testing::Test {
1080 struct OutputPartialMock : public OutputPartialMockBase {
1081 // Sets up the helper functions called by the function under test to use
1082 // mock implementations.
1083 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001084 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001085 compositionengine::Output::CoverageState&));
1086 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1087 MOCK_METHOD0(finalizePendingOutputLayers, void());
1088 };
1089
1090 struct Layer {
1091 Layer() {
1092 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1093 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1094 }
1095
1096 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001097 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001098 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001099 };
1100
1101 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001102 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001103 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1104 .WillRepeatedly(Return(&mLayer1.outputLayer));
1105 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1106 .WillRepeatedly(Return(&mLayer2.outputLayer));
1107 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1108 .WillRepeatedly(Return(&mLayer3.outputLayer));
1109
Lloyd Piquede196652020-01-22 17:29:58 -08001110 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1111 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1112 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001113 }
1114
1115 StrictMock<OutputPartialMock> mOutput;
1116 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001117 LayerFESet mGeomSnapshots;
1118 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001119 Layer mLayer1;
1120 Layer mLayer2;
1121 Layer mLayer3;
1122};
1123
1124TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1125 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001126 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001127
1128 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1129 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1130
1131 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1132}
1133
1134TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1135 // Enforce a call order sequence for this test.
1136 InSequence seq;
1137
1138 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001139 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1140 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1141 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001142
1143 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1144 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1145
1146 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1147
1148 // Ensure all output layers have been assigned a simple/flattened z-order.
1149 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1150 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1151 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1152}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001153
1154/*
1155 * Output::ensureOutputLayerIfVisible()
1156 */
1157
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001158struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1159 struct OutputPartialMock : public OutputPartialMockBase {
1160 // Sets up the helper functions called by the function under test to use
1161 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001162 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001163 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001164 MOCK_METHOD2(ensureOutputLayer,
1165 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001166 };
1167
1168 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001169 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1170 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001171 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001172 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001173 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001174
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001175 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1176 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001177 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1178
Lloyd Piquede196652020-01-22 17:29:58 -08001179 mLayer.layerFEState.isVisible = true;
1180 mLayer.layerFEState.isOpaque = true;
1181 mLayer.layerFEState.contentDirty = true;
1182 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1183 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1184 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001185
Lloyd Piquede196652020-01-22 17:29:58 -08001186 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1187 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001188
Lloyd Piquede196652020-01-22 17:29:58 -08001189 mGeomSnapshots.insert(mLayer.layerFE);
1190 }
1191
1192 void ensureOutputLayerIfVisible() {
1193 sp<LayerFE> layerFE(mLayer.layerFE);
1194 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001195 }
1196
1197 static const Region kEmptyRegion;
1198 static const Region kFullBoundsNoRotation;
1199 static const Region kRightHalfBoundsNoRotation;
1200 static const Region kLowerHalfBoundsNoRotation;
1201 static const Region kFullBounds90Rotation;
1202
1203 StrictMock<OutputPartialMock> mOutput;
1204 LayerFESet mGeomSnapshots;
1205 Output::CoverageState mCoverageState{mGeomSnapshots};
1206
Lloyd Piquede196652020-01-22 17:29:58 -08001207 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001208};
1209
1210const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1211const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1212 Region(Rect(0, 0, 100, 200));
1213const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1214 Region(Rect(0, 100, 100, 200));
1215const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1216 Region(Rect(50, 0, 100, 200));
1217const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1218 Region(Rect(0, 0, 200, 100));
1219
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001221 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1222 EXPECT_CALL(*mLayer.layerFE,
1223 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001224
1225 mGeomSnapshots.clear();
1226
Lloyd Piquede196652020-01-22 17:29:58 -08001227 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228}
1229
1230TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1231 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001232 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001233
Lloyd Piquede196652020-01-22 17:29:58 -08001234 ensureOutputLayerIfVisible();
1235}
1236
1237TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1238 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1239
1240 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001241}
1242
1243TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001244 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001245
Lloyd Piquede196652020-01-22 17:29:58 -08001246 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001247}
1248
1249TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001250 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251
Lloyd Piquede196652020-01-22 17:29:58 -08001252 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253}
1254
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001255TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001256 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257
Lloyd Piquede196652020-01-22 17:29:58 -08001258 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001259}
1260
1261TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1262 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001263 mLayer.layerFEState.isOpaque = true;
1264 mLayer.layerFEState.contentDirty = true;
1265 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001266
1267 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001268 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1269 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270
Lloyd Piquede196652020-01-22 17:29:58 -08001271 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272
1273 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1274 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1275 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1276
Lloyd Piquede196652020-01-22 17:29:58 -08001277 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1278 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1279 RegionEq(kFullBoundsNoRotation));
1280 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1281 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001282}
1283
1284TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1285 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001286 mLayer.layerFEState.isOpaque = true;
1287 mLayer.layerFEState.contentDirty = true;
1288 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001289
Lloyd Piquede196652020-01-22 17:29:58 -08001290 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1291 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294
1295 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1296 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1297 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1298
Lloyd Piquede196652020-01-22 17:29:58 -08001299 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1300 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1301 RegionEq(kFullBoundsNoRotation));
1302 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1303 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001304}
1305
1306TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1307 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001308 mLayer.layerFEState.isOpaque = false;
1309 mLayer.layerFEState.contentDirty = true;
1310 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001311
1312 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001313 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1314 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315
Lloyd Piquede196652020-01-22 17:29:58 -08001316 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001317
1318 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1319 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1320 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1321
Lloyd Piquede196652020-01-22 17:29:58 -08001322 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1323 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001324 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001325 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1326 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327}
1328
1329TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1330 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001331 mLayer.layerFEState.isOpaque = false;
1332 mLayer.layerFEState.contentDirty = true;
1333 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001334
Lloyd Piquede196652020-01-22 17:29:58 -08001335 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1336 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337
Lloyd Piquede196652020-01-22 17:29:58 -08001338 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001339
1340 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1341 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1342 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1343
Lloyd Piquede196652020-01-22 17:29:58 -08001344 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1345 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001347 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1348 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001349}
1350
1351TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1352 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001353 mLayer.layerFEState.isOpaque = true;
1354 mLayer.layerFEState.contentDirty = false;
1355 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
1357 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001358 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1359 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360
Lloyd Piquede196652020-01-22 17:29:58 -08001361 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001362
1363 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1365 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1366
Lloyd Piquede196652020-01-22 17:29:58 -08001367 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1368 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1369 RegionEq(kFullBoundsNoRotation));
1370 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1371 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372}
1373
1374TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1375 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001376 mLayer.layerFEState.isOpaque = true;
1377 mLayer.layerFEState.contentDirty = false;
1378 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
Lloyd Piquede196652020-01-22 17:29:58 -08001380 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1381 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001382
Lloyd Piquede196652020-01-22 17:29:58 -08001383 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384
1385 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1386 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1388
Lloyd Piquede196652020-01-22 17:29:58 -08001389 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1390 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1391 RegionEq(kFullBoundsNoRotation));
1392 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1393 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001394}
1395
1396TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1397 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001398 mLayer.layerFEState.isOpaque = true;
1399 mLayer.layerFEState.contentDirty = true;
1400 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1401 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1402 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1403 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001404
1405 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001406 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1407 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408
Lloyd Piquede196652020-01-22 17:29:58 -08001409 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410
1411 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1412 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1413 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1414
Lloyd Piquede196652020-01-22 17:29:58 -08001415 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1416 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1417 RegionEq(kFullBoundsNoRotation));
1418 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1419 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420}
1421
1422TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1423 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001424 mLayer.layerFEState.isOpaque = true;
1425 mLayer.layerFEState.contentDirty = true;
1426 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1427 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1428 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1429 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430
Lloyd Piquede196652020-01-22 17:29:58 -08001431 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1432 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
1436 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1438 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1439
Lloyd Piquede196652020-01-22 17:29:58 -08001440 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1441 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1442 RegionEq(kFullBoundsNoRotation));
1443 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1444 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445}
1446
1447TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1448 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001449 mLayer.layerFEState.isOpaque = true;
1450 mLayer.layerFEState.contentDirty = true;
1451 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001453 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001454 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1455
1456 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001457 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1458 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459
Lloyd Piquede196652020-01-22 17:29:58 -08001460 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461
1462 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1463 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1464 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1467 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1468 RegionEq(kFullBoundsNoRotation));
1469 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1470 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471}
1472
1473TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1474 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001475 mLayer.layerFEState.isOpaque = true;
1476 mLayer.layerFEState.contentDirty = true;
1477 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001478
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001479 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1481
Lloyd Piquede196652020-01-22 17:29:58 -08001482 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1483 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001484
Lloyd Piquede196652020-01-22 17:29:58 -08001485 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
1487 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1488 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1489 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1490
Lloyd Piquede196652020-01-22 17:29:58 -08001491 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1492 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1493 RegionEq(kFullBoundsNoRotation));
1494 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1495 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496}
1497
1498TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1499 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1500 ui::Transform arbitraryTransform;
1501 arbitraryTransform.set(1, 1, -1, 1);
1502 arbitraryTransform.set(0, 100);
1503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 mLayer.layerFEState.isOpaque = true;
1505 mLayer.layerFEState.contentDirty = true;
1506 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1507 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508
1509 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001510 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1511 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514
1515 const Region kRegion = Region(Rect(0, 0, 300, 300));
1516 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1517
1518 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1519 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1520 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1523 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1524 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1525 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526}
1527
1528TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001529 mLayer.layerFEState.isOpaque = false;
1530 mLayer.layerFEState.contentDirty = true;
1531 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001532
1533 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1534 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1535 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1536
Lloyd Piquede196652020-01-22 17:29:58 -08001537 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1538 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001539
Lloyd Piquede196652020-01-22 17:29:58 -08001540 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541
1542 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1543 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1544 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1545 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1546 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1547 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1548
1549 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1550 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1551 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1552
Lloyd Piquede196652020-01-22 17:29:58 -08001553 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1554 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001555 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001556 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1557 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1558 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001560
Vishnu Naira483b4a2019-12-12 15:07:52 -08001561TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1562 ui::Transform translate;
1563 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001564 mLayer.layerFEState.geomLayerTransform = translate;
1565 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001566
1567 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1568 // half of the layer including the casting shadow is covered and opaque
1569 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1570 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1571
Lloyd Piquede196652020-01-22 17:29:58 -08001572 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1573 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001574
Lloyd Piquede196652020-01-22 17:29:58 -08001575 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001576
1577 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1578 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1579 // add starting opaque region to the opaque half of the casting layer bounds
1580 const Region kExpectedAboveOpaqueRegion =
1581 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1582 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1583 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1584 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1585 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1586 const Region kExpectedLayerShadowRegion =
1587 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1588
1589 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1590 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1591 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1592
Lloyd Piquede196652020-01-22 17:29:58 -08001593 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1594 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001595 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1597 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001598 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001600 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1601}
1602
1603TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1604 ui::Transform translate;
1605 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001606 mLayer.layerFEState.geomLayerTransform = translate;
1607 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001608
1609 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1610 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1611 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1612 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1613
Lloyd Piquede196652020-01-22 17:29:58 -08001614 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1615 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001616
Lloyd Piquede196652020-01-22 17:29:58 -08001617 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001618
1619 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1620 const Region kExpectedLayerShadowRegion =
1621 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1624 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001625 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1626}
1627
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001628TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001629 ui::Transform translate;
1630 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001631 mLayer.layerFEState.geomLayerTransform = translate;
1632 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001633
1634 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1635 // Casting layer and its shadows are covered by an opaque region
1636 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1637 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001640}
1641
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001642/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001643 * Output::present()
1644 */
1645
1646struct OutputPresentTest : public testing::Test {
1647 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001648 // Sets up the helper functions called by the function under test to use
1649 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001650 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001651 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001652 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001653 MOCK_METHOD0(planComposition, void());
1654 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001655 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1656 MOCK_METHOD0(beginFrame, void());
1657 MOCK_METHOD0(prepareFrame, void());
1658 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1659 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1660 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001661 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001662 };
1663
1664 StrictMock<OutputPartialMock> mOutput;
1665};
1666
1667TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1668 CompositionRefreshArgs args;
1669
1670 InSequence seq;
1671 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001672 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1673 EXPECT_CALL(mOutput, planComposition());
1674 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001675 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1676 EXPECT_CALL(mOutput, beginFrame());
1677 EXPECT_CALL(mOutput, prepareFrame());
1678 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1679 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1680 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001681 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001682
1683 mOutput.present(args);
1684}
1685
1686/*
1687 * Output::updateColorProfile()
1688 */
1689
Lloyd Pique17ca7422019-11-14 14:24:10 -08001690struct OutputUpdateColorProfileTest : public testing::Test {
1691 using TestType = OutputUpdateColorProfileTest;
1692
1693 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001694 // Sets up the helper functions called by the function under test to use
1695 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001696 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1697 };
1698
1699 struct Layer {
1700 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001701 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1702 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001703 }
1704
1705 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001706 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001707 LayerFECompositionState mLayerFEState;
1708 };
1709
1710 OutputUpdateColorProfileTest() {
1711 mOutput.setDisplayColorProfileForTest(
1712 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1713 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1714
1715 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1716 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1717 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1718 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1719 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1720 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1721 }
1722
1723 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1724 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1725 };
1726
1727 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1728 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1729 StrictMock<OutputPartialMock> mOutput;
1730
1731 Layer mLayer1;
1732 Layer mLayer2;
1733 Layer mLayer3;
1734
1735 CompositionRefreshArgs mRefreshArgs;
1736};
1737
1738// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1739// to make it easier to write unit tests.
1740
1741TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1742 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1743 // a simple default color profile without looking at anything else.
1744
Lloyd Pique0a456232020-01-16 17:51:13 -08001745 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001746 EXPECT_CALL(mOutput,
1747 setColorProfile(ColorProfileEq(
1748 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1749 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1750
1751 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1752 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1753
1754 mOutput.updateColorProfile(mRefreshArgs);
1755}
1756
1757struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1758 : public OutputUpdateColorProfileTest {
1759 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001760 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001761 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1762 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1763 }
1764
1765 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1766 : public CallOrderStateMachineHelper<
1767 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1768 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1769 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1770 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1771 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1772 _))
1773 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1774 SetArgPointee<4>(renderIntent)));
1775 EXPECT_CALL(getInstance()->mOutput,
1776 setColorProfile(
1777 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1778 ui::Dataspace::UNKNOWN})));
1779 return nextState<ExecuteState>();
1780 }
1781 };
1782
1783 // Call this member function to start using the mini-DSL defined above.
1784 [[nodiscard]] auto verify() {
1785 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1786 }
1787};
1788
1789TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1790 Native_Unknown_Colorimetric_Set) {
1791 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1792 ui::Dataspace::UNKNOWN,
1793 ui::RenderIntent::COLORIMETRIC)
1794 .execute();
1795}
1796
1797TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1798 DisplayP3_DisplayP3_Enhance_Set) {
1799 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1800 ui::Dataspace::DISPLAY_P3,
1801 ui::RenderIntent::ENHANCE)
1802 .execute();
1803}
1804
1805struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1806 : public OutputUpdateColorProfileTest {
1807 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001808 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001809 EXPECT_CALL(*mDisplayColorProfile,
1810 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1811 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1812 SetArgPointee<3>(ui::ColorMode::NATIVE),
1813 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1814 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1815 }
1816
1817 struct IfColorSpaceAgnosticDataspaceSetToState
1818 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1819 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1820 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1821 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1822 }
1823 };
1824
1825 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1826 : public CallOrderStateMachineHelper<
1827 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1828 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1829 ui::Dataspace dataspace) {
1830 EXPECT_CALL(getInstance()->mOutput,
1831 setColorProfile(ColorProfileEq(
1832 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1833 ui::RenderIntent::COLORIMETRIC, dataspace})));
1834 return nextState<ExecuteState>();
1835 }
1836 };
1837
1838 // Call this member function to start using the mini-DSL defined above.
1839 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1840};
1841
1842TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1843 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1844 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1845 .execute();
1846}
1847
1848TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1849 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1850 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1851 .execute();
1852}
1853
1854struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1855 : public OutputUpdateColorProfileTest {
1856 // Internally the implementation looks through the dataspaces of all the
1857 // visible layers. The topmost one that also has an actual dataspace
1858 // preference set is used to drive subsequent choices.
1859
1860 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1861 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1862 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1863
Lloyd Pique0a456232020-01-16 17:51:13 -08001864 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001865 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1866 }
1867
1868 struct IfTopLayerDataspaceState
1869 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1870 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1871 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1872 return nextState<AndIfMiddleLayerDataspaceState>();
1873 }
1874 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1875 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1876 }
1877 };
1878
1879 struct AndIfMiddleLayerDataspaceState
1880 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1881 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1882 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1883 return nextState<AndIfBottomLayerDataspaceState>();
1884 }
1885 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1886 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1887 }
1888 };
1889
1890 struct AndIfBottomLayerDataspaceState
1891 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1892 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1893 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1894 return nextState<ThenExpectBestColorModeCallUsesState>();
1895 }
1896 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1897 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1898 }
1899 };
1900
1901 struct ThenExpectBestColorModeCallUsesState
1902 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1903 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1904 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1905 getBestColorMode(dataspace, _, _, _, _));
1906 return nextState<ExecuteState>();
1907 }
1908 };
1909
1910 // Call this member function to start using the mini-DSL defined above.
1911 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1912};
1913
1914TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1915 noStrongLayerPrefenceUses_V0_SRGB) {
1916 // If none of the layers indicate a preference, then V0_SRGB is the
1917 // preferred choice (subject to additional checks).
1918 verify().ifTopLayerHasNoPreference()
1919 .andIfMiddleLayerHasNoPreference()
1920 .andIfBottomLayerHasNoPreference()
1921 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1922 .execute();
1923}
1924
1925TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1926 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1927 // If only the topmost layer has a preference, then that is what is chosen.
1928 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1929 .andIfMiddleLayerHasNoPreference()
1930 .andIfBottomLayerHasNoPreference()
1931 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1932 .execute();
1933}
1934
1935TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1936 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1937 // If only the middle layer has a preference, that that is what is chosen.
1938 verify().ifTopLayerHasNoPreference()
1939 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1940 .andIfBottomLayerHasNoPreference()
1941 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1942 .execute();
1943}
1944
1945TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1946 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1947 // If only the middle layer has a preference, that that is what is chosen.
1948 verify().ifTopLayerHasNoPreference()
1949 .andIfMiddleLayerHasNoPreference()
1950 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1951 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1952 .execute();
1953}
1954
1955TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1956 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1957 // If multiple layers have a preference, the topmost value is what is used.
1958 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1959 .andIfMiddleLayerHasNoPreference()
1960 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1961 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1962 .execute();
1963}
1964
1965TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1966 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1967 // If multiple layers have a preference, the topmost value is what is used.
1968 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1969 .andIfMiddleLayerHasNoPreference()
1970 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1971 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1972 .execute();
1973}
1974
1975struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1976 : public OutputUpdateColorProfileTest {
1977 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1978 // values, it overrides the layer dataspace choice.
1979
1980 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1981 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1982 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1983
1984 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1985
Lloyd Pique0a456232020-01-16 17:51:13 -08001986 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001987 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1988 }
1989
1990 struct IfForceOutputColorModeState
1991 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1992 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1993 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1994 return nextState<ThenExpectBestColorModeCallUsesState>();
1995 }
1996 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1997 };
1998
1999 struct ThenExpectBestColorModeCallUsesState
2000 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2001 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2002 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2003 getBestColorMode(dataspace, _, _, _, _));
2004 return nextState<ExecuteState>();
2005 }
2006 };
2007
2008 // Call this member function to start using the mini-DSL defined above.
2009 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2010};
2011
2012TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2013 // By default the layer state is used to set the preferred dataspace
2014 verify().ifNoOverride()
2015 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2016 .execute();
2017}
2018
2019TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2020 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2021 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2022 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2023 .execute();
2024}
2025
2026TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2027 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2028 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2029 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2030 .execute();
2031}
2032
2033// HDR output requires all layers to be compatible with the chosen HDR
2034// dataspace, along with there being proper support.
2035struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2036 OutputUpdateColorProfileTest_Hdr() {
2037 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2038 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002039 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002040 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2041 }
2042
2043 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2044 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2045 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2046 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2047
2048 struct IfTopLayerDataspaceState
2049 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2050 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2051 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2052 return nextState<AndTopLayerCompositionTypeState>();
2053 }
2054 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2055 };
2056
2057 struct AndTopLayerCompositionTypeState
2058 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2059 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2060 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2061 return nextState<AndIfBottomLayerDataspaceState>();
2062 }
2063 };
2064
2065 struct AndIfBottomLayerDataspaceState
2066 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2067 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2068 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2069 return nextState<AndBottomLayerCompositionTypeState>();
2070 }
2071 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2072 return andIfBottomLayerIs(kNonHdrDataspace);
2073 }
2074 };
2075
2076 struct AndBottomLayerCompositionTypeState
2077 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2078 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2079 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2080 return nextState<AndIfHasLegacySupportState>();
2081 }
2082 };
2083
2084 struct AndIfHasLegacySupportState
2085 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2086 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2087 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2088 .WillOnce(Return(legacySupport));
2089 return nextState<ThenExpectBestColorModeCallUsesState>();
2090 }
2091 };
2092
2093 struct ThenExpectBestColorModeCallUsesState
2094 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2095 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2096 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2097 getBestColorMode(dataspace, _, _, _, _));
2098 return nextState<ExecuteState>();
2099 }
2100 };
2101
2102 // Call this member function to start using the mini-DSL defined above.
2103 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2104};
2105
2106TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2107 // If all layers use BT2020_PQ, and there are no other special conditions,
2108 // BT2020_PQ is used.
2109 verify().ifTopLayerIs(BT2020_PQ)
2110 .andTopLayerIsREComposed(false)
2111 .andIfBottomLayerIs(BT2020_PQ)
2112 .andBottomLayerIsREComposed(false)
2113 .andIfLegacySupportFor(BT2020_PQ, false)
2114 .thenExpectBestColorModeCallUses(BT2020_PQ)
2115 .execute();
2116}
2117
2118TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2119 // BT2020_PQ is not used if there is only legacy support for it.
2120 verify().ifTopLayerIs(BT2020_PQ)
2121 .andTopLayerIsREComposed(false)
2122 .andIfBottomLayerIs(BT2020_PQ)
2123 .andBottomLayerIsREComposed(false)
2124 .andIfLegacySupportFor(BT2020_PQ, true)
2125 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2126 .execute();
2127}
2128
2129TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2130 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2131 verify().ifTopLayerIs(BT2020_PQ)
2132 .andTopLayerIsREComposed(false)
2133 .andIfBottomLayerIs(BT2020_PQ)
2134 .andBottomLayerIsREComposed(true)
2135 .andIfLegacySupportFor(BT2020_PQ, false)
2136 .thenExpectBestColorModeCallUses(BT2020_PQ)
2137 .execute();
2138}
2139
2140TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2141 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2142 verify().ifTopLayerIs(BT2020_PQ)
2143 .andTopLayerIsREComposed(true)
2144 .andIfBottomLayerIs(BT2020_PQ)
2145 .andBottomLayerIsREComposed(false)
2146 .andIfLegacySupportFor(BT2020_PQ, false)
2147 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2148 .execute();
2149}
2150
2151TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2152 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2153 // are no other special conditions.
2154 verify().ifTopLayerIs(BT2020_PQ)
2155 .andTopLayerIsREComposed(false)
2156 .andIfBottomLayerIs(BT2020_HLG)
2157 .andBottomLayerIsREComposed(false)
2158 .andIfLegacySupportFor(BT2020_PQ, false)
2159 .thenExpectBestColorModeCallUses(BT2020_PQ)
2160 .execute();
2161}
2162
2163TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2164 // BT2020_PQ is not used if there is only legacy support for it.
2165 verify().ifTopLayerIs(BT2020_PQ)
2166 .andTopLayerIsREComposed(false)
2167 .andIfBottomLayerIs(BT2020_HLG)
2168 .andBottomLayerIsREComposed(false)
2169 .andIfLegacySupportFor(BT2020_PQ, true)
2170 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2171 .execute();
2172}
2173
2174TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2175 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2176 verify().ifTopLayerIs(BT2020_PQ)
2177 .andTopLayerIsREComposed(false)
2178 .andIfBottomLayerIs(BT2020_HLG)
2179 .andBottomLayerIsREComposed(true)
2180 .andIfLegacySupportFor(BT2020_PQ, false)
2181 .thenExpectBestColorModeCallUses(BT2020_PQ)
2182 .execute();
2183}
2184
2185TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2186 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2187 verify().ifTopLayerIs(BT2020_PQ)
2188 .andTopLayerIsREComposed(true)
2189 .andIfBottomLayerIs(BT2020_HLG)
2190 .andBottomLayerIsREComposed(false)
2191 .andIfLegacySupportFor(BT2020_PQ, false)
2192 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2193 .execute();
2194}
2195
2196TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2197 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2198 // used if there are no other special conditions.
2199 verify().ifTopLayerIs(BT2020_HLG)
2200 .andTopLayerIsREComposed(false)
2201 .andIfBottomLayerIs(BT2020_PQ)
2202 .andBottomLayerIsREComposed(false)
2203 .andIfLegacySupportFor(BT2020_PQ, false)
2204 .thenExpectBestColorModeCallUses(BT2020_PQ)
2205 .execute();
2206}
2207
2208TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2209 // BT2020_PQ is not used if there is only legacy support for it.
2210 verify().ifTopLayerIs(BT2020_HLG)
2211 .andTopLayerIsREComposed(false)
2212 .andIfBottomLayerIs(BT2020_PQ)
2213 .andBottomLayerIsREComposed(false)
2214 .andIfLegacySupportFor(BT2020_PQ, true)
2215 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2216 .execute();
2217}
2218
2219TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2220 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2221 verify().ifTopLayerIs(BT2020_HLG)
2222 .andTopLayerIsREComposed(false)
2223 .andIfBottomLayerIs(BT2020_PQ)
2224 .andBottomLayerIsREComposed(true)
2225 .andIfLegacySupportFor(BT2020_PQ, false)
2226 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2227 .execute();
2228}
2229
2230TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2231 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2232 verify().ifTopLayerIs(BT2020_HLG)
2233 .andTopLayerIsREComposed(true)
2234 .andIfBottomLayerIs(BT2020_PQ)
2235 .andBottomLayerIsREComposed(false)
2236 .andIfLegacySupportFor(BT2020_PQ, false)
2237 .thenExpectBestColorModeCallUses(BT2020_PQ)
2238 .execute();
2239}
2240
2241TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2242 // If all layers use HLG then HLG is used if there are no other special
2243 // conditions.
2244 verify().ifTopLayerIs(BT2020_HLG)
2245 .andTopLayerIsREComposed(false)
2246 .andIfBottomLayerIs(BT2020_HLG)
2247 .andBottomLayerIsREComposed(false)
2248 .andIfLegacySupportFor(BT2020_HLG, false)
2249 .thenExpectBestColorModeCallUses(BT2020_HLG)
2250 .execute();
2251}
2252
2253TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2254 // BT2020_HLG is not used if there is legacy support for it.
2255 verify().ifTopLayerIs(BT2020_HLG)
2256 .andTopLayerIsREComposed(false)
2257 .andIfBottomLayerIs(BT2020_HLG)
2258 .andBottomLayerIsREComposed(false)
2259 .andIfLegacySupportFor(BT2020_HLG, true)
2260 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2261 .execute();
2262}
2263
2264TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2265 // BT2020_HLG is used even if the bottom layer is client composed.
2266 verify().ifTopLayerIs(BT2020_HLG)
2267 .andTopLayerIsREComposed(false)
2268 .andIfBottomLayerIs(BT2020_HLG)
2269 .andBottomLayerIsREComposed(true)
2270 .andIfLegacySupportFor(BT2020_HLG, false)
2271 .thenExpectBestColorModeCallUses(BT2020_HLG)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2276 // BT2020_HLG is used even if the top layer is client composed.
2277 verify().ifTopLayerIs(BT2020_HLG)
2278 .andTopLayerIsREComposed(true)
2279 .andIfBottomLayerIs(BT2020_HLG)
2280 .andBottomLayerIsREComposed(false)
2281 .andIfLegacySupportFor(BT2020_HLG, false)
2282 .thenExpectBestColorModeCallUses(BT2020_HLG)
2283 .execute();
2284}
2285
2286TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2287 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2288 verify().ifTopLayerIs(BT2020_PQ)
2289 .andTopLayerIsREComposed(false)
2290 .andIfBottomLayerIsNotHdr()
2291 .andBottomLayerIsREComposed(false)
2292 .andIfLegacySupportFor(BT2020_PQ, false)
2293 .thenExpectBestColorModeCallUses(BT2020_PQ)
2294 .execute();
2295}
2296
2297TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2298 // If all layers use HLG then HLG is used if there are no other special
2299 // conditions.
2300 verify().ifTopLayerIs(BT2020_HLG)
2301 .andTopLayerIsREComposed(false)
2302 .andIfBottomLayerIsNotHdr()
2303 .andBottomLayerIsREComposed(true)
2304 .andIfLegacySupportFor(BT2020_HLG, false)
2305 .thenExpectBestColorModeCallUses(BT2020_HLG)
2306 .execute();
2307}
2308
2309struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2310 : public OutputUpdateColorProfileTest {
2311 // The various values for CompositionRefreshArgs::outputColorSetting affect
2312 // the chosen renderIntent, along with whether the preferred dataspace is an
2313 // HDR dataspace or not.
2314
2315 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2316 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2317 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2318 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002319 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002320 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2321 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2322 .WillRepeatedly(Return(false));
2323 }
2324
2325 // The tests here involve enough state and GMock setup that using a mini-DSL
2326 // makes the tests much more readable, and allows the test to focus more on
2327 // the intent than on some of the details.
2328
2329 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2330 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2331
2332 struct IfDataspaceChosenState
2333 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2334 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2335 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2336 return nextState<AndOutputColorSettingState>();
2337 }
2338 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2339 return ifDataspaceChosenIs(kNonHdrDataspace);
2340 }
2341 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2342 };
2343
2344 struct AndOutputColorSettingState
2345 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2346 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2347 getInstance()->mRefreshArgs.outputColorSetting = setting;
2348 return nextState<ThenExpectBestColorModeCallUsesState>();
2349 }
2350 };
2351
2352 struct ThenExpectBestColorModeCallUsesState
2353 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2354 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2355 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2356 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2357 _, _));
2358 return nextState<ExecuteState>();
2359 }
2360 };
2361
2362 // Tests call one of these two helper member functions to start using the
2363 // mini-DSL defined above.
2364 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2365};
2366
2367TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2368 Managed_NonHdr_Prefers_Colorimetric) {
2369 verify().ifDataspaceChosenIsNonHdr()
2370 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2371 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2372 .execute();
2373}
2374
2375TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2376 Managed_Hdr_Prefers_ToneMapColorimetric) {
2377 verify().ifDataspaceChosenIsHdr()
2378 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2379 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2380 .execute();
2381}
2382
2383TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2384 verify().ifDataspaceChosenIsNonHdr()
2385 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2386 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2387 .execute();
2388}
2389
2390TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2391 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2392 verify().ifDataspaceChosenIsHdr()
2393 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2394 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2395 .execute();
2396}
2397
2398TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2399 verify().ifDataspaceChosenIsNonHdr()
2400 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2401 .thenExpectBestColorModeCallUses(
2402 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2403 .execute();
2404}
2405
2406TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2407 verify().ifDataspaceChosenIsHdr()
2408 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2409 .thenExpectBestColorModeCallUses(
2410 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2411 .execute();
2412}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002413
2414/*
2415 * Output::beginFrame()
2416 */
2417
Lloyd Piquee5965952019-11-18 16:16:32 -08002418struct OutputBeginFrameTest : public ::testing::Test {
2419 using TestType = OutputBeginFrameTest;
2420
2421 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002422 // Sets up the helper functions called by the function under test to use
2423 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002424 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2425 };
2426
2427 OutputBeginFrameTest() {
2428 mOutput.setDisplayColorProfileForTest(
2429 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2430 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2431 }
2432
2433 struct IfGetDirtyRegionExpectationState
2434 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2435 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2436 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2437 .WillOnce(Return(dirtyRegion));
2438 return nextState<AndIfGetOutputLayerCountExpectationState>();
2439 }
2440 };
2441
2442 struct AndIfGetOutputLayerCountExpectationState
2443 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2444 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2445 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2446 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2447 }
2448 };
2449
2450 struct AndIfLastCompositionHadVisibleLayersState
2451 : public CallOrderStateMachineHelper<TestType,
2452 AndIfLastCompositionHadVisibleLayersState> {
2453 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2454 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2455 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2456 }
2457 };
2458
2459 struct ThenExpectRenderSurfaceBeginFrameCallState
2460 : public CallOrderStateMachineHelper<TestType,
2461 ThenExpectRenderSurfaceBeginFrameCallState> {
2462 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2463 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2464 return nextState<ExecuteState>();
2465 }
2466 };
2467
2468 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2469 [[nodiscard]] auto execute() {
2470 getInstance()->mOutput.beginFrame();
2471 return nextState<CheckPostconditionHadVisibleLayersState>();
2472 }
2473 };
2474
2475 struct CheckPostconditionHadVisibleLayersState
2476 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2477 void checkPostconditionHadVisibleLayers(bool expected) {
2478 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2479 }
2480 };
2481
2482 // Tests call one of these two helper member functions to start using the
2483 // mini-DSL defined above.
2484 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2485
2486 static const Region kEmptyRegion;
2487 static const Region kNotEmptyRegion;
2488
2489 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2490 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2491 StrictMock<OutputPartialMock> mOutput;
2492};
2493
2494const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2495const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2496
2497TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2498 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2499 .andIfGetOutputLayerCountReturns(1u)
2500 .andIfLastCompositionHadVisibleLayersIs(true)
2501 .thenExpectRenderSurfaceBeginFrameCall(true)
2502 .execute()
2503 .checkPostconditionHadVisibleLayers(true);
2504}
2505
2506TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2507 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2508 .andIfGetOutputLayerCountReturns(0u)
2509 .andIfLastCompositionHadVisibleLayersIs(true)
2510 .thenExpectRenderSurfaceBeginFrameCall(true)
2511 .execute()
2512 .checkPostconditionHadVisibleLayers(false);
2513}
2514
2515TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2516 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2517 .andIfGetOutputLayerCountReturns(1u)
2518 .andIfLastCompositionHadVisibleLayersIs(false)
2519 .thenExpectRenderSurfaceBeginFrameCall(true)
2520 .execute()
2521 .checkPostconditionHadVisibleLayers(true);
2522}
2523
2524TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2525 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2526 .andIfGetOutputLayerCountReturns(0u)
2527 .andIfLastCompositionHadVisibleLayersIs(false)
2528 .thenExpectRenderSurfaceBeginFrameCall(false)
2529 .execute()
2530 .checkPostconditionHadVisibleLayers(false);
2531}
2532
2533TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2534 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2535 .andIfGetOutputLayerCountReturns(1u)
2536 .andIfLastCompositionHadVisibleLayersIs(true)
2537 .thenExpectRenderSurfaceBeginFrameCall(false)
2538 .execute()
2539 .checkPostconditionHadVisibleLayers(true);
2540}
2541
2542TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2543 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2544 .andIfGetOutputLayerCountReturns(0u)
2545 .andIfLastCompositionHadVisibleLayersIs(true)
2546 .thenExpectRenderSurfaceBeginFrameCall(false)
2547 .execute()
2548 .checkPostconditionHadVisibleLayers(true);
2549}
2550
2551TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2552 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2553 .andIfGetOutputLayerCountReturns(1u)
2554 .andIfLastCompositionHadVisibleLayersIs(false)
2555 .thenExpectRenderSurfaceBeginFrameCall(false)
2556 .execute()
2557 .checkPostconditionHadVisibleLayers(false);
2558}
2559
2560TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2561 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2562 .andIfGetOutputLayerCountReturns(0u)
2563 .andIfLastCompositionHadVisibleLayersIs(false)
2564 .thenExpectRenderSurfaceBeginFrameCall(false)
2565 .execute()
2566 .checkPostconditionHadVisibleLayers(false);
2567}
2568
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002569/*
2570 * Output::devOptRepaintFlash()
2571 */
2572
Lloyd Piquedb462d82019-11-19 17:58:46 -08002573struct OutputDevOptRepaintFlashTest : public testing::Test {
2574 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002575 // Sets up the helper functions called by the function under test to use
2576 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002577 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002578 MOCK_METHOD2(composeSurfaces,
2579 std::optional<base::unique_fd>(
2580 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002581 MOCK_METHOD0(postFramebuffer, void());
2582 MOCK_METHOD0(prepareFrame, void());
2583 };
2584
2585 OutputDevOptRepaintFlashTest() {
2586 mOutput.setDisplayColorProfileForTest(
2587 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2588 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2589 }
2590
2591 static const Region kEmptyRegion;
2592 static const Region kNotEmptyRegion;
2593
2594 StrictMock<OutputPartialMock> mOutput;
2595 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2596 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2597 CompositionRefreshArgs mRefreshArgs;
2598};
2599
2600const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2601const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2602
2603TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2604 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2605 mRefreshArgs.repaintEverything = true;
2606 mOutput.mState.isEnabled = true;
2607
2608 mOutput.devOptRepaintFlash(mRefreshArgs);
2609}
2610
2611TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2612 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2613 mRefreshArgs.repaintEverything = true;
2614 mOutput.mState.isEnabled = false;
2615
2616 InSequence seq;
2617 EXPECT_CALL(mOutput, postFramebuffer());
2618 EXPECT_CALL(mOutput, prepareFrame());
2619
2620 mOutput.devOptRepaintFlash(mRefreshArgs);
2621}
2622
2623TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2624 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2625 mRefreshArgs.repaintEverything = true;
2626 mOutput.mState.isEnabled = true;
2627
2628 InSequence seq;
2629 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2630 EXPECT_CALL(mOutput, postFramebuffer());
2631 EXPECT_CALL(mOutput, prepareFrame());
2632
2633 mOutput.devOptRepaintFlash(mRefreshArgs);
2634}
2635
2636TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2637 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2638 mRefreshArgs.repaintEverything = false;
2639 mOutput.mState.isEnabled = true;
2640
2641 InSequence seq;
2642 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002643 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002644 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2645 EXPECT_CALL(mOutput, postFramebuffer());
2646 EXPECT_CALL(mOutput, prepareFrame());
2647
2648 mOutput.devOptRepaintFlash(mRefreshArgs);
2649}
2650
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002651/*
2652 * Output::finishFrame()
2653 */
2654
Lloyd Pique03561a62019-11-19 18:34:52 -08002655struct OutputFinishFrameTest : public testing::Test {
2656 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002657 // Sets up the helper functions called by the function under test to use
2658 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002659 MOCK_METHOD2(composeSurfaces,
2660 std::optional<base::unique_fd>(
2661 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002662 MOCK_METHOD0(postFramebuffer, void());
2663 };
2664
2665 OutputFinishFrameTest() {
2666 mOutput.setDisplayColorProfileForTest(
2667 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2668 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2669 }
2670
2671 StrictMock<OutputPartialMock> mOutput;
2672 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2673 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2674 CompositionRefreshArgs mRefreshArgs;
2675};
2676
2677TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2678 mOutput.mState.isEnabled = false;
2679
2680 mOutput.finishFrame(mRefreshArgs);
2681}
2682
2683TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2684 mOutput.mState.isEnabled = true;
2685
2686 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002687 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002688
2689 mOutput.finishFrame(mRefreshArgs);
2690}
2691
2692TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2693 mOutput.mState.isEnabled = true;
2694
2695 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002696 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002697 .WillOnce(Return(ByMove(base::unique_fd())));
2698 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2699
2700 mOutput.finishFrame(mRefreshArgs);
2701}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002702
2703/*
2704 * Output::postFramebuffer()
2705 */
2706
Lloyd Pique07178e32019-11-19 19:15:26 -08002707struct OutputPostFramebufferTest : public testing::Test {
2708 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002709 // Sets up the helper functions called by the function under test to use
2710 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002711 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2712 };
2713
2714 struct Layer {
2715 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002716 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002717 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2718 }
2719
2720 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002721 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002722 StrictMock<HWC2::mock::Layer> hwc2Layer;
2723 };
2724
2725 OutputPostFramebufferTest() {
2726 mOutput.setDisplayColorProfileForTest(
2727 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2728 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2729
2730 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2731 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2732 .WillRepeatedly(Return(&mLayer1.outputLayer));
2733 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2734 .WillRepeatedly(Return(&mLayer2.outputLayer));
2735 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2736 .WillRepeatedly(Return(&mLayer3.outputLayer));
2737 }
2738
2739 StrictMock<OutputPartialMock> mOutput;
2740 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2741 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2742
2743 Layer mLayer1;
2744 Layer mLayer2;
2745 Layer mLayer3;
2746};
2747
2748TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2749 mOutput.mState.isEnabled = false;
2750
2751 mOutput.postFramebuffer();
2752}
2753
2754TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2755 mOutput.mState.isEnabled = true;
2756
2757 compositionengine::Output::FrameFences frameFences;
2758
2759 // This should happen even if there are no output layers.
2760 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2761
2762 // For this test in particular we want to make sure the call expectations
2763 // setup below are satisfied in the specific order.
2764 InSequence seq;
2765
2766 EXPECT_CALL(*mRenderSurface, flip());
2767 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2768 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2769
2770 mOutput.postFramebuffer();
2771}
2772
2773TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2774 // Simulate getting release fences from each layer, and ensure they are passed to the
2775 // front-end layer interface for each layer correctly.
2776
2777 mOutput.mState.isEnabled = true;
2778
2779 // Create three unique fence instances
2780 sp<Fence> layer1Fence = new Fence();
2781 sp<Fence> layer2Fence = new Fence();
2782 sp<Fence> layer3Fence = new Fence();
2783
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002784 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002785 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2786 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2787 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2788
2789 EXPECT_CALL(*mRenderSurface, flip());
2790 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2791 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2792
2793 // Compare the pointers values of each fence to make sure the correct ones
2794 // are passed. This happens to work with the current implementation, but
2795 // would not survive certain calls like Fence::merge() which would return a
2796 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002797 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002798 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002799 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002800 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002801 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002802 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2803
2804 mOutput.postFramebuffer();
2805}
2806
2807TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2808 mOutput.mState.isEnabled = true;
2809 mOutput.mState.usesClientComposition = true;
2810
2811 sp<Fence> clientTargetAcquireFence = new Fence();
2812 sp<Fence> layer1Fence = new Fence();
2813 sp<Fence> layer2Fence = new Fence();
2814 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002815 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002816 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2817 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2818 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2819 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2820
2821 EXPECT_CALL(*mRenderSurface, flip());
2822 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2823 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2824
2825 // Fence::merge is called, and since none of the fences are actually valid,
2826 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2827 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002828 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2829 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2830 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002831
2832 mOutput.postFramebuffer();
2833}
2834
2835TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2836 mOutput.mState.isEnabled = true;
2837 mOutput.mState.usesClientComposition = true;
2838
2839 // This should happen even if there are no (current) output layers.
2840 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2841
2842 // Load up the released layers with some mock instances
2843 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2844 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2845 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2846 Output::ReleasedLayers layers;
2847 layers.push_back(releasedLayer1);
2848 layers.push_back(releasedLayer2);
2849 layers.push_back(releasedLayer3);
2850 mOutput.setReleasedLayers(std::move(layers));
2851
2852 // Set up a fake present fence
2853 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002854 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002855 frameFences.presentFence = presentFence;
2856
2857 EXPECT_CALL(*mRenderSurface, flip());
2858 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2859 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2860
2861 // Each released layer should be given the presentFence.
2862 EXPECT_CALL(*releasedLayer1,
2863 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2864 EXPECT_CALL(*releasedLayer2,
2865 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2866 EXPECT_CALL(*releasedLayer3,
2867 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2868
2869 mOutput.postFramebuffer();
2870
2871 // After the call the list of released layers should have been cleared.
2872 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2873}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002874
2875/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002876 * Output::composeSurfaces()
2877 */
2878
2879struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002880 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002881
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002882 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002883 // Sets up the helper functions called by the function under test to use
2884 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002885 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002886 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002887 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002888 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002889 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002890 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2891 };
2892
2893 OutputComposeSurfacesTest() {
2894 mOutput.setDisplayColorProfileForTest(
2895 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2896 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002897 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002898
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002899 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2900 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002901 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002902 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002903 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002904 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002905 mOutput.mState.dataspace = kDefaultOutputDataspace;
2906 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2907 mOutput.mState.isSecure = false;
2908 mOutput.mState.needsFiltering = false;
2909 mOutput.mState.usesClientComposition = true;
2910 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002911 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002912 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002913
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002914 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002915 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002916 EXPECT_CALL(mCompositionEngine, getTimeStats())
2917 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002918 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2919 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002920 }
2921
Lloyd Pique6818fa52019-12-03 12:32:13 -08002922 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2923 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002924 getInstance()->mReadyFence =
2925 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002926 return nextState<FenceCheckState>();
2927 }
2928 };
2929
2930 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2931 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2932
2933 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2934 };
2935
2936 // Call this member function to start using the mini-DSL defined above.
2937 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2938
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002939 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2940 static constexpr uint32_t kDefaultOutputOrientationFlags =
2941 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002942 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2943 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2944 static constexpr float kDefaultMaxLuminance = 0.9f;
2945 static constexpr float kDefaultAvgLuminance = 0.7f;
2946 static constexpr float kDefaultMinLuminance = 0.1f;
2947
2948 static const Rect kDefaultOutputFrame;
2949 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002950 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002951 static const mat4 kDefaultColorTransformMat;
2952
2953 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002954 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002955 static const HdrCapabilities kHdrCapabilities;
2956
Lloyd Pique56eba802019-08-28 15:45:25 -07002957 StrictMock<mock::CompositionEngine> mCompositionEngine;
2958 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002959 // TODO: make this is a proper mock.
2960 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002961 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2962 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002963 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00002964 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
2965 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
2966 renderengine::ExternalTexture::Usage::READABLE |
2967 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002968
2969 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002970};
2971
2972const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2973const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002974const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002975const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002976const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002977const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2978const HdrCapabilities OutputComposeSurfacesTest::
2979 kHdrCapabilities{{},
2980 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2981 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2982 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002983
Lloyd Piquea76ce462020-01-14 13:06:37 -08002984TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002985 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002986
Lloyd Piquee9eff972020-05-05 12:36:44 -07002987 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002988 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002989
Lloyd Piquea76ce462020-01-14 13:06:37 -08002990 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2991
Lloyd Pique6818fa52019-12-03 12:32:13 -08002992 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002993}
2994
Lloyd Piquee9eff972020-05-05 12:36:44 -07002995TEST_F(OutputComposeSurfacesTest,
2996 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2997 mOutput.mState.usesClientComposition = false;
2998 mOutput.mState.flipClientTarget = true;
2999
Lloyd Pique6818fa52019-12-03 12:32:13 -08003000 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003001 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003002
3003 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3004 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3005
3006 verify().execute().expectAFenceWasReturned();
3007}
3008
3009TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3010 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003011 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003012
3013 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3014
3015 verify().execute().expectNoFenceWasReturned();
3016}
3017
3018TEST_F(OutputComposeSurfacesTest,
3019 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3020 mOutput.mState.usesClientComposition = false;
3021 mOutput.mState.flipClientTarget = true;
3022
3023 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003024 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003025
Lloyd Pique6818fa52019-12-03 12:32:13 -08003026 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003027
Lloyd Pique6818fa52019-12-03 12:32:13 -08003028 verify().execute().expectNoFenceWasReturned();
3029}
Lloyd Pique56eba802019-08-28 15:45:25 -07003030
Lloyd Pique6818fa52019-12-03 12:32:13 -08003031TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3032 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3033 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3034 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003035 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003036 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003037 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003038 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3039 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003040
Lloyd Pique6818fa52019-12-03 12:32:13 -08003041 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003042 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003044
Lloyd Pique6818fa52019-12-03 12:32:13 -08003045 verify().execute().expectAFenceWasReturned();
3046}
Lloyd Pique56eba802019-08-28 15:45:25 -07003047
Lloyd Pique6818fa52019-12-03 12:32:13 -08003048TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003049 LayerFE::LayerSettings r1;
3050 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003051
3052 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3053 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3054
3055 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3056 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3057 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003058 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003059 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003060 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003061 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3062 .WillRepeatedly(
3063 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003064 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003065 clientCompositionLayers.emplace_back(r2);
3066 }));
3067
3068 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003069 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3070 .WillRepeatedly(Return(NO_ERROR));
3071
3072 verify().execute().expectAFenceWasReturned();
3073}
3074
3075TEST_F(OutputComposeSurfacesTest,
3076 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3077 LayerFE::LayerSettings r1;
3078 LayerFE::LayerSettings r2;
3079
3080 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3081 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3082 const constexpr uint32_t kInternalLayerStack = 1234;
3083 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3084
3085 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3086 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3087 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3088 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3089 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3090 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3091 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3092 .WillRepeatedly(
3093 Invoke([&](const Region&,
3094 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3095 clientCompositionLayers.emplace_back(r2);
3096 }));
3097
3098 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003099 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003100 .WillRepeatedly(Return(NO_ERROR));
3101
3102 verify().execute().expectAFenceWasReturned();
3103}
3104
Vishnu Nair9b079a22020-01-21 14:36:08 -08003105TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3106 mOutput.cacheClientCompositionRequests(0);
3107 LayerFE::LayerSettings r1;
3108 LayerFE::LayerSettings r2;
3109
3110 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3111 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3112
3113 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3114 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3115 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003116 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003117 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3118 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3119 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3120 .WillRepeatedly(Return());
3121
3122 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003123 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003124 .Times(2)
3125 .WillOnce(Return(NO_ERROR));
3126
3127 verify().execute().expectAFenceWasReturned();
3128 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3129
3130 verify().execute().expectAFenceWasReturned();
3131 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3132}
3133
3134TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3135 mOutput.cacheClientCompositionRequests(3);
3136 LayerFE::LayerSettings r1;
3137 LayerFE::LayerSettings r2;
3138
3139 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3140 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3141
3142 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3143 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3144 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003145 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003146 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3147 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3148 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3149 .WillRepeatedly(Return());
3150
3151 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003152 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003153 .WillOnce(Return(NO_ERROR));
3154 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3155
3156 verify().execute().expectAFenceWasReturned();
3157 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3158
3159 // We do not expect another call to draw layers.
3160 verify().execute().expectAFenceWasReturned();
3161 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3162}
3163
3164TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3165 LayerFE::LayerSettings r1;
3166 LayerFE::LayerSettings r2;
3167
3168 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3169 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3170
3171 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3172 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3173 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003174 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003175 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3176 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3177 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3178 .WillRepeatedly(Return());
3179
Alec Mouria90a5702021-04-16 16:36:21 +00003180 const auto otherOutputBuffer = std::make_shared<
3181 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3182 renderengine::ExternalTexture::Usage::READABLE |
3183 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003184 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3185 .WillOnce(Return(mOutputBuffer))
3186 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003187 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003188 .WillRepeatedly(Return(NO_ERROR));
3189
3190 verify().execute().expectAFenceWasReturned();
3191 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3192
3193 verify().execute().expectAFenceWasReturned();
3194 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3195}
3196
3197TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3198 LayerFE::LayerSettings r1;
3199 LayerFE::LayerSettings r2;
3200 LayerFE::LayerSettings r3;
3201
3202 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3203 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3204 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3205
3206 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3207 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3208 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003209 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003210 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3211 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3212 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3213 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3214 .WillRepeatedly(Return());
3215
3216 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003217 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003218 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003219 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003220 .WillOnce(Return(NO_ERROR));
3221
3222 verify().execute().expectAFenceWasReturned();
3223 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3224
3225 verify().execute().expectAFenceWasReturned();
3226 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3227}
3228
Lloyd Pique6818fa52019-12-03 12:32:13 -08003229struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3230 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3231 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003232 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003233 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003234 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003235 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3236 .WillRepeatedly(Return());
3237 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3238 }
3239
3240 struct MixedCompositionState
3241 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3242 auto ifMixedCompositionIs(bool used) {
3243 getInstance()->mOutput.mState.usesDeviceComposition = used;
3244 return nextState<OutputUsesHdrState>();
3245 }
3246 };
3247
3248 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3249 auto andIfUsesHdr(bool used) {
3250 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3251 .WillOnce(Return(used));
3252 return nextState<SkipColorTransformState>();
3253 }
3254 };
3255
3256 struct SkipColorTransformState
3257 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3258 auto andIfSkipColorTransform(bool skip) {
3259 // May be called zero or one times.
3260 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3261 .WillRepeatedly(Return(skip));
3262 return nextState<ExpectDisplaySettingsState>();
3263 }
3264 };
3265
3266 struct ExpectDisplaySettingsState
3267 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3268 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003269 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003270 .WillOnce(Return(NO_ERROR));
3271 return nextState<ExecuteState>();
3272 }
3273 };
3274
3275 // Call this member function to start using the mini-DSL defined above.
3276 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3277};
3278
3279TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3280 verify().ifMixedCompositionIs(true)
3281 .andIfUsesHdr(true)
3282 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003283 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003284 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003285 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003286 .execute()
3287 .expectAFenceWasReturned();
3288}
3289
3290TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3291 verify().ifMixedCompositionIs(true)
3292 .andIfUsesHdr(false)
3293 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003294 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003295 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003296 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003297 .execute()
3298 .expectAFenceWasReturned();
3299}
3300
3301TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3302 verify().ifMixedCompositionIs(false)
3303 .andIfUsesHdr(true)
3304 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003305 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003306 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003307 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003308 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003309 .execute()
3310 .expectAFenceWasReturned();
3311}
3312
3313TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3314 verify().ifMixedCompositionIs(false)
3315 .andIfUsesHdr(false)
3316 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003317 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003318 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003320 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 .execute()
3322 .expectAFenceWasReturned();
3323}
3324
3325TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3326 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3327 verify().ifMixedCompositionIs(false)
3328 .andIfUsesHdr(true)
3329 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003330 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003331 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003332 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003333 .execute()
3334 .expectAFenceWasReturned();
3335}
3336
3337struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3338 struct Layer {
3339 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003340 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3341 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003342 }
3343
3344 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003345 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003346 LayerFECompositionState mLayerFEState;
3347 };
3348
3349 OutputComposeSurfacesTest_HandlesProtectedContent() {
3350 mLayer1.mLayerFEState.hasProtectedContent = false;
3351 mLayer2.mLayerFEState.hasProtectedContent = false;
3352
3353 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3354 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3355 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3356 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3357 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3358
3359 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3360
3361 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3362
3363 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003364 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003365 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3366 .WillRepeatedly(Return());
3367 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003368 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003369 .WillRepeatedly(Return(NO_ERROR));
3370 }
3371
3372 Layer mLayer1;
3373 Layer mLayer2;
3374};
3375
3376TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3377 mOutput.mState.isSecure = false;
3378 mLayer2.mLayerFEState.hasProtectedContent = true;
3379 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003380 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3381 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003382
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003383 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003384}
3385
3386TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3387 mOutput.mState.isSecure = true;
3388 mLayer2.mLayerFEState.hasProtectedContent = true;
3389 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3390
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003391 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003392}
3393
3394TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3395 mOutput.mState.isSecure = true;
3396 mLayer2.mLayerFEState.hasProtectedContent = false;
3397 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3398 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3399 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3400 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3401 EXPECT_CALL(*mRenderSurface, setProtected(false));
3402
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003403 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404}
3405
3406TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3407 mOutput.mState.isSecure = true;
3408 mLayer2.mLayerFEState.hasProtectedContent = true;
3409 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3410
3411 // For this test, we also check the call order of key functions.
3412 InSequence seq;
3413
3414 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3415 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3416 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3417 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3418 EXPECT_CALL(*mRenderSurface, setProtected(true));
3419 // Must happen after setting the protected content state.
3420 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003421 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003422
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003423 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003424}
3425
3426TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3427 mOutput.mState.isSecure = true;
3428 mLayer2.mLayerFEState.hasProtectedContent = true;
3429 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3430 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3431 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3432
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003433 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003434}
3435
3436TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3437 mOutput.mState.isSecure = true;
3438 mLayer2.mLayerFEState.hasProtectedContent = true;
3439 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3440 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3441 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3442 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3443
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003444 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003445}
3446
3447TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3448 mOutput.mState.isSecure = true;
3449 mLayer2.mLayerFEState.hasProtectedContent = true;
3450 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3451 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3452 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3453 EXPECT_CALL(*mRenderSurface, setProtected(true));
3454
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003455 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003456}
3457
3458TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3459 mOutput.mState.isSecure = true;
3460 mLayer2.mLayerFEState.hasProtectedContent = true;
3461 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3462 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3463 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3464 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3465
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003466 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003467}
3468
3469struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3470 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3471 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3472 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3473 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003474 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003475 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3476 .WillRepeatedly(Return());
3477 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3478 }
3479};
3480
3481TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3482 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3483
3484 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003485 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003486
3487 // For this test, we also check the call order of key functions.
3488 InSequence seq;
3489
3490 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003491 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003492
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003493 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3494}
3495
3496struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3497 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3498 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3499 mLayer.layerFEState.backgroundBlurRadius = 10;
3500 mOutput.editState().isEnabled = true;
3501
Snild Dolkow9e217d62020-04-22 15:53:42 +02003502 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003503 EXPECT_CALL(mLayer.outputLayer,
3504 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003505 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3506 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003507 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003508 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3509 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3510 .WillRepeatedly(Return(&mLayer.outputLayer));
3511 }
3512
3513 NonInjectedLayer mLayer;
3514 compositionengine::CompositionRefreshArgs mRefreshArgs;
3515};
3516
3517TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3518 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003519 mOutput.updateCompositionState(mRefreshArgs);
3520 mOutput.planComposition();
3521 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003522
3523 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3524 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3525}
3526
3527TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3528 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003529 mOutput.updateCompositionState(mRefreshArgs);
3530 mOutput.planComposition();
3531 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003532
3533 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3534 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003535}
3536
3537/*
3538 * Output::generateClientCompositionRequests()
3539 */
3540
3541struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003542 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003543 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003544 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003545 bool supportsProtectedContent, Region& clearRegion,
3546 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003547 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003548 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003549 }
3550 };
3551
Lloyd Piquea4863342019-12-04 18:45:02 -08003552 struct Layer {
3553 Layer() {
3554 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3555 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003556 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3557 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003558 }
3559
3560 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003561 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003562 LayerFECompositionState mLayerFEState;
3563 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003564 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003565 };
3566
Lloyd Pique56eba802019-08-28 15:45:25 -07003567 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003568 mOutput.mState.needsFiltering = false;
3569
Lloyd Pique56eba802019-08-28 15:45:25 -07003570 mOutput.setDisplayColorProfileForTest(
3571 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3572 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3573 }
3574
Lloyd Pique56eba802019-08-28 15:45:25 -07003575 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3576 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003577 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003578};
3579
Lloyd Piquea4863342019-12-04 18:45:02 -08003580struct GenerateClientCompositionRequestsTest_ThreeLayers
3581 : public GenerateClientCompositionRequestsTest {
3582 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003583 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3584 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3585 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003586 mOutput.mState.transform =
3587 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3588 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003589 mOutput.mState.needsFiltering = false;
3590 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003591
Lloyd Piquea4863342019-12-04 18:45:02 -08003592 for (size_t i = 0; i < mLayers.size(); i++) {
3593 mLayers[i].mOutputLayerState.clearClientTarget = false;
3594 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3595 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003596 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003597 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003598 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3599 mLayers[i].mLayerSettings.alpha = 1.0f;
3600 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003601
Lloyd Piquea4863342019-12-04 18:45:02 -08003602 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3603 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3604 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3605 .WillRepeatedly(Return(true));
3606 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3607 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003608
Lloyd Piquea4863342019-12-04 18:45:02 -08003609 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3610 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003611
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003612 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003613 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003614
Lloyd Piquea4863342019-12-04 18:45:02 -08003615 static const Rect kDisplayFrame;
3616 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003617 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003618
Lloyd Piquea4863342019-12-04 18:45:02 -08003619 std::array<Layer, 3> mLayers;
3620};
Lloyd Pique56eba802019-08-28 15:45:25 -07003621
Lloyd Piquea4863342019-12-04 18:45:02 -08003622const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3623const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003624const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3625 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003626
Lloyd Piquea4863342019-12-04 18:45:02 -08003627TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3628 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3629 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3630 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003631
Lloyd Piquea4863342019-12-04 18:45:02 -08003632 Region accumClearRegion(Rect(10, 11, 12, 13));
3633 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3634 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003635 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003636 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003637}
3638
Lloyd Piquea4863342019-12-04 18:45:02 -08003639TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3640 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3641 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3642 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3643
3644 Region accumClearRegion(Rect(10, 11, 12, 13));
3645 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3646 accumClearRegion, kDisplayDataspace);
3647 EXPECT_EQ(0u, requests.size());
3648 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3649}
3650
3651TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003652 LayerFE::LayerSettings mShadowSettings;
3653 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003654
Ady Abrahameca9d752021-03-03 12:20:00 -08003655 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003656 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003657 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003658 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003659 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003660 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3661 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003662
3663 Region accumClearRegion(Rect(10, 11, 12, 13));
3664 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3665 accumClearRegion, kDisplayDataspace);
3666 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003667 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3668 EXPECT_EQ(mShadowSettings, requests[1]);
3669 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003670
3671 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3672
3673 // Check that a timestamp was set for the layers that generated requests
3674 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3675 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3676 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3677}
3678
3679TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3680 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3681 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3682 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3683 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3684
3685 mLayers[0].mOutputLayerState.clearClientTarget = false;
3686 mLayers[1].mOutputLayerState.clearClientTarget = false;
3687 mLayers[2].mOutputLayerState.clearClientTarget = false;
3688
3689 mLayers[0].mLayerFEState.isOpaque = true;
3690 mLayers[1].mLayerFEState.isOpaque = true;
3691 mLayers[2].mLayerFEState.isOpaque = true;
3692
Ady Abrahameca9d752021-03-03 12:20:00 -08003693 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003694 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003695
3696 Region accumClearRegion(Rect(10, 11, 12, 13));
3697 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3698 accumClearRegion, kDisplayDataspace);
3699 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003700 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003701
3702 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3703}
3704
3705TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3706 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3707 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3708 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3709 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3710
3711 mLayers[0].mOutputLayerState.clearClientTarget = true;
3712 mLayers[1].mOutputLayerState.clearClientTarget = true;
3713 mLayers[2].mOutputLayerState.clearClientTarget = true;
3714
3715 mLayers[0].mLayerFEState.isOpaque = false;
3716 mLayers[1].mLayerFEState.isOpaque = false;
3717 mLayers[2].mLayerFEState.isOpaque = false;
3718
Ady Abrahameca9d752021-03-03 12:20:00 -08003719 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003720 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003721
3722 Region accumClearRegion(Rect(10, 11, 12, 13));
3723 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3724 accumClearRegion, kDisplayDataspace);
3725 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003726 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003727
3728 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3729}
3730
3731TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003732 // If client composition is performed with some layers set to use device
3733 // composition, device layers after the first layer (device or client) will
3734 // clear the frame buffer if they are opaque and if that layer has a flag
3735 // set to do so. The first layer is skipped as the frame buffer is already
3736 // expected to be clear.
3737
Lloyd Piquea4863342019-12-04 18:45:02 -08003738 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3739 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3740 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003741
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 mLayers[0].mOutputLayerState.clearClientTarget = true;
3743 mLayers[1].mOutputLayerState.clearClientTarget = true;
3744 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003745
Lloyd Piquea4863342019-12-04 18:45:02 -08003746 mLayers[0].mLayerFEState.isOpaque = true;
3747 mLayers[1].mLayerFEState.isOpaque = true;
3748 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003749 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003750 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003751
3752 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3753 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003754 false, /* needs filtering */
3755 false, /* secure */
3756 false, /* supports protected content */
3757 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003758 kDisplayViewport,
3759 kDisplayDataspace,
3760 false /* realContentIsVisible */,
3761 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003762 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003763 };
3764 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3765 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003766 false, /* needs filtering */
3767 false, /* secure */
3768 false, /* supports protected content */
3769 accumClearRegion,
3770 kDisplayViewport,
3771 kDisplayDataspace,
3772 true /* realContentIsVisible */,
3773 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003774 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003775 };
3776
3777 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3778 mBlackoutSettings.source.buffer.buffer = nullptr;
3779 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3780 mBlackoutSettings.alpha = 0.f;
3781 mBlackoutSettings.disableBlending = true;
3782
Ady Abrahameca9d752021-03-03 12:20:00 -08003783 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003784 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003785 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003786 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3787
Lloyd Piquea4863342019-12-04 18:45:02 -08003788 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3789 accumClearRegion, kDisplayDataspace);
3790 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003791
Lloyd Piquea4863342019-12-04 18:45:02 -08003792 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003793 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003794
Vishnu Nair9b079a22020-01-21 14:36:08 -08003795 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003796
Lloyd Piquea4863342019-12-04 18:45:02 -08003797 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3798}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003799
Lloyd Piquea4863342019-12-04 18:45:02 -08003800TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3801 clippedVisibleRegionUsedToGenerateRequest) {
3802 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3803 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3804 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003805
Lloyd Piquea4863342019-12-04 18:45:02 -08003806 Region accumClearRegion(Rect(10, 11, 12, 13));
3807
3808 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3809 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003810 false, /* needs filtering */
3811 false, /* secure */
3812 false, /* supports protected content */
3813 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003814 kDisplayViewport,
3815 kDisplayDataspace,
3816 true /* realContentIsVisible */,
3817 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003818 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003819 };
3820 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3821 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003822 false, /* needs filtering */
3823 false, /* secure */
3824 false, /* supports protected content */
3825 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003826 kDisplayViewport,
3827 kDisplayDataspace,
3828 true /* realContentIsVisible */,
3829 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003830 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 };
3832 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3833 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003834 false, /* needs filtering */
3835 false, /* secure */
3836 false, /* supports protected content */
3837 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003838 kDisplayViewport,
3839 kDisplayDataspace,
3840 true /* realContentIsVisible */,
3841 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003842 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003843 };
3844
Ady Abrahameca9d752021-03-03 12:20:00 -08003845 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003846 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003847 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003848 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003849 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003850 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003851
3852 static_cast<void>(
3853 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3854 accumClearRegion, kDisplayDataspace));
3855}
3856
3857TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3858 perLayerNeedsFilteringUsedToGenerateRequests) {
3859 mOutput.mState.needsFiltering = false;
3860 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3861
3862 Region accumClearRegion(Rect(10, 11, 12, 13));
3863
3864 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3865 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003866 true, /* needs filtering */
3867 false, /* secure */
3868 false, /* supports protected content */
3869 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003870 kDisplayViewport,
3871 kDisplayDataspace,
3872 true /* realContentIsVisible */,
3873 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003874 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003875 };
3876 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3877 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003878 false, /* needs filtering */
3879 false, /* secure */
3880 false, /* supports protected content */
3881 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003882 kDisplayViewport,
3883 kDisplayDataspace,
3884 true /* realContentIsVisible */,
3885 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003886 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003887 };
3888 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3889 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 false, /* needs filtering */
3891 false, /* secure */
3892 false, /* supports protected content */
3893 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003894 kDisplayViewport,
3895 kDisplayDataspace,
3896 true /* realContentIsVisible */,
3897 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003898 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 };
3900
Ady Abrahameca9d752021-03-03 12:20:00 -08003901 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003902 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003903 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003904 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003905 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003906 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003907
3908 static_cast<void>(
3909 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3910 accumClearRegion, kDisplayDataspace));
3911}
3912
3913TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3914 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3915 mOutput.mState.needsFiltering = true;
3916 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3917
3918 Region accumClearRegion(Rect(10, 11, 12, 13));
3919
3920 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3921 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003922 true, /* needs filtering */
3923 false, /* secure */
3924 false, /* supports protected content */
3925 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003926 kDisplayViewport,
3927 kDisplayDataspace,
3928 true /* realContentIsVisible */,
3929 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003930 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003931
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 };
3933 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3934 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003935 true, /* needs filtering */
3936 false, /* secure */
3937 false, /* supports protected content */
3938 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003939 kDisplayViewport,
3940 kDisplayDataspace,
3941 true /* realContentIsVisible */,
3942 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003943 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003944 };
3945 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3946 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003947 true, /* needs filtering */
3948 false, /* secure */
3949 false, /* supports protected content */
3950 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003951 kDisplayViewport,
3952 kDisplayDataspace,
3953 true /* realContentIsVisible */,
3954 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003955 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 };
3957
Ady Abrahameca9d752021-03-03 12:20:00 -08003958 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003959 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003960 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003961 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003962 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003963 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003964
3965 static_cast<void>(
3966 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3967 accumClearRegion, kDisplayDataspace));
3968}
3969
3970TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3971 wholeOutputSecurityUsedToGenerateRequests) {
3972 mOutput.mState.isSecure = true;
3973
3974 Region accumClearRegion(Rect(10, 11, 12, 13));
3975
3976 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3977 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003978 false, /* needs filtering */
3979 true, /* secure */
3980 false, /* supports protected content */
3981 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003982 kDisplayViewport,
3983 kDisplayDataspace,
3984 true /* realContentIsVisible */,
3985 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003986 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003987 };
3988 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3989 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003990 false, /* needs filtering */
3991 true, /* secure */
3992 false, /* supports protected content */
3993 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003994 kDisplayViewport,
3995 kDisplayDataspace,
3996 true /* realContentIsVisible */,
3997 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003998 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 };
4000 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4001 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004002 false, /* needs filtering */
4003 true, /* secure */
4004 false, /* supports protected content */
4005 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004006 kDisplayViewport,
4007 kDisplayDataspace,
4008 true /* realContentIsVisible */,
4009 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004010 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 };
4012
Ady Abrahameca9d752021-03-03 12:20:00 -08004013 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004014 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004015 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004016 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004017 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004018 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004019
4020 static_cast<void>(
4021 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4022 accumClearRegion, kDisplayDataspace));
4023}
4024
4025TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4026 protectedContentSupportUsedToGenerateRequests) {
4027 Region accumClearRegion(Rect(10, 11, 12, 13));
4028
4029 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4030 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004031 false, /* needs filtering */
4032 false, /* secure */
4033 true, /* supports protected content */
4034 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004035 kDisplayViewport,
4036 kDisplayDataspace,
4037 true /* realContentIsVisible */,
4038 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004039 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004040 };
4041 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4042 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004043 false, /* needs filtering */
4044 false, /* secure */
4045 true, /* supports protected content */
4046 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004047 kDisplayViewport,
4048 kDisplayDataspace,
4049 true /* realContentIsVisible */,
4050 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004051 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004052 };
4053 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4054 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004055 false, /* needs filtering */
4056 false, /* secure */
4057 true, /* supports protected content */
4058 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004059 kDisplayViewport,
4060 kDisplayDataspace,
4061 true /* realContentIsVisible */,
4062 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004063 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004064 };
4065
Ady Abrahameca9d752021-03-03 12:20:00 -08004066 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004067 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004068 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004069 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004070 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004071 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004072
4073 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4074 accumClearRegion,
4075 kDisplayDataspace));
4076}
4077
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004078TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004079 InjectedLayer layer1;
4080 InjectedLayer layer2;
4081 InjectedLayer layer3;
4082
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004083 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004084 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004085 EXPECT_CALL(*layer1.outputLayer,
4086 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004087 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004088 EXPECT_CALL(*layer2.outputLayer,
4089 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004090 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004091 EXPECT_CALL(*layer3.outputLayer,
4092 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004093
Lloyd Piquede196652020-01-22 17:29:58 -08004094 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004095
Lloyd Piquede196652020-01-22 17:29:58 -08004096 injectOutputLayer(layer1);
4097 injectOutputLayer(layer2);
4098 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004099
4100 mOutput->editState().isEnabled = true;
4101
4102 CompositionRefreshArgs args;
4103 args.updatingGeometryThisFrame = false;
4104 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004105 mOutput->updateCompositionState(args);
4106 mOutput->planComposition();
4107 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004108}
4109
Lucas Dupinc3800b82020-10-02 16:24:48 -07004110TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4111 InjectedLayer layer1;
4112 InjectedLayer layer2;
4113 InjectedLayer layer3;
4114
4115 // Layer requesting blur, or below, should request client composition.
4116 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004117 EXPECT_CALL(*layer1.outputLayer,
4118 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004119 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004120 EXPECT_CALL(*layer2.outputLayer,
4121 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004122 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004123 EXPECT_CALL(*layer3.outputLayer,
4124 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004125
4126 BlurRegion region;
4127 layer2.layerFEState.blurRegions.push_back(region);
4128
4129 injectOutputLayer(layer1);
4130 injectOutputLayer(layer2);
4131 injectOutputLayer(layer3);
4132
4133 mOutput->editState().isEnabled = true;
4134
4135 CompositionRefreshArgs args;
4136 args.updatingGeometryThisFrame = false;
4137 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004138 mOutput->updateCompositionState(args);
4139 mOutput->planComposition();
4140 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004141}
4142
Lloyd Piquea4863342019-12-04 18:45:02 -08004143TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4144 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4145 // one layer on the left covering the left side of the output, and one layer
4146 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004147
4148 const Rect kPortraitFrame(0, 0, 1000, 2000);
4149 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004150 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004151 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004152 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004153
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004154 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4155 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4156 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004157 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4158 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004159 mOutput.mState.needsFiltering = false;
4160 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004161
Lloyd Piquea4863342019-12-04 18:45:02 -08004162 Layer leftLayer;
4163 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004164
Lloyd Piquea4863342019-12-04 18:45:02 -08004165 leftLayer.mOutputLayerState.clearClientTarget = false;
4166 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4167 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004168 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004169
Lloyd Piquea4863342019-12-04 18:45:02 -08004170 rightLayer.mOutputLayerState.clearClientTarget = false;
4171 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4172 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004173 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004174
4175 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4176 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4177 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4178 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4179 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4180
4181 Region accumClearRegion(Rect(10, 11, 12, 13));
4182
4183 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4184 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004185 false, /* needs filtering */
4186 true, /* secure */
4187 true, /* supports protected content */
4188 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004189 kPortraitViewport,
4190 kOutputDataspace,
4191 true /* realContentIsVisible */,
4192 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004193 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004194 };
4195
4196 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4197 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004198 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004199 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004200
4201 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4202 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004203 false, /* needs filtering */
4204 true, /* secure */
4205 true, /* supports protected content */
4206 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004207 kPortraitViewport,
4208 kOutputDataspace,
4209 true /* realContentIsVisible */,
4210 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004211 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004212 };
4213
4214 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4215 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004216 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004217 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004218
4219 constexpr bool supportsProtectedContent = true;
4220 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4221 accumClearRegion, kOutputDataspace);
4222 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004223 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4224 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004225}
4226
Vishnu Naira483b4a2019-12-12 15:07:52 -08004227TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4228 shadowRegionOnlyVisibleSkipsContentComposition) {
4229 const Rect kContentWithShadow(40, 40, 70, 90);
4230 const Rect kContent(50, 50, 60, 80);
4231 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4232 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4233
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004234 Region accumClearRegion(Rect(10, 11, 12, 13));
4235 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4236 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004237 false, /* needs filtering */
4238 false, /* secure */
4239 false, /* supports protected content */
4240 accumClearRegion,
4241 kDisplayViewport,
4242 kDisplayDataspace,
4243 false /* realContentIsVisible */,
4244 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004245 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004246 };
4247
Vishnu Nair9b079a22020-01-21 14:36:08 -08004248 LayerFE::LayerSettings mShadowSettings;
4249 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004250
4251 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4252 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4253
4254 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4255 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004256 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004257 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004258
Vishnu Naira483b4a2019-12-12 15:07:52 -08004259 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4260 accumClearRegion, kDisplayDataspace);
4261 ASSERT_EQ(1u, requests.size());
4262
Vishnu Nair9b079a22020-01-21 14:36:08 -08004263 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004264}
4265
4266TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4267 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4268 const Rect kContentWithShadow(40, 40, 70, 90);
4269 const Rect kContent(50, 50, 60, 80);
4270 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4271 const Region kPartialContentWithPartialShadowRegion =
4272 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4273
Vishnu Nair9b079a22020-01-21 14:36:08 -08004274 LayerFE::LayerSettings mShadowSettings;
4275 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004276
4277 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4278 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4279
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004280 Region accumClearRegion(Rect(10, 11, 12, 13));
4281 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4282 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004283 false, /* needs filtering */
4284 false, /* secure */
4285 false, /* supports protected content */
4286 accumClearRegion,
4287 kDisplayViewport,
4288 kDisplayDataspace,
4289 true /* realContentIsVisible */,
4290 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004291 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004292 };
4293
Vishnu Naira483b4a2019-12-12 15:07:52 -08004294 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4295 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004296 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4298 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004299
Vishnu Naira483b4a2019-12-12 15:07:52 -08004300 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4301 accumClearRegion, kDisplayDataspace);
4302 ASSERT_EQ(2u, requests.size());
4303
Vishnu Nair9b079a22020-01-21 14:36:08 -08004304 EXPECT_EQ(mShadowSettings, requests[0]);
4305 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004306}
4307
Lloyd Pique32cbe282018-10-19 13:09:22 -07004308} // namespace
4309} // namespace android::compositionengine