blob: 6677f408ad8f7c7094a2a6f08f31629c085aef69 [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>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040033#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000034
Lloyd Pique17ca7422019-11-14 14:24:10 -080035#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080036#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037#include "RegionMatcher.h"
Alec Mouria90a5702021-04-16 16:36:21 +000038#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070039
40namespace android::compositionengine {
41namespace {
42
Lloyd Pique56eba802019-08-28 15:45:25 -070043using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080044using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080045using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080046using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080047using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080048using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080049using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080050using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::Invoke;
52using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080053using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080054using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080055using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080056using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070057using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080059using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070060using testing::StrictMock;
61
Lloyd Pique56eba802019-08-28 15:45:25 -070062constexpr auto TR_IDENT = 0u;
63constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080064constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070065
Lloyd Pique3eb1b212019-03-07 21:15:40 -080066const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080067const mat4 kNonIdentityHalf = mat4() * 0.5f;
68const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069
Lloyd Pique17ca7422019-11-14 14:24:10 -080070constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
71 static_cast<OutputColorSetting>(0x100);
72
Lloyd Piquefaa3f192019-11-14 14:05:09 -080073struct OutputPartialMockBase : public impl::Output {
74 // compositionengine::Output overrides
75 const OutputCompositionState& getState() const override { return mState; }
76 OutputCompositionState& editState() override { return mState; }
77
78 // Use mocks for all the remaining virtual functions
79 // not implemented by the base implementation class.
80 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
81 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080082 MOCK_METHOD2(ensureOutputLayer,
83 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080084 MOCK_METHOD0(finalizePendingOutputLayers, void());
85 MOCK_METHOD0(clearOutputLayers, void());
86 MOCK_CONST_METHOD1(dumpState, void(std::string&));
87 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080089 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
90
91 impl::OutputCompositionState mState;
92};
93
Lloyd Piquede196652020-01-22 17:29:58 -080094struct InjectedLayer {
95 InjectedLayer() {
96 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
97 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
98 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
99
100 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800101 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
102 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800103 }
104
105 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
106 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
107 LayerFECompositionState layerFEState;
108 impl::OutputLayerCompositionState outputLayerState;
109};
110
111struct NonInjectedLayer {
112 NonInjectedLayer() {
113 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
114 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
115 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
116
117 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800118 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
119 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800120 }
121
122 mock::OutputLayer outputLayer;
123 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
124 LayerFECompositionState layerFEState;
125 impl::OutputLayerCompositionState outputLayerState;
126};
127
Lloyd Pique66d68602019-02-13 14:23:31 -0800128struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700129 class Output : public impl::Output {
130 public:
131 using impl::Output::injectOutputLayerForTest;
132 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
133 };
134
135 static std::shared_ptr<Output> createOutput(
136 const compositionengine::CompositionEngine& compositionEngine) {
137 return impl::createOutputTemplated<Output>(compositionEngine);
138 }
139
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700141 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700142 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700143 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800144
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200145 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700147
Lloyd Piquede196652020-01-22 17:29:58 -0800148 void injectOutputLayer(InjectedLayer& layer) {
149 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
150 }
151
152 void injectNullOutputLayer() {
153 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
154 }
155
Lloyd Piqueef958122019-02-05 18:00:12 -0800156 static const Rect kDefaultDisplaySize;
157
Lloyd Pique32cbe282018-10-19 13:09:22 -0700158 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700159 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700160 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700161 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700162};
163
Lloyd Piqueef958122019-02-05 18:00:12 -0800164const Rect OutputTest::kDefaultDisplaySize{100, 200};
165
Lloyd Pique17ca7422019-11-14 14:24:10 -0800166using ColorProfile = compositionengine::Output::ColorProfile;
167
168void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
169 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
170 toString(profile.mode).c_str(), profile.mode,
171 toString(profile.dataspace).c_str(), profile.dataspace,
172 toString(profile.renderIntent).c_str(), profile.renderIntent,
173 toString(profile.colorSpaceAgnosticDataspace).c_str(),
174 profile.colorSpaceAgnosticDataspace);
175}
176
177// Checks for a ColorProfile match
178MATCHER_P(ColorProfileEq, expected, "") {
179 std::string buf;
180 buf.append("ColorProfiles are not equal\n");
181 dumpColorProfile(expected, buf, "expected value");
182 dumpColorProfile(arg, buf, "actual value");
183 *result_listener << buf;
184
185 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
186 (expected.renderIntent == arg.renderIntent) &&
187 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
188}
189
Lloyd Pique66d68602019-02-13 14:23:31 -0800190/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700191 * Basic construction
192 */
193
Lloyd Pique31cb2942018-10-19 17:23:03 -0700194TEST_F(OutputTest, canInstantiateOutput) {
195 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700196 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
198
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700199 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200
201 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700202 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700204 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
205
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208
Lloyd Pique66d68602019-02-13 14:23:31 -0800209/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210 * Output::setCompositionEnabled()
211 */
212
213TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700214 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 EXPECT_TRUE(mOutput->getState().isEnabled);
219 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220}
221
222TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 EXPECT_TRUE(mOutput->getState().isEnabled);
228 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229}
230
231TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 EXPECT_FALSE(mOutput->getState().isEnabled);
237 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238}
239
Lloyd Pique66d68602019-02-13 14:23:31 -0800240/*
Alec Mouri023c1882021-05-08 16:36:33 -0700241 * Output::setLayerCachingEnabled()
242 */
243
244TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
245 const auto kSize = ui::Size(1, 1);
246 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
247 mOutput->setLayerCachingEnabled(false);
248 mOutput->setLayerCachingEnabled(true);
249
250 EXPECT_TRUE(mOutput->plannerEnabled());
251}
252
253TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
254 const auto kSize = ui::Size(1, 1);
255 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
256 mOutput->setLayerCachingEnabled(true);
257 mOutput->setLayerCachingEnabled(false);
258
259 EXPECT_FALSE(mOutput->plannerEnabled());
260}
261
Alec Mouric773472b2021-05-19 14:29:05 -0700262TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
263 renderengine::mock::RenderEngine renderEngine;
264 const auto kSize = ui::Size(1, 1);
265 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
266 mOutput->setLayerCachingEnabled(true);
267
268 // Inject some layers
269 InjectedLayer layer;
270 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
271 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
272 renderengine::ExternalTexture::Usage::READABLE |
273 renderengine::ExternalTexture::Usage::WRITEABLE);
274 injectOutputLayer(layer);
275 // inject a null layer to check for null exceptions
276 injectNullOutputLayer();
277
278 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
279 mOutput->setLayerCachingEnabled(false);
280 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
281}
282
Alec Mouri023c1882021-05-08 16:36:33 -0700283/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700284 * Output::setProjection()
285 */
286
Marin Shalamanov209ae612020-10-01 00:17:39 +0200287TEST_F(OutputTest, setProjectionWorks) {
288 const Rect displayRect{0, 0, 1000, 2000};
289 mOutput->editState().displaySpace.bounds = displayRect;
290 mOutput->editState().framebufferSpace.bounds = displayRect;
291
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200292 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200293 const Rect frame{50, 60, 100, 100};
294 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700295
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200296 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700297
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200298 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200299 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
300 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200301
302 const auto state = mOutput->getState();
303 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
304 EXPECT_EQ(viewport, state.layerStackSpace.content);
305 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
306
307 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
308 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
309 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
310
311 EXPECT_EQ(displayRect, state.displaySpace.bounds);
312 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
313 EXPECT_EQ(orientation, state.displaySpace.orientation);
314
315 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
316 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
317 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
318
319 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700320
321 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200322}
323
324TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
325 const Rect displayRect{0, 0, 1000, 2000};
326 const Rect framebufferRect{0, 0, 500, 1000};
327 mOutput->editState().displaySpace.bounds = displayRect;
328 mOutput->editState().framebufferSpace.bounds = framebufferRect;
329
330 const ui::Rotation orientation = ui::ROTATION_90;
331 const Rect frame{50, 60, 100, 100};
332 const Rect viewport{10, 20, 30, 40};
333
334 mOutput->setProjection(orientation, viewport, frame);
335
336 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
337 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
338 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
339
340 const auto state = mOutput->getState();
341 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
342 EXPECT_EQ(viewport, state.layerStackSpace.content);
343 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
344
345 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
346 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
347 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
348
349 EXPECT_EQ(displayRect, state.displaySpace.bounds);
350 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
351 EXPECT_EQ(orientation, state.displaySpace.orientation);
352
353 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
354 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
355 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
356
357 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700358}
359
Lloyd Pique66d68602019-02-13 14:23:31 -0800360/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200361 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700362 */
363
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200364TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
365 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
366 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
367 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
368 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
369 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
370 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
371 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
372 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
373 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
374 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700375
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200376 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700377
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700379
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200380 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700381
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200382 const auto state = mOutput->getState();
383
384 const Rect displayRect(newDisplaySize);
385 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
386 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
387 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200388
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200389 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200390 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200391
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200396 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
397
398 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
399
400 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700401}
402
Lloyd Pique66d68602019-02-13 14:23:31 -0800403/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700404 * Output::setLayerStackFilter()
405 */
406
407TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700409 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700411 EXPECT_TRUE(mOutput->getState().layerStackInternal);
412 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700413
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700414 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415}
416
Lloyd Pique66d68602019-02-13 14:23:31 -0800417/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700418 * Output::setColorTransform
419 */
420
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800421TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700422 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700423
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800424 // If no colorTransformMatrix is set the update should be skipped.
425 CompositionRefreshArgs refreshArgs;
426 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700427
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700428 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700429
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800430 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700431 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800432
433 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435}
Lloyd Piqueef958122019-02-05 18:00:12 -0800436
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440 // Attempting to set the same colorTransformMatrix that is already set should
441 // also skip the update.
442 CompositionRefreshArgs refreshArgs;
443 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700445 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700446
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800447 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700448 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449
450 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452}
453
454TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456
457 // Setting a different colorTransformMatrix should perform the update.
458 CompositionRefreshArgs refreshArgs;
459 refreshArgs.colorTransformMatrix = kIdentity;
460
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462
463 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700469
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800470TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700472
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473 // Setting a different colorTransformMatrix should perform the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800478
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800479 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484}
485
486TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488
489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494
495 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700500}
501
Lloyd Pique66d68602019-02-13 14:23:31 -0800502/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800503 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700504 */
505
Lloyd Pique17ca7422019-11-14 14:24:10 -0800506using OutputSetColorProfileTest = OutputTest;
507
508TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800509 using ColorProfile = Output::ColorProfile;
510
Lloyd Piquef5275482019-01-29 18:42:42 -0800511 EXPECT_CALL(*mDisplayColorProfile,
512 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
513 ui::Dataspace::UNKNOWN))
514 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800515 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700516
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700517 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
518 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
519 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700520
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700521 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
522 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
523 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
524 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800525
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800527}
528
Lloyd Pique17ca7422019-11-14 14:24:10 -0800529TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800530 using ColorProfile = Output::ColorProfile;
531
Lloyd Piquef5275482019-01-29 18:42:42 -0800532 EXPECT_CALL(*mDisplayColorProfile,
533 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
534 ui::Dataspace::UNKNOWN))
535 .WillOnce(Return(ui::Dataspace::UNKNOWN));
536
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
538 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
539 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
540 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800541
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
543 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
544 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800545
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700546 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700547}
548
Lloyd Pique66d68602019-02-13 14:23:31 -0800549/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700550 * Output::setRenderSurface()
551 */
552
553TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
554 const ui::Size newDisplaySize{640, 480};
555
556 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
557 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
558
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700560
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200561 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700562}
563
Lloyd Pique66d68602019-02-13 14:23:31 -0800564/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000565 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700566 */
567
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000568TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
569 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200570 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700571 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700572
573 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700575
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000576 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700577 }
578}
579
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000580TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
581 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200582 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700583 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700584
585 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700586 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700587
588 // The dirtyRegion should be clipped to the display bounds.
589 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
590 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700591}
592
Lloyd Pique66d68602019-02-13 14:23:31 -0800593/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800594 * Output::belongsInOutput()
595 */
596
597TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
598 const uint32_t layerStack1 = 123u;
599 const uint32_t layerStack2 = 456u;
600
601 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700602 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800603
Lloyd Piquec6687342019-03-07 21:34:57 -0800604 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700605 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
606 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800607
Lloyd Piqueef36b002019-01-23 17:52:04 -0800608 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700609 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
610 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
611 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
612 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613
614 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700615 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800616
617 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700618 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
619 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
620 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
621 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800622}
623
Lloyd Piquede196652020-01-22 17:29:58 -0800624TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
625 NonInjectedLayer layer;
626 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800627
Lloyd Piquede196652020-01-22 17:29:58 -0800628 // If the layer has no composition state, it does not belong to any output.
629 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
630 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
631}
632
633TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
634 NonInjectedLayer layer;
635 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800636
637 const uint32_t layerStack1 = 123u;
638 const uint32_t layerStack2 = 456u;
639
640 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700641 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800642
Lloyd Pique66c20c42019-03-07 21:44:02 -0800643 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800644 layer.layerFEState.layerStackId = std::nullopt;
645 layer.layerFEState.internalOnly = false;
646 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Lloyd Piquede196652020-01-22 17:29:58 -0800648 layer.layerFEState.layerStackId = std::nullopt;
649 layer.layerFEState.internalOnly = true;
650 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800651
652 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800653 layer.layerFEState.layerStackId = layerStack1;
654 layer.layerFEState.internalOnly = false;
655 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Lloyd Piquede196652020-01-22 17:29:58 -0800657 layer.layerFEState.layerStackId = layerStack1;
658 layer.layerFEState.internalOnly = true;
659 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Lloyd Piquede196652020-01-22 17:29:58 -0800661 layer.layerFEState.layerStackId = layerStack2;
662 layer.layerFEState.internalOnly = true;
663 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Lloyd Piquede196652020-01-22 17:29:58 -0800665 layer.layerFEState.layerStackId = layerStack2;
666 layer.layerFEState.internalOnly = false;
667 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800668
669 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700670 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800671
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800673 layer.layerFEState.layerStackId = layerStack1;
674 layer.layerFEState.internalOnly = false;
675 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Lloyd Piquede196652020-01-22 17:29:58 -0800677 layer.layerFEState.layerStackId = layerStack1;
678 layer.layerFEState.internalOnly = true;
679 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Lloyd Piquede196652020-01-22 17:29:58 -0800681 layer.layerFEState.layerStackId = layerStack2;
682 layer.layerFEState.internalOnly = true;
683 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800684
Lloyd Piquede196652020-01-22 17:29:58 -0800685 layer.layerFEState.layerStackId = layerStack2;
686 layer.layerFEState.internalOnly = false;
687 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800688}
689
Lloyd Pique66d68602019-02-13 14:23:31 -0800690/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800691 * Output::getOutputLayerForLayer()
692 */
693
694TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800695 InjectedLayer layer1;
696 InjectedLayer layer2;
697 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800698
Lloyd Piquede196652020-01-22 17:29:58 -0800699 injectOutputLayer(layer1);
700 injectNullOutputLayer();
701 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702
703 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800704 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
705 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
707 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800708 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
709 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
710 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800711
712 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800713 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
714 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
715 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800716}
717
Lloyd Pique66d68602019-02-13 14:23:31 -0800718/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800719 * Output::setReleasedLayers()
720 */
721
722using OutputSetReleasedLayersTest = OutputTest;
723
724TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
725 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
726 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
727 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
728
729 Output::ReleasedLayers layers;
730 layers.push_back(layer1FE);
731 layers.push_back(layer2FE);
732 layers.push_back(layer3FE);
733
734 mOutput->setReleasedLayers(std::move(layers));
735
736 const auto& setLayers = mOutput->getReleasedLayersForTest();
737 ASSERT_EQ(3u, setLayers.size());
738 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
739 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
740 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
741}
742
743/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800744 * Output::updateLayerStateFromFE()
745 */
746
Lloyd Piquede196652020-01-22 17:29:58 -0800747using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748
749TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
750 CompositionRefreshArgs refreshArgs;
751
752 mOutput->updateLayerStateFromFE(refreshArgs);
753}
754
Lloyd Piquede196652020-01-22 17:29:58 -0800755TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
756 InjectedLayer layer1;
757 InjectedLayer layer2;
758 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800759
Lloyd Piquede196652020-01-22 17:29:58 -0800760 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
761 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
762 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763
764 injectOutputLayer(layer1);
765 injectOutputLayer(layer2);
766 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800767
768 CompositionRefreshArgs refreshArgs;
769 refreshArgs.updatingGeometryThisFrame = false;
770
771 mOutput->updateLayerStateFromFE(refreshArgs);
772}
773
Lloyd Piquede196652020-01-22 17:29:58 -0800774TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
775 InjectedLayer layer1;
776 InjectedLayer layer2;
777 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800778
Lloyd Piquede196652020-01-22 17:29:58 -0800779 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
780 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
781 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782
783 injectOutputLayer(layer1);
784 injectOutputLayer(layer2);
785 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800786
787 CompositionRefreshArgs refreshArgs;
788 refreshArgs.updatingGeometryThisFrame = true;
789
790 mOutput->updateLayerStateFromFE(refreshArgs);
791}
792
793/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800794 * Output::updateAndWriteCompositionState()
795 */
796
Lloyd Piquede196652020-01-22 17:29:58 -0800797using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800798
799TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
800 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800801
802 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800803 mOutput->updateCompositionState(args);
804 mOutput->planComposition();
805 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800806}
807
Lloyd Piqueef63b612019-11-14 13:19:56 -0800808TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800809 InjectedLayer layer1;
810 InjectedLayer layer2;
811 InjectedLayer layer3;
812
Lloyd Piqueef63b612019-11-14 13:19:56 -0800813 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800814
Lloyd Piquede196652020-01-22 17:29:58 -0800815 injectOutputLayer(layer1);
816 injectOutputLayer(layer2);
817 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818
819 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800820 mOutput->updateCompositionState(args);
821 mOutput->planComposition();
822 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800823}
824
825TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800826 InjectedLayer layer1;
827 InjectedLayer layer2;
828 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800829
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400830 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800832 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400833 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
834 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200839 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800843
844 injectOutputLayer(layer1);
845 injectOutputLayer(layer2);
846 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
848 mOutput->editState().isEnabled = true;
849
850 CompositionRefreshArgs args;
851 args.updatingGeometryThisFrame = false;
852 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200853 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800854 mOutput->updateCompositionState(args);
855 mOutput->planComposition();
856 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800857}
858
859TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800860 InjectedLayer layer1;
861 InjectedLayer layer2;
862 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400864 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200865 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800866 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400867 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200869 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400871 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200873 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800874 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400875 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800877
878 injectOutputLayer(layer1);
879 injectOutputLayer(layer2);
880 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881
882 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800883
884 CompositionRefreshArgs args;
885 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800886 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800887 mOutput->updateCompositionState(args);
888 mOutput->planComposition();
889 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890}
891
892TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800893 InjectedLayer layer1;
894 InjectedLayer layer2;
895 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800896
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400897 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200898 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800899 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400900 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
901 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200902 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800903 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400904 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
905 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200906 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800907 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800910
911 injectOutputLayer(layer1);
912 injectOutputLayer(layer2);
913 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800914
915 mOutput->editState().isEnabled = true;
916
917 CompositionRefreshArgs args;
918 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800919 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800920 mOutput->updateCompositionState(args);
921 mOutput->planComposition();
922 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800923}
924
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400925TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
926 renderengine::mock::RenderEngine renderEngine;
927 InjectedLayer layer0;
928 InjectedLayer layer1;
929 InjectedLayer layer2;
930 InjectedLayer layer3;
931
932 InSequence seq;
933 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
934 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937
938 uint32_t z = 0;
939 EXPECT_CALL(*layer0.outputLayer,
940 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
941 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
942
943 // After calling planComposition (which clears overrideInfo), this test sets
944 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
945 // comes first, setting isPeekingThrough to true and zIsOverridden to true
946 // for it and the following layers.
947 EXPECT_CALL(*layer3.outputLayer,
948 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
949 /*zIsOverridden*/ true, /*isPeekingThrough*/
950 true));
951 EXPECT_CALL(*layer1.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
954 EXPECT_CALL(*layer2.outputLayer,
955 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
956 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
957
958 injectOutputLayer(layer0);
959 injectOutputLayer(layer1);
960 injectOutputLayer(layer2);
961 injectOutputLayer(layer3);
962
963 mOutput->editState().isEnabled = true;
964
965 CompositionRefreshArgs args;
966 args.updatingGeometryThisFrame = true;
967 args.devOptForceClientComposition = false;
968 mOutput->updateCompositionState(args);
969 mOutput->planComposition();
970
971 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
972 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
973 renderengine::ExternalTexture::Usage::READABLE |
974 renderengine::ExternalTexture::Usage::WRITEABLE);
975 layer1.outputLayerState.overrideInfo.buffer = buffer;
976 layer2.outputLayerState.overrideInfo.buffer = buffer;
977 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
978 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
979
980 mOutput->writeCompositionState(args);
981}
982
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800983/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800984 * Output::prepareFrame()
985 */
986
987struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800988 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800989 // Sets up the helper functions called by the function under test to use
990 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800991 MOCK_METHOD0(chooseCompositionStrategy, void());
992 };
993
994 OutputPrepareFrameTest() {
995 mOutput.setDisplayColorProfileForTest(
996 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
997 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
998 }
999
1000 StrictMock<mock::CompositionEngine> mCompositionEngine;
1001 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1002 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001003 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001004};
1005
1006TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1007 mOutput.editState().isEnabled = false;
1008
1009 mOutput.prepareFrame();
1010}
1011
1012TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1013 mOutput.editState().isEnabled = true;
1014 mOutput.editState().usesClientComposition = false;
1015 mOutput.editState().usesDeviceComposition = true;
1016
1017 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001018 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001019 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1020
1021 mOutput.prepareFrame();
1022}
1023
1024// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1025// base chooseCompositionStrategy() is invoked.
1026TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001027 mOutput->editState().isEnabled = true;
1028 mOutput->editState().usesClientComposition = false;
1029 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001030
1031 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1032
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001033 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001034
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001035 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1036 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001037}
1038
Lloyd Pique56eba802019-08-28 15:45:25 -07001039/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001040 * Output::prepare()
1041 */
1042
1043struct OutputPrepareTest : public testing::Test {
1044 struct OutputPartialMock : public OutputPartialMockBase {
1045 // Sets up the helper functions called by the function under test to use
1046 // mock implementations.
1047 MOCK_METHOD2(rebuildLayerStacks,
1048 void(const compositionengine::CompositionRefreshArgs&,
1049 compositionengine::LayerFESet&));
1050 };
1051
1052 StrictMock<OutputPartialMock> mOutput;
1053 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001054 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001055};
1056
1057TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1058 InSequence seq;
1059 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1060
1061 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1062}
1063
1064/*
1065 * Output::rebuildLayerStacks()
1066 */
1067
1068struct OutputRebuildLayerStacksTest : public testing::Test {
1069 struct OutputPartialMock : public OutputPartialMockBase {
1070 // Sets up the helper functions called by the function under test to use
1071 // mock implementations.
1072 MOCK_METHOD2(collectVisibleLayers,
1073 void(const compositionengine::CompositionRefreshArgs&,
1074 compositionengine::Output::CoverageState&));
1075 };
1076
1077 OutputRebuildLayerStacksTest() {
1078 mOutput.mState.isEnabled = true;
1079 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001080 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001081
1082 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1083
1084 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1085
1086 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1087 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1088 }
1089
1090 void setTestCoverageValues(const CompositionRefreshArgs&,
1091 compositionengine::Output::CoverageState& state) {
1092 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1093 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1094 state.dirtyRegion = mCoverageDirtyRegionToSet;
1095 }
1096
1097 static const ui::Transform kIdentityTransform;
1098 static const ui::Transform kRotate90Transform;
1099 static const Rect kOutputBounds;
1100
1101 StrictMock<OutputPartialMock> mOutput;
1102 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001103 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001104 Region mCoverageAboveCoveredLayersToSet;
1105 Region mCoverageAboveOpaqueLayersToSet;
1106 Region mCoverageDirtyRegionToSet;
1107};
1108
1109const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1110const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1111const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1112
1113TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1114 mOutput.mState.isEnabled = false;
1115
1116 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1117}
1118
1119TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1120 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1121
1122 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1123}
1124
1125TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1126 mOutput.mState.transform = kIdentityTransform;
1127
1128 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1129
1130 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1131
1132 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1133}
1134
1135TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1136 mOutput.mState.transform = kIdentityTransform;
1137
1138 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1139
1140 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1141
1142 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1143}
1144
1145TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1146 mOutput.mState.transform = kRotate90Transform;
1147
1148 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1149
1150 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1151
1152 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1153}
1154
1155TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1156 mOutput.mState.transform = kRotate90Transform;
1157
1158 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1159
1160 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1161
1162 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1163}
1164
1165TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1166 mOutput.mState.transform = kIdentityTransform;
1167 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1168
1169 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1170
1171 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1172
1173 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1174}
1175
1176TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1177 mOutput.mState.transform = kRotate90Transform;
1178 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1179
1180 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1181
1182 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1183
1184 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1185}
1186
1187/*
1188 * Output::collectVisibleLayers()
1189 */
1190
Lloyd Pique1ef93222019-11-21 16:41:53 -08001191struct OutputCollectVisibleLayersTest : public testing::Test {
1192 struct OutputPartialMock : public OutputPartialMockBase {
1193 // Sets up the helper functions called by the function under test to use
1194 // mock implementations.
1195 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001196 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001197 compositionengine::Output::CoverageState&));
1198 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1199 MOCK_METHOD0(finalizePendingOutputLayers, void());
1200 };
1201
1202 struct Layer {
1203 Layer() {
1204 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1205 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1206 }
1207
1208 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001209 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001210 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001211 };
1212
1213 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001214 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001215 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1216 .WillRepeatedly(Return(&mLayer1.outputLayer));
1217 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1218 .WillRepeatedly(Return(&mLayer2.outputLayer));
1219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1220 .WillRepeatedly(Return(&mLayer3.outputLayer));
1221
Lloyd Piquede196652020-01-22 17:29:58 -08001222 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1223 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1224 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001225 }
1226
1227 StrictMock<OutputPartialMock> mOutput;
1228 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229 LayerFESet mGeomSnapshots;
1230 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001231 Layer mLayer1;
1232 Layer mLayer2;
1233 Layer mLayer3;
1234};
1235
1236TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1237 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001238 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001239
1240 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1241 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1242
1243 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1244}
1245
1246TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1247 // Enforce a call order sequence for this test.
1248 InSequence seq;
1249
1250 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001251 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1252 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1253 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001254
1255 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1256 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1257
1258 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001259}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001260
1261/*
1262 * Output::ensureOutputLayerIfVisible()
1263 */
1264
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1266 struct OutputPartialMock : public OutputPartialMockBase {
1267 // Sets up the helper functions called by the function under test to use
1268 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001269 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001271 MOCK_METHOD2(ensureOutputLayer,
1272 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 };
1274
1275 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001276 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1277 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001278 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001279 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001280 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001282 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1283 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1285
Lloyd Piquede196652020-01-22 17:29:58 -08001286 mLayer.layerFEState.isVisible = true;
1287 mLayer.layerFEState.isOpaque = true;
1288 mLayer.layerFEState.contentDirty = true;
1289 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1290 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1291 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1294 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001295
Lloyd Piquede196652020-01-22 17:29:58 -08001296 mGeomSnapshots.insert(mLayer.layerFE);
1297 }
1298
1299 void ensureOutputLayerIfVisible() {
1300 sp<LayerFE> layerFE(mLayer.layerFE);
1301 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001302 }
1303
1304 static const Region kEmptyRegion;
1305 static const Region kFullBoundsNoRotation;
1306 static const Region kRightHalfBoundsNoRotation;
1307 static const Region kLowerHalfBoundsNoRotation;
1308 static const Region kFullBounds90Rotation;
1309
1310 StrictMock<OutputPartialMock> mOutput;
1311 LayerFESet mGeomSnapshots;
1312 Output::CoverageState mCoverageState{mGeomSnapshots};
1313
Lloyd Piquede196652020-01-22 17:29:58 -08001314 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315};
1316
1317const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1318const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1319 Region(Rect(0, 0, 100, 200));
1320const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1321 Region(Rect(0, 100, 100, 200));
1322const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1323 Region(Rect(50, 0, 100, 200));
1324const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1325 Region(Rect(0, 0, 200, 100));
1326
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001328 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1329 EXPECT_CALL(*mLayer.layerFE,
1330 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331
1332 mGeomSnapshots.clear();
1333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335}
1336
1337TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1338 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001339 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340
Lloyd Piquede196652020-01-22 17:29:58 -08001341 ensureOutputLayerIfVisible();
1342}
1343
1344TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1345 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1346
1347 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001351 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354}
1355
1356TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001357 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360}
1361
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001362TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001363 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366}
1367
1368TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1369 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001370 mLayer.layerFEState.isOpaque = true;
1371 mLayer.layerFEState.contentDirty = true;
1372 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
1374 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001375 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1376 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1383
Lloyd Piquede196652020-01-22 17:29:58 -08001384 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1386 RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1388 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389}
1390
1391TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1392 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001393 mLayer.layerFEState.isOpaque = true;
1394 mLayer.layerFEState.contentDirty = true;
1395 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001396
Lloyd Piquede196652020-01-22 17:29:58 -08001397 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1398 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001399
Lloyd Piquede196652020-01-22 17:29:58 -08001400 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
1402 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1403 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1404 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1405
Lloyd Piquede196652020-01-22 17:29:58 -08001406 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1407 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1408 RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1410 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001411}
1412
1413TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1414 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001415 mLayer.layerFEState.isOpaque = false;
1416 mLayer.layerFEState.contentDirty = true;
1417 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418
1419 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001420 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1421 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
1425 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1426 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1428
Lloyd Piquede196652020-01-22 17:29:58 -08001429 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1433 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434}
1435
1436TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1437 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001438 mLayer.layerFEState.isOpaque = false;
1439 mLayer.layerFEState.contentDirty = true;
1440 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1443 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
1447 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1448 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1449 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1452 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001454 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1455 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001456}
1457
1458TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1459 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001460 mLayer.layerFEState.isOpaque = true;
1461 mLayer.layerFEState.contentDirty = false;
1462 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001463
1464 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1466 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1471 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1476 RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1478 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479}
1480
1481TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1482 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = false;
1485 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1488 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
1492 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1493 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1494 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1497 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1498 RegionEq(kFullBoundsNoRotation));
1499 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1500 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501}
1502
1503TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1504 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001505 mLayer.layerFEState.isOpaque = true;
1506 mLayer.layerFEState.contentDirty = true;
1507 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1508 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1509 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1510 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
1512 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001513 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1514 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
1518 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1519 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1520 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1524 RegionEq(kFullBoundsNoRotation));
1525 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1526 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527}
1528
1529TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1530 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001531 mLayer.layerFEState.isOpaque = true;
1532 mLayer.layerFEState.contentDirty = true;
1533 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1534 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1535 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1536 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537
Lloyd Piquede196652020-01-22 17:29:58 -08001538 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1539 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542
1543 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1545 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1549 RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1551 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552}
1553
1554TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1555 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001556 mLayer.layerFEState.isOpaque = true;
1557 mLayer.layerFEState.contentDirty = true;
1558 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001560 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1562
1563 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001564 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1565 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
1569 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1571 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1572
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1575 RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1577 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578}
1579
1580TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1581 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001582 mLayer.layerFEState.isOpaque = true;
1583 mLayer.layerFEState.contentDirty = true;
1584 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001586 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1590 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
1594 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1596 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1599 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1600 RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1602 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603}
1604
1605TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1606 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1607 ui::Transform arbitraryTransform;
1608 arbitraryTransform.set(1, 1, -1, 1);
1609 arbitraryTransform.set(0, 100);
1610
Lloyd Piquede196652020-01-22 17:29:58 -08001611 mLayer.layerFEState.isOpaque = true;
1612 mLayer.layerFEState.contentDirty = true;
1613 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1614 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615
1616 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001617 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1618 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001619
Lloyd Piquede196652020-01-22 17:29:58 -08001620 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621
1622 const Region kRegion = Region(Rect(0, 0, 300, 300));
1623 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1624
1625 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1626 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1627 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1630 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1631 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633}
1634
1635TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001636 mLayer.layerFEState.isOpaque = false;
1637 mLayer.layerFEState.contentDirty = true;
1638 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639
1640 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1641 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1642 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1643
Lloyd Piquede196652020-01-22 17:29:58 -08001644 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1645 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
1649 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1650 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1651 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1652 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1653 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1654 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1655
1656 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1657 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1658 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1659
Lloyd Piquede196652020-01-22 17:29:58 -08001660 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1661 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001662 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001663 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1664 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1665 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001666}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001667
Vishnu Naira483b4a2019-12-12 15:07:52 -08001668TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1669 ui::Transform translate;
1670 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001671 mLayer.layerFEState.geomLayerTransform = translate;
1672 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001673
1674 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1675 // half of the layer including the casting shadow is covered and opaque
1676 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1677 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1680 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001681
Lloyd Piquede196652020-01-22 17:29:58 -08001682 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001683
1684 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1685 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1686 // add starting opaque region to the opaque half of the casting layer bounds
1687 const Region kExpectedAboveOpaqueRegion =
1688 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1689 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1690 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1691 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1692 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1693 const Region kExpectedLayerShadowRegion =
1694 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1695
1696 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1697 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1698 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1701 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001702 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001703 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1704 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001705 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001707 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1708}
1709
1710TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1711 ui::Transform translate;
1712 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001713 mLayer.layerFEState.geomLayerTransform = translate;
1714 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001715
1716 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1717 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1718 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1719 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1720
Lloyd Piquede196652020-01-22 17:29:58 -08001721 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1722 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001725
1726 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1727 const Region kExpectedLayerShadowRegion =
1728 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1731 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001732 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1733}
1734
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001735TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001736 ui::Transform translate;
1737 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001738 mLayer.layerFEState.geomLayerTransform = translate;
1739 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001740
1741 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1742 // Casting layer and its shadows are covered by an opaque region
1743 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1744 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1745
Lloyd Piquede196652020-01-22 17:29:58 -08001746 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001747}
1748
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001749/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001750 * Output::present()
1751 */
1752
1753struct OutputPresentTest : public testing::Test {
1754 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001755 // Sets up the helper functions called by the function under test to use
1756 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001757 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001758 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001759 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001760 MOCK_METHOD0(planComposition, void());
1761 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001762 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1763 MOCK_METHOD0(beginFrame, void());
1764 MOCK_METHOD0(prepareFrame, void());
1765 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1766 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1767 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001768 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001769 };
1770
1771 StrictMock<OutputPartialMock> mOutput;
1772};
1773
1774TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1775 CompositionRefreshArgs args;
1776
1777 InSequence seq;
1778 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001779 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1780 EXPECT_CALL(mOutput, planComposition());
1781 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001782 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1783 EXPECT_CALL(mOutput, beginFrame());
1784 EXPECT_CALL(mOutput, prepareFrame());
1785 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1786 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1787 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001788 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001789
1790 mOutput.present(args);
1791}
1792
1793/*
1794 * Output::updateColorProfile()
1795 */
1796
Lloyd Pique17ca7422019-11-14 14:24:10 -08001797struct OutputUpdateColorProfileTest : public testing::Test {
1798 using TestType = OutputUpdateColorProfileTest;
1799
1800 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001801 // Sets up the helper functions called by the function under test to use
1802 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001803 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1804 };
1805
1806 struct Layer {
1807 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001808 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1809 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001810 }
1811
1812 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001813 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001814 LayerFECompositionState mLayerFEState;
1815 };
1816
1817 OutputUpdateColorProfileTest() {
1818 mOutput.setDisplayColorProfileForTest(
1819 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1820 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1821
1822 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1823 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1824 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1825 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1826 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1827 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1828 }
1829
1830 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1831 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1832 };
1833
1834 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1835 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1836 StrictMock<OutputPartialMock> mOutput;
1837
1838 Layer mLayer1;
1839 Layer mLayer2;
1840 Layer mLayer3;
1841
1842 CompositionRefreshArgs mRefreshArgs;
1843};
1844
1845// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1846// to make it easier to write unit tests.
1847
1848TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1849 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1850 // a simple default color profile without looking at anything else.
1851
Lloyd Pique0a456232020-01-16 17:51:13 -08001852 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001853 EXPECT_CALL(mOutput,
1854 setColorProfile(ColorProfileEq(
1855 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1856 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1857
1858 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1859 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1860
1861 mOutput.updateColorProfile(mRefreshArgs);
1862}
1863
1864struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1865 : public OutputUpdateColorProfileTest {
1866 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001867 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001868 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1869 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1870 }
1871
1872 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1873 : public CallOrderStateMachineHelper<
1874 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1875 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1876 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1877 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1878 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1879 _))
1880 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1881 SetArgPointee<4>(renderIntent)));
1882 EXPECT_CALL(getInstance()->mOutput,
1883 setColorProfile(
1884 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1885 ui::Dataspace::UNKNOWN})));
1886 return nextState<ExecuteState>();
1887 }
1888 };
1889
1890 // Call this member function to start using the mini-DSL defined above.
1891 [[nodiscard]] auto verify() {
1892 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1893 }
1894};
1895
1896TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1897 Native_Unknown_Colorimetric_Set) {
1898 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1899 ui::Dataspace::UNKNOWN,
1900 ui::RenderIntent::COLORIMETRIC)
1901 .execute();
1902}
1903
1904TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1905 DisplayP3_DisplayP3_Enhance_Set) {
1906 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1907 ui::Dataspace::DISPLAY_P3,
1908 ui::RenderIntent::ENHANCE)
1909 .execute();
1910}
1911
1912struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1913 : public OutputUpdateColorProfileTest {
1914 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001915 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001916 EXPECT_CALL(*mDisplayColorProfile,
1917 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1918 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1919 SetArgPointee<3>(ui::ColorMode::NATIVE),
1920 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1921 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1922 }
1923
1924 struct IfColorSpaceAgnosticDataspaceSetToState
1925 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1926 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1927 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1928 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1929 }
1930 };
1931
1932 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1933 : public CallOrderStateMachineHelper<
1934 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1935 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1936 ui::Dataspace dataspace) {
1937 EXPECT_CALL(getInstance()->mOutput,
1938 setColorProfile(ColorProfileEq(
1939 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1940 ui::RenderIntent::COLORIMETRIC, dataspace})));
1941 return nextState<ExecuteState>();
1942 }
1943 };
1944
1945 // Call this member function to start using the mini-DSL defined above.
1946 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1947};
1948
1949TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1950 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1951 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1952 .execute();
1953}
1954
1955TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1956 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1957 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1958 .execute();
1959}
1960
1961struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1962 : public OutputUpdateColorProfileTest {
1963 // Internally the implementation looks through the dataspaces of all the
1964 // visible layers. The topmost one that also has an actual dataspace
1965 // preference set is used to drive subsequent choices.
1966
1967 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1968 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1969 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1970
Lloyd Pique0a456232020-01-16 17:51:13 -08001971 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001972 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1973 }
1974
1975 struct IfTopLayerDataspaceState
1976 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1977 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1978 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1979 return nextState<AndIfMiddleLayerDataspaceState>();
1980 }
1981 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1982 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1983 }
1984 };
1985
1986 struct AndIfMiddleLayerDataspaceState
1987 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1988 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1989 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1990 return nextState<AndIfBottomLayerDataspaceState>();
1991 }
1992 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1993 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1994 }
1995 };
1996
1997 struct AndIfBottomLayerDataspaceState
1998 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1999 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2000 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2001 return nextState<ThenExpectBestColorModeCallUsesState>();
2002 }
2003 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2004 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2005 }
2006 };
2007
2008 struct ThenExpectBestColorModeCallUsesState
2009 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2010 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2011 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2012 getBestColorMode(dataspace, _, _, _, _));
2013 return nextState<ExecuteState>();
2014 }
2015 };
2016
2017 // Call this member function to start using the mini-DSL defined above.
2018 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2019};
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 noStrongLayerPrefenceUses_V0_SRGB) {
2023 // If none of the layers indicate a preference, then V0_SRGB is the
2024 // preferred choice (subject to additional checks).
2025 verify().ifTopLayerHasNoPreference()
2026 .andIfMiddleLayerHasNoPreference()
2027 .andIfBottomLayerHasNoPreference()
2028 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2029 .execute();
2030}
2031
2032TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2033 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2034 // If only the topmost layer has a preference, then that is what is chosen.
2035 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2036 .andIfMiddleLayerHasNoPreference()
2037 .andIfBottomLayerHasNoPreference()
2038 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2039 .execute();
2040}
2041
2042TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2043 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2044 // If only the middle layer has a preference, that that is what is chosen.
2045 verify().ifTopLayerHasNoPreference()
2046 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2047 .andIfBottomLayerHasNoPreference()
2048 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2049 .execute();
2050}
2051
2052TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2053 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2054 // If only the middle layer has a preference, that that is what is chosen.
2055 verify().ifTopLayerHasNoPreference()
2056 .andIfMiddleLayerHasNoPreference()
2057 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2058 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2059 .execute();
2060}
2061
2062TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2063 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2064 // If multiple layers have a preference, the topmost value is what is used.
2065 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2066 .andIfMiddleLayerHasNoPreference()
2067 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2068 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2069 .execute();
2070}
2071
2072TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2073 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2074 // If multiple layers have a preference, the topmost value is what is used.
2075 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2076 .andIfMiddleLayerHasNoPreference()
2077 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2078 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2079 .execute();
2080}
2081
2082struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2083 : public OutputUpdateColorProfileTest {
2084 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2085 // values, it overrides the layer dataspace choice.
2086
2087 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2088 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2089 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2090
2091 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2092
Lloyd Pique0a456232020-01-16 17:51:13 -08002093 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002094 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2095 }
2096
2097 struct IfForceOutputColorModeState
2098 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2099 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2100 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2101 return nextState<ThenExpectBestColorModeCallUsesState>();
2102 }
2103 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2104 };
2105
2106 struct ThenExpectBestColorModeCallUsesState
2107 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2108 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2109 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2110 getBestColorMode(dataspace, _, _, _, _));
2111 return nextState<ExecuteState>();
2112 }
2113 };
2114
2115 // Call this member function to start using the mini-DSL defined above.
2116 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2117};
2118
2119TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2120 // By default the layer state is used to set the preferred dataspace
2121 verify().ifNoOverride()
2122 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2127 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2128 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2129 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2130 .execute();
2131}
2132
2133TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2134 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2135 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2136 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2137 .execute();
2138}
2139
2140// HDR output requires all layers to be compatible with the chosen HDR
2141// dataspace, along with there being proper support.
2142struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2143 OutputUpdateColorProfileTest_Hdr() {
2144 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2145 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002146 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002147 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2148 }
2149
2150 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2151 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2152 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2153 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2154
2155 struct IfTopLayerDataspaceState
2156 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2157 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2158 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2159 return nextState<AndTopLayerCompositionTypeState>();
2160 }
2161 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2162 };
2163
2164 struct AndTopLayerCompositionTypeState
2165 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2166 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2167 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2168 return nextState<AndIfBottomLayerDataspaceState>();
2169 }
2170 };
2171
2172 struct AndIfBottomLayerDataspaceState
2173 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2174 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2175 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2176 return nextState<AndBottomLayerCompositionTypeState>();
2177 }
2178 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2179 return andIfBottomLayerIs(kNonHdrDataspace);
2180 }
2181 };
2182
2183 struct AndBottomLayerCompositionTypeState
2184 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2185 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2186 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2187 return nextState<AndIfHasLegacySupportState>();
2188 }
2189 };
2190
2191 struct AndIfHasLegacySupportState
2192 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2193 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2194 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2195 .WillOnce(Return(legacySupport));
2196 return nextState<ThenExpectBestColorModeCallUsesState>();
2197 }
2198 };
2199
2200 struct ThenExpectBestColorModeCallUsesState
2201 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2202 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2203 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2204 getBestColorMode(dataspace, _, _, _, _));
2205 return nextState<ExecuteState>();
2206 }
2207 };
2208
2209 // Call this member function to start using the mini-DSL defined above.
2210 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2211};
2212
2213TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2214 // If all layers use BT2020_PQ, and there are no other special conditions,
2215 // BT2020_PQ is used.
2216 verify().ifTopLayerIs(BT2020_PQ)
2217 .andTopLayerIsREComposed(false)
2218 .andIfBottomLayerIs(BT2020_PQ)
2219 .andBottomLayerIsREComposed(false)
2220 .andIfLegacySupportFor(BT2020_PQ, false)
2221 .thenExpectBestColorModeCallUses(BT2020_PQ)
2222 .execute();
2223}
2224
2225TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2226 // BT2020_PQ is not used if there is only legacy support for it.
2227 verify().ifTopLayerIs(BT2020_PQ)
2228 .andTopLayerIsREComposed(false)
2229 .andIfBottomLayerIs(BT2020_PQ)
2230 .andBottomLayerIsREComposed(false)
2231 .andIfLegacySupportFor(BT2020_PQ, true)
2232 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2233 .execute();
2234}
2235
2236TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2237 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2238 verify().ifTopLayerIs(BT2020_PQ)
2239 .andTopLayerIsREComposed(false)
2240 .andIfBottomLayerIs(BT2020_PQ)
2241 .andBottomLayerIsREComposed(true)
2242 .andIfLegacySupportFor(BT2020_PQ, false)
2243 .thenExpectBestColorModeCallUses(BT2020_PQ)
2244 .execute();
2245}
2246
2247TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2248 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2249 verify().ifTopLayerIs(BT2020_PQ)
2250 .andTopLayerIsREComposed(true)
2251 .andIfBottomLayerIs(BT2020_PQ)
2252 .andBottomLayerIsREComposed(false)
2253 .andIfLegacySupportFor(BT2020_PQ, false)
2254 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2255 .execute();
2256}
2257
2258TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2259 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2260 // are no other special conditions.
2261 verify().ifTopLayerIs(BT2020_PQ)
2262 .andTopLayerIsREComposed(false)
2263 .andIfBottomLayerIs(BT2020_HLG)
2264 .andBottomLayerIsREComposed(false)
2265 .andIfLegacySupportFor(BT2020_PQ, false)
2266 .thenExpectBestColorModeCallUses(BT2020_PQ)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2271 // BT2020_PQ is not used if there is only legacy support for it.
2272 verify().ifTopLayerIs(BT2020_PQ)
2273 .andTopLayerIsREComposed(false)
2274 .andIfBottomLayerIs(BT2020_HLG)
2275 .andBottomLayerIsREComposed(false)
2276 .andIfLegacySupportFor(BT2020_PQ, true)
2277 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2278 .execute();
2279}
2280
2281TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2282 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2283 verify().ifTopLayerIs(BT2020_PQ)
2284 .andTopLayerIsREComposed(false)
2285 .andIfBottomLayerIs(BT2020_HLG)
2286 .andBottomLayerIsREComposed(true)
2287 .andIfLegacySupportFor(BT2020_PQ, false)
2288 .thenExpectBestColorModeCallUses(BT2020_PQ)
2289 .execute();
2290}
2291
2292TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2293 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2294 verify().ifTopLayerIs(BT2020_PQ)
2295 .andTopLayerIsREComposed(true)
2296 .andIfBottomLayerIs(BT2020_HLG)
2297 .andBottomLayerIsREComposed(false)
2298 .andIfLegacySupportFor(BT2020_PQ, false)
2299 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2300 .execute();
2301}
2302
2303TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2304 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2305 // used if there are no other special conditions.
2306 verify().ifTopLayerIs(BT2020_HLG)
2307 .andTopLayerIsREComposed(false)
2308 .andIfBottomLayerIs(BT2020_PQ)
2309 .andBottomLayerIsREComposed(false)
2310 .andIfLegacySupportFor(BT2020_PQ, false)
2311 .thenExpectBestColorModeCallUses(BT2020_PQ)
2312 .execute();
2313}
2314
2315TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2316 // BT2020_PQ is not used if there is only legacy support for it.
2317 verify().ifTopLayerIs(BT2020_HLG)
2318 .andTopLayerIsREComposed(false)
2319 .andIfBottomLayerIs(BT2020_PQ)
2320 .andBottomLayerIsREComposed(false)
2321 .andIfLegacySupportFor(BT2020_PQ, true)
2322 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2323 .execute();
2324}
2325
2326TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2327 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2328 verify().ifTopLayerIs(BT2020_HLG)
2329 .andTopLayerIsREComposed(false)
2330 .andIfBottomLayerIs(BT2020_PQ)
2331 .andBottomLayerIsREComposed(true)
2332 .andIfLegacySupportFor(BT2020_PQ, false)
2333 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2334 .execute();
2335}
2336
2337TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2338 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2339 verify().ifTopLayerIs(BT2020_HLG)
2340 .andTopLayerIsREComposed(true)
2341 .andIfBottomLayerIs(BT2020_PQ)
2342 .andBottomLayerIsREComposed(false)
2343 .andIfLegacySupportFor(BT2020_PQ, false)
2344 .thenExpectBestColorModeCallUses(BT2020_PQ)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2349 // If all layers use HLG then HLG is used if there are no other special
2350 // conditions.
2351 verify().ifTopLayerIs(BT2020_HLG)
2352 .andTopLayerIsREComposed(false)
2353 .andIfBottomLayerIs(BT2020_HLG)
2354 .andBottomLayerIsREComposed(false)
2355 .andIfLegacySupportFor(BT2020_HLG, false)
2356 .thenExpectBestColorModeCallUses(BT2020_HLG)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2361 // BT2020_HLG is not used if there is legacy support for it.
2362 verify().ifTopLayerIs(BT2020_HLG)
2363 .andTopLayerIsREComposed(false)
2364 .andIfBottomLayerIs(BT2020_HLG)
2365 .andBottomLayerIsREComposed(false)
2366 .andIfLegacySupportFor(BT2020_HLG, true)
2367 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2372 // BT2020_HLG is used even if the bottom layer is client composed.
2373 verify().ifTopLayerIs(BT2020_HLG)
2374 .andTopLayerIsREComposed(false)
2375 .andIfBottomLayerIs(BT2020_HLG)
2376 .andBottomLayerIsREComposed(true)
2377 .andIfLegacySupportFor(BT2020_HLG, false)
2378 .thenExpectBestColorModeCallUses(BT2020_HLG)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2383 // BT2020_HLG is used even if the top layer is client composed.
2384 verify().ifTopLayerIs(BT2020_HLG)
2385 .andTopLayerIsREComposed(true)
2386 .andIfBottomLayerIs(BT2020_HLG)
2387 .andBottomLayerIsREComposed(false)
2388 .andIfLegacySupportFor(BT2020_HLG, false)
2389 .thenExpectBestColorModeCallUses(BT2020_HLG)
2390 .execute();
2391}
2392
2393TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2394 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2395 verify().ifTopLayerIs(BT2020_PQ)
2396 .andTopLayerIsREComposed(false)
2397 .andIfBottomLayerIsNotHdr()
2398 .andBottomLayerIsREComposed(false)
2399 .andIfLegacySupportFor(BT2020_PQ, false)
2400 .thenExpectBestColorModeCallUses(BT2020_PQ)
2401 .execute();
2402}
2403
2404TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2405 // If all layers use HLG then HLG is used if there are no other special
2406 // conditions.
2407 verify().ifTopLayerIs(BT2020_HLG)
2408 .andTopLayerIsREComposed(false)
2409 .andIfBottomLayerIsNotHdr()
2410 .andBottomLayerIsREComposed(true)
2411 .andIfLegacySupportFor(BT2020_HLG, false)
2412 .thenExpectBestColorModeCallUses(BT2020_HLG)
2413 .execute();
2414}
2415
2416struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2417 : public OutputUpdateColorProfileTest {
2418 // The various values for CompositionRefreshArgs::outputColorSetting affect
2419 // the chosen renderIntent, along with whether the preferred dataspace is an
2420 // HDR dataspace or not.
2421
2422 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2423 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2424 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2425 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002426 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002427 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2428 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2429 .WillRepeatedly(Return(false));
2430 }
2431
2432 // The tests here involve enough state and GMock setup that using a mini-DSL
2433 // makes the tests much more readable, and allows the test to focus more on
2434 // the intent than on some of the details.
2435
2436 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2437 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2438
2439 struct IfDataspaceChosenState
2440 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2441 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2442 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2443 return nextState<AndOutputColorSettingState>();
2444 }
2445 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2446 return ifDataspaceChosenIs(kNonHdrDataspace);
2447 }
2448 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2449 };
2450
2451 struct AndOutputColorSettingState
2452 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2453 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2454 getInstance()->mRefreshArgs.outputColorSetting = setting;
2455 return nextState<ThenExpectBestColorModeCallUsesState>();
2456 }
2457 };
2458
2459 struct ThenExpectBestColorModeCallUsesState
2460 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2461 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2462 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2463 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2464 _, _));
2465 return nextState<ExecuteState>();
2466 }
2467 };
2468
2469 // Tests call one of these two helper member functions to start using the
2470 // mini-DSL defined above.
2471 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2472};
2473
2474TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2475 Managed_NonHdr_Prefers_Colorimetric) {
2476 verify().ifDataspaceChosenIsNonHdr()
2477 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2478 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2479 .execute();
2480}
2481
2482TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2483 Managed_Hdr_Prefers_ToneMapColorimetric) {
2484 verify().ifDataspaceChosenIsHdr()
2485 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2486 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2487 .execute();
2488}
2489
2490TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2491 verify().ifDataspaceChosenIsNonHdr()
2492 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2493 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2494 .execute();
2495}
2496
2497TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2498 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2499 verify().ifDataspaceChosenIsHdr()
2500 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2501 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2506 verify().ifDataspaceChosenIsNonHdr()
2507 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2508 .thenExpectBestColorModeCallUses(
2509 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2510 .execute();
2511}
2512
2513TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2514 verify().ifDataspaceChosenIsHdr()
2515 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2516 .thenExpectBestColorModeCallUses(
2517 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2518 .execute();
2519}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002520
2521/*
2522 * Output::beginFrame()
2523 */
2524
Lloyd Piquee5965952019-11-18 16:16:32 -08002525struct OutputBeginFrameTest : public ::testing::Test {
2526 using TestType = OutputBeginFrameTest;
2527
2528 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002529 // Sets up the helper functions called by the function under test to use
2530 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002531 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2532 };
2533
2534 OutputBeginFrameTest() {
2535 mOutput.setDisplayColorProfileForTest(
2536 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2537 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2538 }
2539
2540 struct IfGetDirtyRegionExpectationState
2541 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2542 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2543 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2544 .WillOnce(Return(dirtyRegion));
2545 return nextState<AndIfGetOutputLayerCountExpectationState>();
2546 }
2547 };
2548
2549 struct AndIfGetOutputLayerCountExpectationState
2550 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2551 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2552 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2553 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2554 }
2555 };
2556
2557 struct AndIfLastCompositionHadVisibleLayersState
2558 : public CallOrderStateMachineHelper<TestType,
2559 AndIfLastCompositionHadVisibleLayersState> {
2560 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2561 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2562 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2563 }
2564 };
2565
2566 struct ThenExpectRenderSurfaceBeginFrameCallState
2567 : public CallOrderStateMachineHelper<TestType,
2568 ThenExpectRenderSurfaceBeginFrameCallState> {
2569 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2570 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2571 return nextState<ExecuteState>();
2572 }
2573 };
2574
2575 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2576 [[nodiscard]] auto execute() {
2577 getInstance()->mOutput.beginFrame();
2578 return nextState<CheckPostconditionHadVisibleLayersState>();
2579 }
2580 };
2581
2582 struct CheckPostconditionHadVisibleLayersState
2583 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2584 void checkPostconditionHadVisibleLayers(bool expected) {
2585 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2586 }
2587 };
2588
2589 // Tests call one of these two helper member functions to start using the
2590 // mini-DSL defined above.
2591 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2592
2593 static const Region kEmptyRegion;
2594 static const Region kNotEmptyRegion;
2595
2596 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2597 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2598 StrictMock<OutputPartialMock> mOutput;
2599};
2600
2601const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2602const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2603
2604TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2605 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2606 .andIfGetOutputLayerCountReturns(1u)
2607 .andIfLastCompositionHadVisibleLayersIs(true)
2608 .thenExpectRenderSurfaceBeginFrameCall(true)
2609 .execute()
2610 .checkPostconditionHadVisibleLayers(true);
2611}
2612
2613TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2614 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2615 .andIfGetOutputLayerCountReturns(0u)
2616 .andIfLastCompositionHadVisibleLayersIs(true)
2617 .thenExpectRenderSurfaceBeginFrameCall(true)
2618 .execute()
2619 .checkPostconditionHadVisibleLayers(false);
2620}
2621
2622TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2623 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2624 .andIfGetOutputLayerCountReturns(1u)
2625 .andIfLastCompositionHadVisibleLayersIs(false)
2626 .thenExpectRenderSurfaceBeginFrameCall(true)
2627 .execute()
2628 .checkPostconditionHadVisibleLayers(true);
2629}
2630
2631TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2632 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2633 .andIfGetOutputLayerCountReturns(0u)
2634 .andIfLastCompositionHadVisibleLayersIs(false)
2635 .thenExpectRenderSurfaceBeginFrameCall(false)
2636 .execute()
2637 .checkPostconditionHadVisibleLayers(false);
2638}
2639
2640TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2641 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2642 .andIfGetOutputLayerCountReturns(1u)
2643 .andIfLastCompositionHadVisibleLayersIs(true)
2644 .thenExpectRenderSurfaceBeginFrameCall(false)
2645 .execute()
2646 .checkPostconditionHadVisibleLayers(true);
2647}
2648
2649TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2650 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2651 .andIfGetOutputLayerCountReturns(0u)
2652 .andIfLastCompositionHadVisibleLayersIs(true)
2653 .thenExpectRenderSurfaceBeginFrameCall(false)
2654 .execute()
2655 .checkPostconditionHadVisibleLayers(true);
2656}
2657
2658TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2659 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2660 .andIfGetOutputLayerCountReturns(1u)
2661 .andIfLastCompositionHadVisibleLayersIs(false)
2662 .thenExpectRenderSurfaceBeginFrameCall(false)
2663 .execute()
2664 .checkPostconditionHadVisibleLayers(false);
2665}
2666
2667TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2668 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2669 .andIfGetOutputLayerCountReturns(0u)
2670 .andIfLastCompositionHadVisibleLayersIs(false)
2671 .thenExpectRenderSurfaceBeginFrameCall(false)
2672 .execute()
2673 .checkPostconditionHadVisibleLayers(false);
2674}
2675
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002676/*
2677 * Output::devOptRepaintFlash()
2678 */
2679
Lloyd Piquedb462d82019-11-19 17:58:46 -08002680struct OutputDevOptRepaintFlashTest : public testing::Test {
2681 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002682 // Sets up the helper functions called by the function under test to use
2683 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002684 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002685 MOCK_METHOD2(composeSurfaces,
2686 std::optional<base::unique_fd>(
2687 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002688 MOCK_METHOD0(postFramebuffer, void());
2689 MOCK_METHOD0(prepareFrame, void());
2690 };
2691
2692 OutputDevOptRepaintFlashTest() {
2693 mOutput.setDisplayColorProfileForTest(
2694 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2695 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2696 }
2697
2698 static const Region kEmptyRegion;
2699 static const Region kNotEmptyRegion;
2700
2701 StrictMock<OutputPartialMock> mOutput;
2702 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2703 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2704 CompositionRefreshArgs mRefreshArgs;
2705};
2706
2707const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2708const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2709
2710TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2711 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2712 mRefreshArgs.repaintEverything = true;
2713 mOutput.mState.isEnabled = true;
2714
2715 mOutput.devOptRepaintFlash(mRefreshArgs);
2716}
2717
2718TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2719 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2720 mRefreshArgs.repaintEverything = true;
2721 mOutput.mState.isEnabled = false;
2722
2723 InSequence seq;
2724 EXPECT_CALL(mOutput, postFramebuffer());
2725 EXPECT_CALL(mOutput, prepareFrame());
2726
2727 mOutput.devOptRepaintFlash(mRefreshArgs);
2728}
2729
2730TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2731 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2732 mRefreshArgs.repaintEverything = true;
2733 mOutput.mState.isEnabled = true;
2734
2735 InSequence seq;
2736 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2737 EXPECT_CALL(mOutput, postFramebuffer());
2738 EXPECT_CALL(mOutput, prepareFrame());
2739
2740 mOutput.devOptRepaintFlash(mRefreshArgs);
2741}
2742
2743TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2744 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2745 mRefreshArgs.repaintEverything = false;
2746 mOutput.mState.isEnabled = true;
2747
2748 InSequence seq;
2749 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002750 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002751 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2752 EXPECT_CALL(mOutput, postFramebuffer());
2753 EXPECT_CALL(mOutput, prepareFrame());
2754
2755 mOutput.devOptRepaintFlash(mRefreshArgs);
2756}
2757
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002758/*
2759 * Output::finishFrame()
2760 */
2761
Lloyd Pique03561a62019-11-19 18:34:52 -08002762struct OutputFinishFrameTest : public testing::Test {
2763 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002764 // Sets up the helper functions called by the function under test to use
2765 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002766 MOCK_METHOD2(composeSurfaces,
2767 std::optional<base::unique_fd>(
2768 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002769 MOCK_METHOD0(postFramebuffer, void());
2770 };
2771
2772 OutputFinishFrameTest() {
2773 mOutput.setDisplayColorProfileForTest(
2774 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2775 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2776 }
2777
2778 StrictMock<OutputPartialMock> mOutput;
2779 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2780 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2781 CompositionRefreshArgs mRefreshArgs;
2782};
2783
2784TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2785 mOutput.mState.isEnabled = false;
2786
2787 mOutput.finishFrame(mRefreshArgs);
2788}
2789
2790TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2791 mOutput.mState.isEnabled = true;
2792
2793 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002794 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002795
2796 mOutput.finishFrame(mRefreshArgs);
2797}
2798
2799TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2800 mOutput.mState.isEnabled = true;
2801
2802 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002803 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002804 .WillOnce(Return(ByMove(base::unique_fd())));
2805 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2806
2807 mOutput.finishFrame(mRefreshArgs);
2808}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002809
2810/*
2811 * Output::postFramebuffer()
2812 */
2813
Lloyd Pique07178e32019-11-19 19:15:26 -08002814struct OutputPostFramebufferTest : public testing::Test {
2815 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002816 // Sets up the helper functions called by the function under test to use
2817 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002818 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2819 };
2820
2821 struct Layer {
2822 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002823 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002824 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2825 }
2826
2827 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002828 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002829 StrictMock<HWC2::mock::Layer> hwc2Layer;
2830 };
2831
2832 OutputPostFramebufferTest() {
2833 mOutput.setDisplayColorProfileForTest(
2834 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2835 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2836
2837 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2838 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2839 .WillRepeatedly(Return(&mLayer1.outputLayer));
2840 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2841 .WillRepeatedly(Return(&mLayer2.outputLayer));
2842 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2843 .WillRepeatedly(Return(&mLayer3.outputLayer));
2844 }
2845
2846 StrictMock<OutputPartialMock> mOutput;
2847 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2848 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2849
2850 Layer mLayer1;
2851 Layer mLayer2;
2852 Layer mLayer3;
2853};
2854
2855TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2856 mOutput.mState.isEnabled = false;
2857
2858 mOutput.postFramebuffer();
2859}
2860
2861TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2862 mOutput.mState.isEnabled = true;
2863
2864 compositionengine::Output::FrameFences frameFences;
2865
2866 // This should happen even if there are no output layers.
2867 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2868
2869 // For this test in particular we want to make sure the call expectations
2870 // setup below are satisfied in the specific order.
2871 InSequence seq;
2872
2873 EXPECT_CALL(*mRenderSurface, flip());
2874 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2875 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2876
2877 mOutput.postFramebuffer();
2878}
2879
2880TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2881 // Simulate getting release fences from each layer, and ensure they are passed to the
2882 // front-end layer interface for each layer correctly.
2883
2884 mOutput.mState.isEnabled = true;
2885
2886 // Create three unique fence instances
2887 sp<Fence> layer1Fence = new Fence();
2888 sp<Fence> layer2Fence = new Fence();
2889 sp<Fence> layer3Fence = new Fence();
2890
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002891 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002892 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2893 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2894 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2895
2896 EXPECT_CALL(*mRenderSurface, flip());
2897 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2898 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2899
2900 // Compare the pointers values of each fence to make sure the correct ones
2901 // are passed. This happens to work with the current implementation, but
2902 // would not survive certain calls like Fence::merge() which would return a
2903 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002904 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002905 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002906 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002907 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002908 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002909 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2910
2911 mOutput.postFramebuffer();
2912}
2913
2914TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2915 mOutput.mState.isEnabled = true;
2916 mOutput.mState.usesClientComposition = true;
2917
2918 sp<Fence> clientTargetAcquireFence = new Fence();
2919 sp<Fence> layer1Fence = new Fence();
2920 sp<Fence> layer2Fence = new Fence();
2921 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002922 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002923 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2924 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2925 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2926 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2927
2928 EXPECT_CALL(*mRenderSurface, flip());
2929 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2930 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2931
2932 // Fence::merge is called, and since none of the fences are actually valid,
2933 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2934 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002935 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2936 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2937 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002938
2939 mOutput.postFramebuffer();
2940}
2941
2942TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2943 mOutput.mState.isEnabled = true;
2944 mOutput.mState.usesClientComposition = true;
2945
2946 // This should happen even if there are no (current) output layers.
2947 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2948
2949 // Load up the released layers with some mock instances
2950 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2951 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2952 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2953 Output::ReleasedLayers layers;
2954 layers.push_back(releasedLayer1);
2955 layers.push_back(releasedLayer2);
2956 layers.push_back(releasedLayer3);
2957 mOutput.setReleasedLayers(std::move(layers));
2958
2959 // Set up a fake present fence
2960 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002961 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002962 frameFences.presentFence = presentFence;
2963
2964 EXPECT_CALL(*mRenderSurface, flip());
2965 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2966 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2967
2968 // Each released layer should be given the presentFence.
2969 EXPECT_CALL(*releasedLayer1,
2970 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2971 EXPECT_CALL(*releasedLayer2,
2972 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2973 EXPECT_CALL(*releasedLayer3,
2974 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2975
2976 mOutput.postFramebuffer();
2977
2978 // After the call the list of released layers should have been cleared.
2979 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2980}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002981
2982/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002983 * Output::composeSurfaces()
2984 */
2985
2986struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002987 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002988
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002989 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002990 // Sets up the helper functions called by the function under test to use
2991 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002992 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002993 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002994 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002995 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002996 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002997 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2998 };
2999
3000 OutputComposeSurfacesTest() {
3001 mOutput.setDisplayColorProfileForTest(
3002 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3003 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003004 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003005
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003006 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
3007 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003008 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003009 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003010 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003011 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003012 mOutput.mState.dataspace = kDefaultOutputDataspace;
3013 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3014 mOutput.mState.isSecure = false;
3015 mOutput.mState.needsFiltering = false;
3016 mOutput.mState.usesClientComposition = true;
3017 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003018 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003019 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003020
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003021 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003022 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003023 EXPECT_CALL(mCompositionEngine, getTimeStats())
3024 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003025 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3026 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003027 }
3028
Lloyd Pique6818fa52019-12-03 12:32:13 -08003029 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3030 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003031 getInstance()->mReadyFence =
3032 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003033 return nextState<FenceCheckState>();
3034 }
3035 };
3036
3037 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3038 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3039
3040 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3041 };
3042
3043 // Call this member function to start using the mini-DSL defined above.
3044 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3045
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003046 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3047 static constexpr uint32_t kDefaultOutputOrientationFlags =
3048 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003049 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3050 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3051 static constexpr float kDefaultMaxLuminance = 0.9f;
3052 static constexpr float kDefaultAvgLuminance = 0.7f;
3053 static constexpr float kDefaultMinLuminance = 0.1f;
3054
3055 static const Rect kDefaultOutputFrame;
3056 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003057 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058 static const mat4 kDefaultColorTransformMat;
3059
3060 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003061 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003062 static const HdrCapabilities kHdrCapabilities;
3063
Lloyd Pique56eba802019-08-28 15:45:25 -07003064 StrictMock<mock::CompositionEngine> mCompositionEngine;
3065 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003066 // TODO: make this is a proper mock.
3067 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003068 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3069 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003070 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003071 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3072 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3073 renderengine::ExternalTexture::Usage::READABLE |
3074 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003075
3076 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003077};
3078
3079const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3080const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003081const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003082const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003083const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003084const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3085const HdrCapabilities OutputComposeSurfacesTest::
3086 kHdrCapabilities{{},
3087 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3088 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3089 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003090
Lloyd Piquea76ce462020-01-14 13:06:37 -08003091TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003092 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003093
Lloyd Piquee9eff972020-05-05 12:36:44 -07003094 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003095 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003096
Lloyd Piquea76ce462020-01-14 13:06:37 -08003097 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3098
Lloyd Pique6818fa52019-12-03 12:32:13 -08003099 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003100}
3101
Lloyd Piquee9eff972020-05-05 12:36:44 -07003102TEST_F(OutputComposeSurfacesTest,
3103 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3104 mOutput.mState.usesClientComposition = false;
3105 mOutput.mState.flipClientTarget = true;
3106
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003108 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003109
3110 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3111 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3112
3113 verify().execute().expectAFenceWasReturned();
3114}
3115
3116TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3117 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003118 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003119
3120 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3121
3122 verify().execute().expectNoFenceWasReturned();
3123}
3124
3125TEST_F(OutputComposeSurfacesTest,
3126 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3127 mOutput.mState.usesClientComposition = false;
3128 mOutput.mState.flipClientTarget = true;
3129
3130 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003131 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003132
Lloyd Pique6818fa52019-12-03 12:32:13 -08003133 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003134
Lloyd Pique6818fa52019-12-03 12:32:13 -08003135 verify().execute().expectNoFenceWasReturned();
3136}
Lloyd Pique56eba802019-08-28 15:45:25 -07003137
Lloyd Pique6818fa52019-12-03 12:32:13 -08003138TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3139 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3140 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3141 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003142 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003143 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003144 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3146 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003147
Lloyd Pique6818fa52019-12-03 12:32:13 -08003148 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003149 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003150 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003151
Lloyd Pique6818fa52019-12-03 12:32:13 -08003152 verify().execute().expectAFenceWasReturned();
3153}
Lloyd Pique56eba802019-08-28 15:45:25 -07003154
Lloyd Pique6818fa52019-12-03 12:32:13 -08003155TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003156 LayerFE::LayerSettings r1;
3157 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003158
3159 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3160 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3161
3162 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3163 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3164 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003165 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003166 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003167 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003168 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3169 .WillRepeatedly(
3170 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003171 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003172 clientCompositionLayers.emplace_back(r2);
3173 }));
3174
3175 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003176 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3177 .WillRepeatedly(Return(NO_ERROR));
3178
3179 verify().execute().expectAFenceWasReturned();
3180}
3181
3182TEST_F(OutputComposeSurfacesTest,
3183 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3184 LayerFE::LayerSettings r1;
3185 LayerFE::LayerSettings r2;
3186
3187 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3188 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3189 const constexpr uint32_t kInternalLayerStack = 1234;
3190 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3191
3192 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3193 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3194 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3195 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3196 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3197 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3198 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3199 .WillRepeatedly(
3200 Invoke([&](const Region&,
3201 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3202 clientCompositionLayers.emplace_back(r2);
3203 }));
3204
3205 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003206 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003207 .WillRepeatedly(Return(NO_ERROR));
3208
3209 verify().execute().expectAFenceWasReturned();
3210}
3211
Vishnu Nair9b079a22020-01-21 14:36:08 -08003212TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3213 mOutput.cacheClientCompositionRequests(0);
3214 LayerFE::LayerSettings r1;
3215 LayerFE::LayerSettings r2;
3216
3217 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3218 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3219
3220 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3221 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3222 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003223 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003224 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3225 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3226 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3227 .WillRepeatedly(Return());
3228
3229 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003230 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003231 .Times(2)
3232 .WillOnce(Return(NO_ERROR));
3233
3234 verify().execute().expectAFenceWasReturned();
3235 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3236
3237 verify().execute().expectAFenceWasReturned();
3238 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3239}
3240
3241TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3242 mOutput.cacheClientCompositionRequests(3);
3243 LayerFE::LayerSettings r1;
3244 LayerFE::LayerSettings r2;
3245
3246 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3247 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3248
3249 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3250 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3251 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003252 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003253 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3254 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3255 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3256 .WillRepeatedly(Return());
3257
3258 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003259 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003260 .WillOnce(Return(NO_ERROR));
3261 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3262
3263 verify().execute().expectAFenceWasReturned();
3264 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3265
3266 // We do not expect another call to draw layers.
3267 verify().execute().expectAFenceWasReturned();
3268 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3269}
3270
3271TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3272 LayerFE::LayerSettings r1;
3273 LayerFE::LayerSettings r2;
3274
3275 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3276 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3277
3278 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3279 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3280 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003281 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003282 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3283 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3284 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3285 .WillRepeatedly(Return());
3286
Alec Mouria90a5702021-04-16 16:36:21 +00003287 const auto otherOutputBuffer = std::make_shared<
3288 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3289 renderengine::ExternalTexture::Usage::READABLE |
3290 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003291 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3292 .WillOnce(Return(mOutputBuffer))
3293 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003294 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003295 .WillRepeatedly(Return(NO_ERROR));
3296
3297 verify().execute().expectAFenceWasReturned();
3298 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3299
3300 verify().execute().expectAFenceWasReturned();
3301 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3302}
3303
3304TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3305 LayerFE::LayerSettings r1;
3306 LayerFE::LayerSettings r2;
3307 LayerFE::LayerSettings r3;
3308
3309 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3310 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3311 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3312
3313 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3314 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3315 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003316 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003317 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3318 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3319 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3320 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3321 .WillRepeatedly(Return());
3322
3323 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003324 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003325 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003326 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003327 .WillOnce(Return(NO_ERROR));
3328
3329 verify().execute().expectAFenceWasReturned();
3330 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3331
3332 verify().execute().expectAFenceWasReturned();
3333 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3334}
3335
Lloyd Pique6818fa52019-12-03 12:32:13 -08003336struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3337 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3338 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003339 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003340 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003341 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003342 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3343 .WillRepeatedly(Return());
3344 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3345 }
3346
3347 struct MixedCompositionState
3348 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3349 auto ifMixedCompositionIs(bool used) {
3350 getInstance()->mOutput.mState.usesDeviceComposition = used;
3351 return nextState<OutputUsesHdrState>();
3352 }
3353 };
3354
3355 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3356 auto andIfUsesHdr(bool used) {
3357 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3358 .WillOnce(Return(used));
3359 return nextState<SkipColorTransformState>();
3360 }
3361 };
3362
3363 struct SkipColorTransformState
3364 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3365 auto andIfSkipColorTransform(bool skip) {
3366 // May be called zero or one times.
3367 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3368 .WillRepeatedly(Return(skip));
3369 return nextState<ExpectDisplaySettingsState>();
3370 }
3371 };
3372
3373 struct ExpectDisplaySettingsState
3374 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3375 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003376 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003377 .WillOnce(Return(NO_ERROR));
3378 return nextState<ExecuteState>();
3379 }
3380 };
3381
3382 // Call this member function to start using the mini-DSL defined above.
3383 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3384};
3385
3386TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3387 verify().ifMixedCompositionIs(true)
3388 .andIfUsesHdr(true)
3389 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003390 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003391 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003392 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003393 .execute()
3394 .expectAFenceWasReturned();
3395}
3396
3397TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3398 verify().ifMixedCompositionIs(true)
3399 .andIfUsesHdr(false)
3400 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003401 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003402 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003403 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404 .execute()
3405 .expectAFenceWasReturned();
3406}
3407
3408TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3409 verify().ifMixedCompositionIs(false)
3410 .andIfUsesHdr(true)
3411 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003412 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003413 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003414 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003415 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003416 .execute()
3417 .expectAFenceWasReturned();
3418}
3419
3420TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3421 verify().ifMixedCompositionIs(false)
3422 .andIfUsesHdr(false)
3423 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003424 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003425 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003426 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003427 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428 .execute()
3429 .expectAFenceWasReturned();
3430}
3431
3432TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3433 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3434 verify().ifMixedCompositionIs(false)
3435 .andIfUsesHdr(true)
3436 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003437 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003438 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003439 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 .execute()
3441 .expectAFenceWasReturned();
3442}
3443
3444struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3445 struct Layer {
3446 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003447 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3448 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003449 }
3450
3451 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003452 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453 LayerFECompositionState mLayerFEState;
3454 };
3455
3456 OutputComposeSurfacesTest_HandlesProtectedContent() {
3457 mLayer1.mLayerFEState.hasProtectedContent = false;
3458 mLayer2.mLayerFEState.hasProtectedContent = false;
3459
3460 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3461 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3462 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3463 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3464 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3465
3466 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3467
3468 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3469
3470 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003471 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003472 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3473 .WillRepeatedly(Return());
3474 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003475 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003476 .WillRepeatedly(Return(NO_ERROR));
3477 }
3478
3479 Layer mLayer1;
3480 Layer mLayer2;
3481};
3482
3483TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3484 mOutput.mState.isSecure = false;
3485 mLayer2.mLayerFEState.hasProtectedContent = true;
3486 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003487 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3488 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003489
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003490 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003491}
3492
3493TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3494 mOutput.mState.isSecure = true;
3495 mLayer2.mLayerFEState.hasProtectedContent = true;
3496 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3497
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003498 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003499}
3500
3501TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3502 mOutput.mState.isSecure = true;
3503 mLayer2.mLayerFEState.hasProtectedContent = false;
3504 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3505 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3506 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3507 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3508 EXPECT_CALL(*mRenderSurface, setProtected(false));
3509
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003510 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003511}
3512
3513TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3514 mOutput.mState.isSecure = true;
3515 mLayer2.mLayerFEState.hasProtectedContent = true;
3516 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3517
3518 // For this test, we also check the call order of key functions.
3519 InSequence seq;
3520
3521 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3522 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3523 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3524 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3525 EXPECT_CALL(*mRenderSurface, setProtected(true));
3526 // Must happen after setting the protected content state.
3527 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003528 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003529
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003530 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003531}
3532
3533TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3534 mOutput.mState.isSecure = true;
3535 mLayer2.mLayerFEState.hasProtectedContent = true;
3536 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3537 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3538 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3539
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003540 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003541}
3542
3543TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3544 mOutput.mState.isSecure = true;
3545 mLayer2.mLayerFEState.hasProtectedContent = true;
3546 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3547 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3548 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3549 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3550
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003551 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552}
3553
3554TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3555 mOutput.mState.isSecure = true;
3556 mLayer2.mLayerFEState.hasProtectedContent = true;
3557 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3558 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3559 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3560 EXPECT_CALL(*mRenderSurface, setProtected(true));
3561
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003562 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003563}
3564
3565TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3566 mOutput.mState.isSecure = true;
3567 mLayer2.mLayerFEState.hasProtectedContent = true;
3568 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3569 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3570 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3571 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3572
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003573 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003574}
3575
3576struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3577 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3578 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3579 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3580 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003581 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003582 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3583 .WillRepeatedly(Return());
3584 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3585 }
3586};
3587
3588TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3589 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3590
3591 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003592 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003593
3594 // For this test, we also check the call order of key functions.
3595 InSequence seq;
3596
3597 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003598 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003599
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003600 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3601}
3602
3603struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3604 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3605 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3606 mLayer.layerFEState.backgroundBlurRadius = 10;
3607 mOutput.editState().isEnabled = true;
3608
Snild Dolkow9e217d62020-04-22 15:53:42 +02003609 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003610 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003611 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3612 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003613 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3614 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003615 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003616 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3617 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3618 .WillRepeatedly(Return(&mLayer.outputLayer));
3619 }
3620
3621 NonInjectedLayer mLayer;
3622 compositionengine::CompositionRefreshArgs mRefreshArgs;
3623};
3624
3625TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3626 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003627 mOutput.updateCompositionState(mRefreshArgs);
3628 mOutput.planComposition();
3629 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003630
3631 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3632 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3633}
3634
3635TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3636 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003637 mOutput.updateCompositionState(mRefreshArgs);
3638 mOutput.planComposition();
3639 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003640
3641 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3642 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003643}
3644
3645/*
3646 * Output::generateClientCompositionRequests()
3647 */
3648
3649struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003650 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003651 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003652 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003653 bool supportsProtectedContent, Region& clearRegion,
3654 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003655 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003656 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003657 }
3658 };
3659
Lloyd Piquea4863342019-12-04 18:45:02 -08003660 struct Layer {
3661 Layer() {
3662 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3663 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003664 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3665 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003666 }
3667
3668 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003669 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003670 LayerFECompositionState mLayerFEState;
3671 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003672 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003673 };
3674
Lloyd Pique56eba802019-08-28 15:45:25 -07003675 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003676 mOutput.mState.needsFiltering = false;
3677
Lloyd Pique56eba802019-08-28 15:45:25 -07003678 mOutput.setDisplayColorProfileForTest(
3679 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3680 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3681 }
3682
Lloyd Pique56eba802019-08-28 15:45:25 -07003683 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3684 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003685 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003686};
3687
Lloyd Piquea4863342019-12-04 18:45:02 -08003688struct GenerateClientCompositionRequestsTest_ThreeLayers
3689 : public GenerateClientCompositionRequestsTest {
3690 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003691 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3692 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3693 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003694 mOutput.mState.transform =
3695 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3696 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003697 mOutput.mState.needsFiltering = false;
3698 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003699
Lloyd Piquea4863342019-12-04 18:45:02 -08003700 for (size_t i = 0; i < mLayers.size(); i++) {
3701 mLayers[i].mOutputLayerState.clearClientTarget = false;
3702 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3703 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003704 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003705 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3707 mLayers[i].mLayerSettings.alpha = 1.0f;
3708 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003709
Lloyd Piquea4863342019-12-04 18:45:02 -08003710 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3711 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3712 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3713 .WillRepeatedly(Return(true));
3714 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3715 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003716
Lloyd Piquea4863342019-12-04 18:45:02 -08003717 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3718 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003719
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003720 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003721 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003722
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 static const Rect kDisplayFrame;
3724 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003725 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003726
Lloyd Piquea4863342019-12-04 18:45:02 -08003727 std::array<Layer, 3> mLayers;
3728};
Lloyd Pique56eba802019-08-28 15:45:25 -07003729
Lloyd Piquea4863342019-12-04 18:45:02 -08003730const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3731const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003732const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3733 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003734
Lloyd Piquea4863342019-12-04 18:45:02 -08003735TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3736 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3737 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3738 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003739
Lloyd Piquea4863342019-12-04 18:45:02 -08003740 Region accumClearRegion(Rect(10, 11, 12, 13));
3741 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3742 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003743 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003744 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003745}
3746
Lloyd Piquea4863342019-12-04 18:45:02 -08003747TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3748 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3749 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3750 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3751
3752 Region accumClearRegion(Rect(10, 11, 12, 13));
3753 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3754 accumClearRegion, kDisplayDataspace);
3755 EXPECT_EQ(0u, requests.size());
3756 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3757}
3758
3759TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003760 LayerFE::LayerSettings mShadowSettings;
3761 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003762
Ady Abrahameca9d752021-03-03 12:20:00 -08003763 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003764 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003765 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003766 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003767 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003768 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3769 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003770
3771 Region accumClearRegion(Rect(10, 11, 12, 13));
3772 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3773 accumClearRegion, kDisplayDataspace);
3774 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003775 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3776 EXPECT_EQ(mShadowSettings, requests[1]);
3777 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003778
3779 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3780
3781 // Check that a timestamp was set for the layers that generated requests
3782 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3783 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3784 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3785}
3786
3787TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3788 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3789 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3790 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3791 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3792
3793 mLayers[0].mOutputLayerState.clearClientTarget = false;
3794 mLayers[1].mOutputLayerState.clearClientTarget = false;
3795 mLayers[2].mOutputLayerState.clearClientTarget = false;
3796
3797 mLayers[0].mLayerFEState.isOpaque = true;
3798 mLayers[1].mLayerFEState.isOpaque = true;
3799 mLayers[2].mLayerFEState.isOpaque = true;
3800
Ady Abrahameca9d752021-03-03 12:20:00 -08003801 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003802 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003803
3804 Region accumClearRegion(Rect(10, 11, 12, 13));
3805 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3806 accumClearRegion, kDisplayDataspace);
3807 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003808 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003809
3810 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3811}
3812
3813TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3814 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3815 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3816 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3817 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3818
3819 mLayers[0].mOutputLayerState.clearClientTarget = true;
3820 mLayers[1].mOutputLayerState.clearClientTarget = true;
3821 mLayers[2].mOutputLayerState.clearClientTarget = true;
3822
3823 mLayers[0].mLayerFEState.isOpaque = false;
3824 mLayers[1].mLayerFEState.isOpaque = false;
3825 mLayers[2].mLayerFEState.isOpaque = false;
3826
Ady Abrahameca9d752021-03-03 12:20:00 -08003827 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003828 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003829
3830 Region accumClearRegion(Rect(10, 11, 12, 13));
3831 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3832 accumClearRegion, kDisplayDataspace);
3833 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003834 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003835
3836 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3837}
3838
3839TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003840 // If client composition is performed with some layers set to use device
3841 // composition, device layers after the first layer (device or client) will
3842 // clear the frame buffer if they are opaque and if that layer has a flag
3843 // set to do so. The first layer is skipped as the frame buffer is already
3844 // expected to be clear.
3845
Lloyd Piquea4863342019-12-04 18:45:02 -08003846 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3847 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3848 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003849
Lloyd Piquea4863342019-12-04 18:45:02 -08003850 mLayers[0].mOutputLayerState.clearClientTarget = true;
3851 mLayers[1].mOutputLayerState.clearClientTarget = true;
3852 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003853
Lloyd Piquea4863342019-12-04 18:45:02 -08003854 mLayers[0].mLayerFEState.isOpaque = true;
3855 mLayers[1].mLayerFEState.isOpaque = true;
3856 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003857 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003858 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003859
3860 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3861 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003862 false, /* needs filtering */
3863 false, /* secure */
3864 false, /* supports protected content */
3865 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003866 kDisplayViewport,
3867 kDisplayDataspace,
3868 false /* realContentIsVisible */,
3869 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003870 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003871 };
3872 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3873 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003874 false, /* needs filtering */
3875 false, /* secure */
3876 false, /* supports protected content */
3877 accumClearRegion,
3878 kDisplayViewport,
3879 kDisplayDataspace,
3880 true /* realContentIsVisible */,
3881 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003882 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003883 };
3884
3885 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3886 mBlackoutSettings.source.buffer.buffer = nullptr;
3887 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3888 mBlackoutSettings.alpha = 0.f;
3889 mBlackoutSettings.disableBlending = true;
3890
Ady Abrahameca9d752021-03-03 12:20:00 -08003891 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003892 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003893 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003894 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3895
Lloyd Piquea4863342019-12-04 18:45:02 -08003896 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3897 accumClearRegion, kDisplayDataspace);
3898 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003899
Lloyd Piquea4863342019-12-04 18:45:02 -08003900 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003901 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003902
Vishnu Nair9b079a22020-01-21 14:36:08 -08003903 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003904
Lloyd Piquea4863342019-12-04 18:45:02 -08003905 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3906}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003907
Lloyd Piquea4863342019-12-04 18:45:02 -08003908TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3909 clippedVisibleRegionUsedToGenerateRequest) {
3910 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3911 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3912 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003913
Lloyd Piquea4863342019-12-04 18:45:02 -08003914 Region accumClearRegion(Rect(10, 11, 12, 13));
3915
3916 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3917 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003918 false, /* needs filtering */
3919 false, /* secure */
3920 false, /* supports protected content */
3921 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003922 kDisplayViewport,
3923 kDisplayDataspace,
3924 true /* realContentIsVisible */,
3925 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003926 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003927 };
3928 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3929 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003930 false, /* needs filtering */
3931 false, /* secure */
3932 false, /* supports protected content */
3933 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003934 kDisplayViewport,
3935 kDisplayDataspace,
3936 true /* realContentIsVisible */,
3937 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003938 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003939 };
3940 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3941 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 false, /* needs filtering */
3943 false, /* secure */
3944 false, /* supports protected content */
3945 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003946 kDisplayViewport,
3947 kDisplayDataspace,
3948 true /* realContentIsVisible */,
3949 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003950 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003951 };
3952
Ady Abrahameca9d752021-03-03 12:20:00 -08003953 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003954 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003955 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003956 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003957 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003958 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003959
3960 static_cast<void>(
3961 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3962 accumClearRegion, kDisplayDataspace));
3963}
3964
3965TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3966 perLayerNeedsFilteringUsedToGenerateRequests) {
3967 mOutput.mState.needsFiltering = false;
3968 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3969
3970 Region accumClearRegion(Rect(10, 11, 12, 13));
3971
3972 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3973 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003974 true, /* needs filtering */
3975 false, /* secure */
3976 false, /* supports protected content */
3977 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003978 kDisplayViewport,
3979 kDisplayDataspace,
3980 true /* realContentIsVisible */,
3981 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003982 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003983 };
3984 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3985 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003986 false, /* needs filtering */
3987 false, /* secure */
3988 false, /* supports protected content */
3989 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003990 kDisplayViewport,
3991 kDisplayDataspace,
3992 true /* realContentIsVisible */,
3993 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003994 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003995 };
3996 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3997 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 false, /* needs filtering */
3999 false, /* secure */
4000 false, /* supports protected content */
4001 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004002 kDisplayViewport,
4003 kDisplayDataspace,
4004 true /* realContentIsVisible */,
4005 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004006 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 };
4008
Ady Abrahameca9d752021-03-03 12:20:00 -08004009 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004010 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004011 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004012 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004013 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004014 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004015
4016 static_cast<void>(
4017 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4018 accumClearRegion, kDisplayDataspace));
4019}
4020
4021TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4022 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4023 mOutput.mState.needsFiltering = true;
4024 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4025
4026 Region accumClearRegion(Rect(10, 11, 12, 13));
4027
4028 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4029 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 true, /* needs filtering */
4031 false, /* secure */
4032 false, /* supports protected content */
4033 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004034 kDisplayViewport,
4035 kDisplayDataspace,
4036 true /* realContentIsVisible */,
4037 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004038 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004039
Lloyd Piquea4863342019-12-04 18:45:02 -08004040 };
4041 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4042 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004043 true, /* needs filtering */
4044 false, /* secure */
4045 false, /* 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 true, /* needs filtering */
4056 false, /* secure */
4057 false, /* 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>(
4074 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4075 accumClearRegion, kDisplayDataspace));
4076}
4077
4078TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4079 wholeOutputSecurityUsedToGenerateRequests) {
4080 mOutput.mState.isSecure = true;
4081
4082 Region accumClearRegion(Rect(10, 11, 12, 13));
4083
4084 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4085 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004086 false, /* needs filtering */
4087 true, /* secure */
4088 false, /* supports protected content */
4089 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004090 kDisplayViewport,
4091 kDisplayDataspace,
4092 true /* realContentIsVisible */,
4093 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004094 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004095 };
4096 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4097 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004098 false, /* needs filtering */
4099 true, /* secure */
4100 false, /* supports protected content */
4101 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004102 kDisplayViewport,
4103 kDisplayDataspace,
4104 true /* realContentIsVisible */,
4105 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004106 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004107 };
4108 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4109 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 false, /* needs filtering */
4111 true, /* secure */
4112 false, /* supports protected content */
4113 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004114 kDisplayViewport,
4115 kDisplayDataspace,
4116 true /* realContentIsVisible */,
4117 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004118 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004119 };
4120
Ady Abrahameca9d752021-03-03 12:20:00 -08004121 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004122 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004123 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004124 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004125 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004126 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004127
4128 static_cast<void>(
4129 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4130 accumClearRegion, kDisplayDataspace));
4131}
4132
4133TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4134 protectedContentSupportUsedToGenerateRequests) {
4135 Region accumClearRegion(Rect(10, 11, 12, 13));
4136
4137 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4138 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 false, /* needs filtering */
4140 false, /* secure */
4141 true, /* supports protected content */
4142 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004143 kDisplayViewport,
4144 kDisplayDataspace,
4145 true /* realContentIsVisible */,
4146 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004147 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004148 };
4149 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4150 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004151 false, /* needs filtering */
4152 false, /* secure */
4153 true, /* supports protected content */
4154 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004155 kDisplayViewport,
4156 kDisplayDataspace,
4157 true /* realContentIsVisible */,
4158 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004159 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004160 };
4161 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4162 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004163 false, /* needs filtering */
4164 false, /* secure */
4165 true, /* supports protected content */
4166 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004167 kDisplayViewport,
4168 kDisplayDataspace,
4169 true /* realContentIsVisible */,
4170 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004171 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004172 };
4173
Ady Abrahameca9d752021-03-03 12:20:00 -08004174 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004175 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004176 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004177 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004178 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004179 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004180
4181 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4182 accumClearRegion,
4183 kDisplayDataspace));
4184}
4185
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004186TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004187 InjectedLayer layer1;
4188 InjectedLayer layer2;
4189 InjectedLayer layer3;
4190
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004191 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004192 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004193 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004194 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004195 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4196 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004197 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004198 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004199 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4200 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004201 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004202 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004203 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4204 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004205
Lloyd Piquede196652020-01-22 17:29:58 -08004206 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004207
Lloyd Piquede196652020-01-22 17:29:58 -08004208 injectOutputLayer(layer1);
4209 injectOutputLayer(layer2);
4210 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004211
4212 mOutput->editState().isEnabled = true;
4213
4214 CompositionRefreshArgs args;
4215 args.updatingGeometryThisFrame = false;
4216 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004217 mOutput->updateCompositionState(args);
4218 mOutput->planComposition();
4219 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004220}
4221
Lucas Dupinc3800b82020-10-02 16:24:48 -07004222TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4223 InjectedLayer layer1;
4224 InjectedLayer layer2;
4225 InjectedLayer layer3;
4226
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004227 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004228 // Layer requesting blur, or below, should request client composition.
4229 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004230 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004231 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4232 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004233 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004234 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004235 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4236 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004237 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004238 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004239 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4240 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004241
4242 BlurRegion region;
4243 layer2.layerFEState.blurRegions.push_back(region);
4244
4245 injectOutputLayer(layer1);
4246 injectOutputLayer(layer2);
4247 injectOutputLayer(layer3);
4248
4249 mOutput->editState().isEnabled = true;
4250
4251 CompositionRefreshArgs args;
4252 args.updatingGeometryThisFrame = false;
4253 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004254 mOutput->updateCompositionState(args);
4255 mOutput->planComposition();
4256 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004257}
4258
Lloyd Piquea4863342019-12-04 18:45:02 -08004259TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4260 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4261 // one layer on the left covering the left side of the output, and one layer
4262 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004263
4264 const Rect kPortraitFrame(0, 0, 1000, 2000);
4265 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004266 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004267 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004268 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004269
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004270 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4271 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4272 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004273 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4274 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004275 mOutput.mState.needsFiltering = false;
4276 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004277
Lloyd Piquea4863342019-12-04 18:45:02 -08004278 Layer leftLayer;
4279 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004280
Lloyd Piquea4863342019-12-04 18:45:02 -08004281 leftLayer.mOutputLayerState.clearClientTarget = false;
4282 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4283 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004284 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286 rightLayer.mOutputLayerState.clearClientTarget = false;
4287 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4288 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004289 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004290
4291 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4292 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4293 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4294 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4295 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4296
4297 Region accumClearRegion(Rect(10, 11, 12, 13));
4298
4299 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4300 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004301 false, /* needs filtering */
4302 true, /* secure */
4303 true, /* supports protected content */
4304 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004305 kPortraitViewport,
4306 kOutputDataspace,
4307 true /* realContentIsVisible */,
4308 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004309 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004310 };
4311
4312 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4313 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004314 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004315 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004316
4317 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4318 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004319 false, /* needs filtering */
4320 true, /* secure */
4321 true, /* supports protected content */
4322 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004323 kPortraitViewport,
4324 kOutputDataspace,
4325 true /* realContentIsVisible */,
4326 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004327 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004328 };
4329
4330 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4331 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004332 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004333 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004334
4335 constexpr bool supportsProtectedContent = true;
4336 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4337 accumClearRegion, kOutputDataspace);
4338 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004339 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4340 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004341}
4342
Vishnu Naira483b4a2019-12-12 15:07:52 -08004343TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4344 shadowRegionOnlyVisibleSkipsContentComposition) {
4345 const Rect kContentWithShadow(40, 40, 70, 90);
4346 const Rect kContent(50, 50, 60, 80);
4347 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4348 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4349
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004350 Region accumClearRegion(Rect(10, 11, 12, 13));
4351 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4352 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004353 false, /* needs filtering */
4354 false, /* secure */
4355 false, /* supports protected content */
4356 accumClearRegion,
4357 kDisplayViewport,
4358 kDisplayDataspace,
4359 false /* realContentIsVisible */,
4360 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004361 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004362 };
4363
Vishnu Nair9b079a22020-01-21 14:36:08 -08004364 LayerFE::LayerSettings mShadowSettings;
4365 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004366
4367 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4368 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4369
4370 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4371 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004372 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004373 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004374
Vishnu Naira483b4a2019-12-12 15:07:52 -08004375 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4376 accumClearRegion, kDisplayDataspace);
4377 ASSERT_EQ(1u, requests.size());
4378
Vishnu Nair9b079a22020-01-21 14:36:08 -08004379 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004380}
4381
4382TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4383 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4384 const Rect kContentWithShadow(40, 40, 70, 90);
4385 const Rect kContent(50, 50, 60, 80);
4386 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4387 const Region kPartialContentWithPartialShadowRegion =
4388 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4389
Vishnu Nair9b079a22020-01-21 14:36:08 -08004390 LayerFE::LayerSettings mShadowSettings;
4391 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004392
4393 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4394 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4395
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004396 Region accumClearRegion(Rect(10, 11, 12, 13));
4397 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4398 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004399 false, /* needs filtering */
4400 false, /* secure */
4401 false, /* supports protected content */
4402 accumClearRegion,
4403 kDisplayViewport,
4404 kDisplayDataspace,
4405 true /* realContentIsVisible */,
4406 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004407 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004408 };
4409
Vishnu Naira483b4a2019-12-12 15:07:52 -08004410 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4411 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004412 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004413 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4414 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004415
Vishnu Naira483b4a2019-12-12 15:07:52 -08004416 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4417 accumClearRegion, kDisplayDataspace);
4418 ASSERT_EQ(2u, requests.size());
4419
Vishnu Nair9b079a22020-01-21 14:36:08 -08004420 EXPECT_EQ(mShadowSettings, requests[0]);
4421 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004422}
4423
Lloyd Pique32cbe282018-10-19 13:09:22 -07004424} // namespace
4425} // namespace android::compositionengine