blob: 11736d1e075b979904f93bca9251af63aa774bb8 [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
262/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700263 * Output::setProjection()
264 */
265
Marin Shalamanov209ae612020-10-01 00:17:39 +0200266TEST_F(OutputTest, setProjectionWorks) {
267 const Rect displayRect{0, 0, 1000, 2000};
268 mOutput->editState().displaySpace.bounds = displayRect;
269 mOutput->editState().framebufferSpace.bounds = displayRect;
270
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200271 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200272 const Rect frame{50, 60, 100, 100};
273 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700274
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200275 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700276
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200277 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200278 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
279 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200280
281 const auto state = mOutput->getState();
282 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
283 EXPECT_EQ(viewport, state.layerStackSpace.content);
284 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
285
286 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
287 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
288 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
289
290 EXPECT_EQ(displayRect, state.displaySpace.bounds);
291 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
292 EXPECT_EQ(orientation, state.displaySpace.orientation);
293
294 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
295 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
296 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
297
298 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700299
300 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200301}
302
303TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
304 const Rect displayRect{0, 0, 1000, 2000};
305 const Rect framebufferRect{0, 0, 500, 1000};
306 mOutput->editState().displaySpace.bounds = displayRect;
307 mOutput->editState().framebufferSpace.bounds = framebufferRect;
308
309 const ui::Rotation orientation = ui::ROTATION_90;
310 const Rect frame{50, 60, 100, 100};
311 const Rect viewport{10, 20, 30, 40};
312
313 mOutput->setProjection(orientation, viewport, frame);
314
315 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
316 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
317 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
318
319 const auto state = mOutput->getState();
320 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
321 EXPECT_EQ(viewport, state.layerStackSpace.content);
322 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
323
324 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
325 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
326 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
327
328 EXPECT_EQ(displayRect, state.displaySpace.bounds);
329 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
330 EXPECT_EQ(orientation, state.displaySpace.orientation);
331
332 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
333 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
334 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
335
336 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700337}
338
Lloyd Pique66d68602019-02-13 14:23:31 -0800339/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200340 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700341 */
342
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200343TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
344 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
345 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
346 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
347 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
348 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
349 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
350 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
351 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
352 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
353 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700354
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200355 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700356
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200357 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700358
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200359 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700360
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200361 const auto state = mOutput->getState();
362
363 const Rect displayRect(newDisplaySize);
364 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
365 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
366 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200367
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200368 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200369 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200370
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200371 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200372 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200373
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200374 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200375 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
376
377 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
378
379 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700380}
381
Lloyd Pique66d68602019-02-13 14:23:31 -0800382/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700383 * Output::setLayerStackFilter()
384 */
385
386TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700387 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700388 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700389
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 EXPECT_TRUE(mOutput->getState().layerStackInternal);
391 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700393 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700394}
395
Lloyd Pique66d68602019-02-13 14:23:31 -0800396/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700397 * Output::setColorTransform
398 */
399
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800400TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700401 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700402
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800403 // If no colorTransformMatrix is set the update should be skipped.
404 CompositionRefreshArgs refreshArgs;
405 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700406
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700407 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800409 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700410 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800411
412 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700413 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800414}
Lloyd Piqueef958122019-02-05 18:00:12 -0800415
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800416TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700417 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700418
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800419 // Attempting to set the same colorTransformMatrix that is already set should
420 // also skip the update.
421 CompositionRefreshArgs refreshArgs;
422 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700423
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700424 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700425
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800426 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700427 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800428
429 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700430 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800431}
432
433TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435
436 // Setting a different colorTransformMatrix should perform the update.
437 CompositionRefreshArgs refreshArgs;
438 refreshArgs.colorTransformMatrix = kIdentity;
439
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800441
442 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800444
445 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700446 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800447}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700448
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700451
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452 // Setting a different colorTransformMatrix should perform the update.
453 CompositionRefreshArgs refreshArgs;
454 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700455
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700456 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800457
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800458 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700459 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800460
461 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700462 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463}
464
465TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467
468 // Setting a different colorTransformMatrix should perform the update.
469 CompositionRefreshArgs refreshArgs;
470 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
471
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700472 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473
474 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700475 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800476
477 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700479}
480
Lloyd Pique66d68602019-02-13 14:23:31 -0800481/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800482 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700483 */
484
Lloyd Pique17ca7422019-11-14 14:24:10 -0800485using OutputSetColorProfileTest = OutputTest;
486
487TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800488 using ColorProfile = Output::ColorProfile;
489
Lloyd Piquef5275482019-01-29 18:42:42 -0800490 EXPECT_CALL(*mDisplayColorProfile,
491 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
492 ui::Dataspace::UNKNOWN))
493 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800494 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
497 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
498 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700499
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
501 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
502 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
503 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800504
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800506}
507
Lloyd Pique17ca7422019-11-14 14:24:10 -0800508TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
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));
515
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
517 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
518 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
519 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800520
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700521 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
522 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
523 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800524
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700526}
527
Lloyd Pique66d68602019-02-13 14:23:31 -0800528/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700529 * Output::setRenderSurface()
530 */
531
532TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
533 const ui::Size newDisplaySize{640, 480};
534
535 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
536 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
537
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700538 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700539
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200540 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700541}
542
Lloyd Pique66d68602019-02-13 14:23:31 -0800543/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000544 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700545 */
546
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000547TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
548 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200549 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700550 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700551
552 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700554
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000555 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700556 }
557}
558
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000559TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
560 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200561 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700563
564 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700565 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700566
567 // The dirtyRegion should be clipped to the display bounds.
568 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
569 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700570}
571
Lloyd Pique66d68602019-02-13 14:23:31 -0800572/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800573 * Output::belongsInOutput()
574 */
575
576TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
577 const uint32_t layerStack1 = 123u;
578 const uint32_t layerStack2 = 456u;
579
580 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700581 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800582
Lloyd Piquec6687342019-03-07 21:34:57 -0800583 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700584 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
585 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800586
Lloyd Piqueef36b002019-01-23 17:52:04 -0800587 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700588 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
589 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
590 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
591 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800592
593 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700594 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800595
596 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700597 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
598 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
599 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
600 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800601}
602
Lloyd Piquede196652020-01-22 17:29:58 -0800603TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
604 NonInjectedLayer layer;
605 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800606
Lloyd Piquede196652020-01-22 17:29:58 -0800607 // If the layer has no composition state, it does not belong to any output.
608 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
609 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
610}
611
612TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
613 NonInjectedLayer layer;
614 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800615
616 const uint32_t layerStack1 = 123u;
617 const uint32_t layerStack2 = 456u;
618
619 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700620 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800621
Lloyd Pique66c20c42019-03-07 21:44:02 -0800622 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800623 layer.layerFEState.layerStackId = std::nullopt;
624 layer.layerFEState.internalOnly = false;
625 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800626
Lloyd Piquede196652020-01-22 17:29:58 -0800627 layer.layerFEState.layerStackId = std::nullopt;
628 layer.layerFEState.internalOnly = true;
629 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800630
631 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800632 layer.layerFEState.layerStackId = layerStack1;
633 layer.layerFEState.internalOnly = false;
634 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Lloyd Piquede196652020-01-22 17:29:58 -0800636 layer.layerFEState.layerStackId = layerStack1;
637 layer.layerFEState.internalOnly = true;
638 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800639
Lloyd Piquede196652020-01-22 17:29:58 -0800640 layer.layerFEState.layerStackId = layerStack2;
641 layer.layerFEState.internalOnly = true;
642 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800643
Lloyd Piquede196652020-01-22 17:29:58 -0800644 layer.layerFEState.layerStackId = layerStack2;
645 layer.layerFEState.internalOnly = false;
646 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
648 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700649 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Lloyd Pique66c20c42019-03-07 21:44:02 -0800651 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800652 layer.layerFEState.layerStackId = layerStack1;
653 layer.layerFEState.internalOnly = false;
654 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Lloyd Piquede196652020-01-22 17:29:58 -0800656 layer.layerFEState.layerStackId = layerStack1;
657 layer.layerFEState.internalOnly = true;
658 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Lloyd Piquede196652020-01-22 17:29:58 -0800660 layer.layerFEState.layerStackId = layerStack2;
661 layer.layerFEState.internalOnly = true;
662 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Lloyd Piquede196652020-01-22 17:29:58 -0800664 layer.layerFEState.layerStackId = layerStack2;
665 layer.layerFEState.internalOnly = false;
666 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667}
668
Lloyd Pique66d68602019-02-13 14:23:31 -0800669/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800670 * Output::getOutputLayerForLayer()
671 */
672
673TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800674 InjectedLayer layer1;
675 InjectedLayer layer2;
676 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800677
Lloyd Piquede196652020-01-22 17:29:58 -0800678 injectOutputLayer(layer1);
679 injectNullOutputLayer();
680 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800681
682 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800683 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
684 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800685
686 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800687 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
688 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
689 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800690
691 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800692 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
693 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
694 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800695}
696
Lloyd Pique66d68602019-02-13 14:23:31 -0800697/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800698 * Output::setReleasedLayers()
699 */
700
701using OutputSetReleasedLayersTest = OutputTest;
702
703TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
704 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
705 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
706 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
707
708 Output::ReleasedLayers layers;
709 layers.push_back(layer1FE);
710 layers.push_back(layer2FE);
711 layers.push_back(layer3FE);
712
713 mOutput->setReleasedLayers(std::move(layers));
714
715 const auto& setLayers = mOutput->getReleasedLayersForTest();
716 ASSERT_EQ(3u, setLayers.size());
717 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
718 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
719 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
720}
721
722/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800723 * Output::updateLayerStateFromFE()
724 */
725
Lloyd Piquede196652020-01-22 17:29:58 -0800726using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800727
728TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
729 CompositionRefreshArgs refreshArgs;
730
731 mOutput->updateLayerStateFromFE(refreshArgs);
732}
733
Lloyd Piquede196652020-01-22 17:29:58 -0800734TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
735 InjectedLayer layer1;
736 InjectedLayer layer2;
737 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800738
Lloyd Piquede196652020-01-22 17:29:58 -0800739 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
740 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
741 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
742
743 injectOutputLayer(layer1);
744 injectOutputLayer(layer2);
745 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800746
747 CompositionRefreshArgs refreshArgs;
748 refreshArgs.updatingGeometryThisFrame = false;
749
750 mOutput->updateLayerStateFromFE(refreshArgs);
751}
752
Lloyd Piquede196652020-01-22 17:29:58 -0800753TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
754 InjectedLayer layer1;
755 InjectedLayer layer2;
756 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800757
Lloyd Piquede196652020-01-22 17:29:58 -0800758 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
759 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
760 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
761
762 injectOutputLayer(layer1);
763 injectOutputLayer(layer2);
764 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800765
766 CompositionRefreshArgs refreshArgs;
767 refreshArgs.updatingGeometryThisFrame = true;
768
769 mOutput->updateLayerStateFromFE(refreshArgs);
770}
771
772/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800773 * Output::updateAndWriteCompositionState()
774 */
775
Lloyd Piquede196652020-01-22 17:29:58 -0800776using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800777
778TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
779 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800780
781 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800782 mOutput->updateCompositionState(args);
783 mOutput->planComposition();
784 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800785}
786
Lloyd Piqueef63b612019-11-14 13:19:56 -0800787TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800788 InjectedLayer layer1;
789 InjectedLayer layer2;
790 InjectedLayer layer3;
791
Lloyd Piqueef63b612019-11-14 13:19:56 -0800792 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800793
Lloyd Piquede196652020-01-22 17:29:58 -0800794 injectOutputLayer(layer1);
795 injectOutputLayer(layer2);
796 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800797
798 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800799 mOutput->updateCompositionState(args);
800 mOutput->planComposition();
801 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800802}
803
804TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800805 InjectedLayer layer1;
806 InjectedLayer layer2;
807 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800808
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400809 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200810 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800811 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400812 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
813 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200814 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800815 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400816 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
817 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200818 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800819 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400820 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
821 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800822
823 injectOutputLayer(layer1);
824 injectOutputLayer(layer2);
825 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800826
827 mOutput->editState().isEnabled = true;
828
829 CompositionRefreshArgs args;
830 args.updatingGeometryThisFrame = false;
831 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200832 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800833 mOutput->updateCompositionState(args);
834 mOutput->planComposition();
835 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836}
837
838TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800839 InjectedLayer layer1;
840 InjectedLayer layer2;
841 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800842
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400843 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200844 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800845 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400846 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
847 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200848 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800849 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400850 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
851 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200852 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800853 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400854 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
855 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800856
857 injectOutputLayer(layer1);
858 injectOutputLayer(layer2);
859 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800860
861 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800862
863 CompositionRefreshArgs args;
864 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800865 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800866 mOutput->updateCompositionState(args);
867 mOutput->planComposition();
868 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800869}
870
871TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800872 InjectedLayer layer1;
873 InjectedLayer layer2;
874 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800875
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400876 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800878 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400879 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200881 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800882 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400883 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
884 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200885 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800886 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400887 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
888 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800889
890 injectOutputLayer(layer1);
891 injectOutputLayer(layer2);
892 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800893
894 mOutput->editState().isEnabled = true;
895
896 CompositionRefreshArgs args;
897 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800898 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800899 mOutput->updateCompositionState(args);
900 mOutput->planComposition();
901 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800902}
903
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400904TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
905 renderengine::mock::RenderEngine renderEngine;
906 InjectedLayer layer0;
907 InjectedLayer layer1;
908 InjectedLayer layer2;
909 InjectedLayer layer3;
910
911 InSequence seq;
912 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
913 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
914 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
915 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
916
917 uint32_t z = 0;
918 EXPECT_CALL(*layer0.outputLayer,
919 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
920 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
921
922 // After calling planComposition (which clears overrideInfo), this test sets
923 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
924 // comes first, setting isPeekingThrough to true and zIsOverridden to true
925 // for it and the following layers.
926 EXPECT_CALL(*layer3.outputLayer,
927 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
928 /*zIsOverridden*/ true, /*isPeekingThrough*/
929 true));
930 EXPECT_CALL(*layer1.outputLayer,
931 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
932 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
933 EXPECT_CALL(*layer2.outputLayer,
934 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
935 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
936
937 injectOutputLayer(layer0);
938 injectOutputLayer(layer1);
939 injectOutputLayer(layer2);
940 injectOutputLayer(layer3);
941
942 mOutput->editState().isEnabled = true;
943
944 CompositionRefreshArgs args;
945 args.updatingGeometryThisFrame = true;
946 args.devOptForceClientComposition = false;
947 mOutput->updateCompositionState(args);
948 mOutput->planComposition();
949
950 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
951 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
952 renderengine::ExternalTexture::Usage::READABLE |
953 renderengine::ExternalTexture::Usage::WRITEABLE);
954 layer1.outputLayerState.overrideInfo.buffer = buffer;
955 layer2.outputLayerState.overrideInfo.buffer = buffer;
956 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
957 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
958
959 mOutput->writeCompositionState(args);
960}
961
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800962/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800963 * Output::prepareFrame()
964 */
965
966struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800967 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800968 // Sets up the helper functions called by the function under test to use
969 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800970 MOCK_METHOD0(chooseCompositionStrategy, void());
971 };
972
973 OutputPrepareFrameTest() {
974 mOutput.setDisplayColorProfileForTest(
975 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
976 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
977 }
978
979 StrictMock<mock::CompositionEngine> mCompositionEngine;
980 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
981 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700982 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800983};
984
985TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
986 mOutput.editState().isEnabled = false;
987
988 mOutput.prepareFrame();
989}
990
991TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
992 mOutput.editState().isEnabled = true;
993 mOutput.editState().usesClientComposition = false;
994 mOutput.editState().usesDeviceComposition = true;
995
996 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800998 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
999
1000 mOutput.prepareFrame();
1001}
1002
1003// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1004// base chooseCompositionStrategy() is invoked.
1005TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001006 mOutput->editState().isEnabled = true;
1007 mOutput->editState().usesClientComposition = false;
1008 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001009
1010 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1011
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001012 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001013
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001014 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1015 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001016}
1017
Lloyd Pique56eba802019-08-28 15:45:25 -07001018/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001019 * Output::prepare()
1020 */
1021
1022struct OutputPrepareTest : public testing::Test {
1023 struct OutputPartialMock : public OutputPartialMockBase {
1024 // Sets up the helper functions called by the function under test to use
1025 // mock implementations.
1026 MOCK_METHOD2(rebuildLayerStacks,
1027 void(const compositionengine::CompositionRefreshArgs&,
1028 compositionengine::LayerFESet&));
1029 };
1030
1031 StrictMock<OutputPartialMock> mOutput;
1032 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001033 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001034};
1035
1036TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1037 InSequence seq;
1038 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1039
1040 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1041}
1042
1043/*
1044 * Output::rebuildLayerStacks()
1045 */
1046
1047struct OutputRebuildLayerStacksTest : public testing::Test {
1048 struct OutputPartialMock : public OutputPartialMockBase {
1049 // Sets up the helper functions called by the function under test to use
1050 // mock implementations.
1051 MOCK_METHOD2(collectVisibleLayers,
1052 void(const compositionengine::CompositionRefreshArgs&,
1053 compositionengine::Output::CoverageState&));
1054 };
1055
1056 OutputRebuildLayerStacksTest() {
1057 mOutput.mState.isEnabled = true;
1058 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001059 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001060
1061 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1062
1063 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1064
1065 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1066 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1067 }
1068
1069 void setTestCoverageValues(const CompositionRefreshArgs&,
1070 compositionengine::Output::CoverageState& state) {
1071 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1072 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1073 state.dirtyRegion = mCoverageDirtyRegionToSet;
1074 }
1075
1076 static const ui::Transform kIdentityTransform;
1077 static const ui::Transform kRotate90Transform;
1078 static const Rect kOutputBounds;
1079
1080 StrictMock<OutputPartialMock> mOutput;
1081 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001082 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001083 Region mCoverageAboveCoveredLayersToSet;
1084 Region mCoverageAboveOpaqueLayersToSet;
1085 Region mCoverageDirtyRegionToSet;
1086};
1087
1088const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1089const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1090const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1091
1092TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1093 mOutput.mState.isEnabled = false;
1094
1095 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1096}
1097
1098TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1099 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1100
1101 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1102}
1103
1104TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1105 mOutput.mState.transform = kIdentityTransform;
1106
1107 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1108
1109 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1110
1111 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1112}
1113
1114TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1115 mOutput.mState.transform = kIdentityTransform;
1116
1117 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1118
1119 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1120
1121 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1122}
1123
1124TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1125 mOutput.mState.transform = kRotate90Transform;
1126
1127 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1128
1129 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1130
1131 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1132}
1133
1134TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1135 mOutput.mState.transform = kRotate90Transform;
1136
1137 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1138
1139 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1140
1141 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1142}
1143
1144TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1145 mOutput.mState.transform = kIdentityTransform;
1146 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1147
1148 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1149
1150 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1151
1152 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1153}
1154
1155TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1156 mOutput.mState.transform = kRotate90Transform;
1157 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1158
1159 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1160
1161 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1162
1163 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1164}
1165
1166/*
1167 * Output::collectVisibleLayers()
1168 */
1169
Lloyd Pique1ef93222019-11-21 16:41:53 -08001170struct OutputCollectVisibleLayersTest : public testing::Test {
1171 struct OutputPartialMock : public OutputPartialMockBase {
1172 // Sets up the helper functions called by the function under test to use
1173 // mock implementations.
1174 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001175 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001176 compositionengine::Output::CoverageState&));
1177 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1178 MOCK_METHOD0(finalizePendingOutputLayers, void());
1179 };
1180
1181 struct Layer {
1182 Layer() {
1183 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1184 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1185 }
1186
1187 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001188 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001189 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001190 };
1191
1192 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001193 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001194 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1195 .WillRepeatedly(Return(&mLayer1.outputLayer));
1196 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1197 .WillRepeatedly(Return(&mLayer2.outputLayer));
1198 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1199 .WillRepeatedly(Return(&mLayer3.outputLayer));
1200
Lloyd Piquede196652020-01-22 17:29:58 -08001201 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1202 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1203 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001204 }
1205
1206 StrictMock<OutputPartialMock> mOutput;
1207 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001208 LayerFESet mGeomSnapshots;
1209 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001210 Layer mLayer1;
1211 Layer mLayer2;
1212 Layer mLayer3;
1213};
1214
1215TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1216 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001217 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001218
1219 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1220 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1221
1222 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1223}
1224
1225TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1226 // Enforce a call order sequence for this test.
1227 InSequence seq;
1228
1229 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001230 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1231 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1232 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001233
1234 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1235 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1236
1237 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001238}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001239
1240/*
1241 * Output::ensureOutputLayerIfVisible()
1242 */
1243
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001244struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1245 struct OutputPartialMock : public OutputPartialMockBase {
1246 // Sets up the helper functions called by the function under test to use
1247 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001248 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001250 MOCK_METHOD2(ensureOutputLayer,
1251 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001252 };
1253
1254 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001255 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1256 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001257 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001259 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001260
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001261 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1262 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001263 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1264
Lloyd Piquede196652020-01-22 17:29:58 -08001265 mLayer.layerFEState.isVisible = true;
1266 mLayer.layerFEState.isOpaque = true;
1267 mLayer.layerFEState.contentDirty = true;
1268 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1269 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1270 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001271
Lloyd Piquede196652020-01-22 17:29:58 -08001272 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1273 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 mGeomSnapshots.insert(mLayer.layerFE);
1276 }
1277
1278 void ensureOutputLayerIfVisible() {
1279 sp<LayerFE> layerFE(mLayer.layerFE);
1280 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281 }
1282
1283 static const Region kEmptyRegion;
1284 static const Region kFullBoundsNoRotation;
1285 static const Region kRightHalfBoundsNoRotation;
1286 static const Region kLowerHalfBoundsNoRotation;
1287 static const Region kFullBounds90Rotation;
1288
1289 StrictMock<OutputPartialMock> mOutput;
1290 LayerFESet mGeomSnapshots;
1291 Output::CoverageState mCoverageState{mGeomSnapshots};
1292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294};
1295
1296const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1297const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1298 Region(Rect(0, 0, 100, 200));
1299const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1300 Region(Rect(0, 100, 100, 200));
1301const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1302 Region(Rect(50, 0, 100, 200));
1303const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1304 Region(Rect(0, 0, 200, 100));
1305
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001306TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001307 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1308 EXPECT_CALL(*mLayer.layerFE,
1309 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310
1311 mGeomSnapshots.clear();
1312
Lloyd Piquede196652020-01-22 17:29:58 -08001313 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314}
1315
1316TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1317 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001318 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319
Lloyd Piquede196652020-01-22 17:29:58 -08001320 ensureOutputLayerIfVisible();
1321}
1322
1323TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1324 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1325
1326 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327}
1328
1329TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001330 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331
Lloyd Piquede196652020-01-22 17:29:58 -08001332 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333}
1334
1335TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001336 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337
Lloyd Piquede196652020-01-22 17:29:58 -08001338 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001339}
1340
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001341TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001342 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343
Lloyd Piquede196652020-01-22 17:29:58 -08001344 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345}
1346
1347TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1348 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001349 mLayer.layerFEState.isOpaque = true;
1350 mLayer.layerFEState.contentDirty = true;
1351 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
1353 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001354 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1355 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
1359 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1361 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1362
Lloyd Piquede196652020-01-22 17:29:58 -08001363 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1365 RegionEq(kFullBoundsNoRotation));
1366 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1367 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368}
1369
1370TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1371 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001372 mLayer.layerFEState.isOpaque = true;
1373 mLayer.layerFEState.contentDirty = true;
1374 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1377 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380
1381 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1384
Lloyd Piquede196652020-01-22 17:29:58 -08001385 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1387 RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1389 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390}
1391
1392TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1393 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001394 mLayer.layerFEState.isOpaque = false;
1395 mLayer.layerFEState.contentDirty = true;
1396 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001397
1398 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001399 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1400 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
Lloyd Piquede196652020-01-22 17:29:58 -08001402 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
1404 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1405 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001411 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1412 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413}
1414
1415TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1416 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mLayer.layerFEState.isOpaque = false;
1418 mLayer.layerFEState.contentDirty = true;
1419 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
Lloyd Piquede196652020-01-22 17:29:58 -08001421 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1422 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423
Lloyd Piquede196652020-01-22 17:29:58 -08001424 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
1426 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1428 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1431 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001433 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1434 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435}
1436
1437TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1438 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001439 mLayer.layerFEState.isOpaque = true;
1440 mLayer.layerFEState.contentDirty = false;
1441 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001442
1443 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001444 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1445 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
1449 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1450 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1452
Lloyd Piquede196652020-01-22 17:29:58 -08001453 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1455 RegionEq(kFullBoundsNoRotation));
1456 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1457 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458}
1459
1460TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1461 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001462 mLayer.layerFEState.isOpaque = true;
1463 mLayer.layerFEState.contentDirty = false;
1464 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1467 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468
Lloyd Piquede196652020-01-22 17:29:58 -08001469 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
1471 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1473 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1476 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1477 RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1479 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480}
1481
1482TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1483 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001484 mLayer.layerFEState.isOpaque = true;
1485 mLayer.layerFEState.contentDirty = true;
1486 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1487 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1488 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1489 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490
1491 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001492 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1493 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
Lloyd Piquede196652020-01-22 17:29:58 -08001495 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496
1497 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1498 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1499 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1500
Lloyd Piquede196652020-01-22 17:29:58 -08001501 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1502 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1503 RegionEq(kFullBoundsNoRotation));
1504 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1505 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506}
1507
1508TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1509 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001510 mLayer.layerFEState.isOpaque = true;
1511 mLayer.layerFEState.contentDirty = true;
1512 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1513 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1514 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1515 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516
Lloyd Piquede196652020-01-22 17:29:58 -08001517 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1518 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
Lloyd Piquede196652020-01-22 17:29:58 -08001520 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
1522 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1524 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1527 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1528 RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531}
1532
1533TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1534 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001535 mLayer.layerFEState.isOpaque = true;
1536 mLayer.layerFEState.contentDirty = true;
1537 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001539 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1541
1542 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001543 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1544 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
1548 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1551
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1554 RegionEq(kFullBoundsNoRotation));
1555 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1556 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557}
1558
1559TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1560 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001561 mLayer.layerFEState.isOpaque = true;
1562 mLayer.layerFEState.contentDirty = true;
1563 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001565 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1569 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570
Lloyd Piquede196652020-01-22 17:29:58 -08001571 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572
1573 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1575 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1576
Lloyd Piquede196652020-01-22 17:29:58 -08001577 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1578 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1579 RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1581 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582}
1583
1584TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1585 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1586 ui::Transform arbitraryTransform;
1587 arbitraryTransform.set(1, 1, -1, 1);
1588 arbitraryTransform.set(0, 100);
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 mLayer.layerFEState.isOpaque = true;
1591 mLayer.layerFEState.contentDirty = true;
1592 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1593 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
1595 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1597 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001600
1601 const Region kRegion = Region(Rect(0, 0, 300, 300));
1602 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1603
1604 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1605 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1606 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1609 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1610 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1611 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612}
1613
1614TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001615 mLayer.layerFEState.isOpaque = false;
1616 mLayer.layerFEState.contentDirty = true;
1617 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618
1619 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1620 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1621 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1624 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
Lloyd Piquede196652020-01-22 17:29:58 -08001626 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
1628 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1629 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1630 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1631 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1632 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1633 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1634
1635 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1636 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1637 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1640 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001641 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001642 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1643 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1644 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001646
Vishnu Naira483b4a2019-12-12 15:07:52 -08001647TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1648 ui::Transform translate;
1649 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001650 mLayer.layerFEState.geomLayerTransform = translate;
1651 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001652
1653 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1654 // half of the layer including the casting shadow is covered and opaque
1655 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1656 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1659 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001660
Lloyd Piquede196652020-01-22 17:29:58 -08001661 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001662
1663 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1664 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1665 // add starting opaque region to the opaque half of the casting layer bounds
1666 const Region kExpectedAboveOpaqueRegion =
1667 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1668 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1669 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1670 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1671 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1672 const Region kExpectedLayerShadowRegion =
1673 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1674
1675 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1676 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1677 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1680 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001681 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001682 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1683 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001684 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001685 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001686 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1687}
1688
1689TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1690 ui::Transform translate;
1691 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001692 mLayer.layerFEState.geomLayerTransform = translate;
1693 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001694
1695 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1696 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1697 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1698 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1701 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001702
Lloyd Piquede196652020-01-22 17:29:58 -08001703 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001704
1705 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1706 const Region kExpectedLayerShadowRegion =
1707 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1710 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001711 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1712}
1713
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001714TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001715 ui::Transform translate;
1716 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001717 mLayer.layerFEState.geomLayerTransform = translate;
1718 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001719
1720 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1721 // Casting layer and its shadows are covered by an opaque region
1722 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1723 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1724
Lloyd Piquede196652020-01-22 17:29:58 -08001725 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001726}
1727
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001728/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001729 * Output::present()
1730 */
1731
1732struct OutputPresentTest : public testing::Test {
1733 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001734 // Sets up the helper functions called by the function under test to use
1735 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001736 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001737 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001738 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001739 MOCK_METHOD0(planComposition, void());
1740 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001741 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1742 MOCK_METHOD0(beginFrame, void());
1743 MOCK_METHOD0(prepareFrame, void());
1744 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1745 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1746 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001747 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001748 };
1749
1750 StrictMock<OutputPartialMock> mOutput;
1751};
1752
1753TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1754 CompositionRefreshArgs args;
1755
1756 InSequence seq;
1757 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001758 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1759 EXPECT_CALL(mOutput, planComposition());
1760 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001761 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1762 EXPECT_CALL(mOutput, beginFrame());
1763 EXPECT_CALL(mOutput, prepareFrame());
1764 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1765 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1766 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001767 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001768
1769 mOutput.present(args);
1770}
1771
1772/*
1773 * Output::updateColorProfile()
1774 */
1775
Lloyd Pique17ca7422019-11-14 14:24:10 -08001776struct OutputUpdateColorProfileTest : public testing::Test {
1777 using TestType = OutputUpdateColorProfileTest;
1778
1779 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001780 // Sets up the helper functions called by the function under test to use
1781 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001782 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1783 };
1784
1785 struct Layer {
1786 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001787 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1788 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001789 }
1790
1791 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001792 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001793 LayerFECompositionState mLayerFEState;
1794 };
1795
1796 OutputUpdateColorProfileTest() {
1797 mOutput.setDisplayColorProfileForTest(
1798 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1799 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1800
1801 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1802 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1803 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1804 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1805 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1806 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1807 }
1808
1809 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1810 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1811 };
1812
1813 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1814 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1815 StrictMock<OutputPartialMock> mOutput;
1816
1817 Layer mLayer1;
1818 Layer mLayer2;
1819 Layer mLayer3;
1820
1821 CompositionRefreshArgs mRefreshArgs;
1822};
1823
1824// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1825// to make it easier to write unit tests.
1826
1827TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1828 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1829 // a simple default color profile without looking at anything else.
1830
Lloyd Pique0a456232020-01-16 17:51:13 -08001831 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001832 EXPECT_CALL(mOutput,
1833 setColorProfile(ColorProfileEq(
1834 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1835 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1836
1837 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1838 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1839
1840 mOutput.updateColorProfile(mRefreshArgs);
1841}
1842
1843struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1844 : public OutputUpdateColorProfileTest {
1845 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001846 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001847 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1848 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1849 }
1850
1851 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1852 : public CallOrderStateMachineHelper<
1853 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1854 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1855 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1856 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1857 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1858 _))
1859 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1860 SetArgPointee<4>(renderIntent)));
1861 EXPECT_CALL(getInstance()->mOutput,
1862 setColorProfile(
1863 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1864 ui::Dataspace::UNKNOWN})));
1865 return nextState<ExecuteState>();
1866 }
1867 };
1868
1869 // Call this member function to start using the mini-DSL defined above.
1870 [[nodiscard]] auto verify() {
1871 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1872 }
1873};
1874
1875TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1876 Native_Unknown_Colorimetric_Set) {
1877 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1878 ui::Dataspace::UNKNOWN,
1879 ui::RenderIntent::COLORIMETRIC)
1880 .execute();
1881}
1882
1883TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1884 DisplayP3_DisplayP3_Enhance_Set) {
1885 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1886 ui::Dataspace::DISPLAY_P3,
1887 ui::RenderIntent::ENHANCE)
1888 .execute();
1889}
1890
1891struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1892 : public OutputUpdateColorProfileTest {
1893 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001894 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001895 EXPECT_CALL(*mDisplayColorProfile,
1896 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1897 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1898 SetArgPointee<3>(ui::ColorMode::NATIVE),
1899 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1900 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1901 }
1902
1903 struct IfColorSpaceAgnosticDataspaceSetToState
1904 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1905 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1906 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1907 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1908 }
1909 };
1910
1911 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1912 : public CallOrderStateMachineHelper<
1913 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1914 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1915 ui::Dataspace dataspace) {
1916 EXPECT_CALL(getInstance()->mOutput,
1917 setColorProfile(ColorProfileEq(
1918 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1919 ui::RenderIntent::COLORIMETRIC, dataspace})));
1920 return nextState<ExecuteState>();
1921 }
1922 };
1923
1924 // Call this member function to start using the mini-DSL defined above.
1925 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1926};
1927
1928TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1929 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1930 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1931 .execute();
1932}
1933
1934TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1935 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1936 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1937 .execute();
1938}
1939
1940struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1941 : public OutputUpdateColorProfileTest {
1942 // Internally the implementation looks through the dataspaces of all the
1943 // visible layers. The topmost one that also has an actual dataspace
1944 // preference set is used to drive subsequent choices.
1945
1946 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1947 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1948 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1949
Lloyd Pique0a456232020-01-16 17:51:13 -08001950 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001951 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1952 }
1953
1954 struct IfTopLayerDataspaceState
1955 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1956 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1957 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1958 return nextState<AndIfMiddleLayerDataspaceState>();
1959 }
1960 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1961 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1962 }
1963 };
1964
1965 struct AndIfMiddleLayerDataspaceState
1966 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1967 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1968 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1969 return nextState<AndIfBottomLayerDataspaceState>();
1970 }
1971 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1972 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1973 }
1974 };
1975
1976 struct AndIfBottomLayerDataspaceState
1977 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1978 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1979 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1980 return nextState<ThenExpectBestColorModeCallUsesState>();
1981 }
1982 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1983 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1984 }
1985 };
1986
1987 struct ThenExpectBestColorModeCallUsesState
1988 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1989 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1990 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1991 getBestColorMode(dataspace, _, _, _, _));
1992 return nextState<ExecuteState>();
1993 }
1994 };
1995
1996 // Call this member function to start using the mini-DSL defined above.
1997 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1998};
1999
2000TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2001 noStrongLayerPrefenceUses_V0_SRGB) {
2002 // If none of the layers indicate a preference, then V0_SRGB is the
2003 // preferred choice (subject to additional checks).
2004 verify().ifTopLayerHasNoPreference()
2005 .andIfMiddleLayerHasNoPreference()
2006 .andIfBottomLayerHasNoPreference()
2007 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2008 .execute();
2009}
2010
2011TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2012 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2013 // If only the topmost layer has a preference, then that is what is chosen.
2014 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2015 .andIfMiddleLayerHasNoPreference()
2016 .andIfBottomLayerHasNoPreference()
2017 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2018 .execute();
2019}
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2023 // If only the middle layer has a preference, that that is what is chosen.
2024 verify().ifTopLayerHasNoPreference()
2025 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2026 .andIfBottomLayerHasNoPreference()
2027 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2028 .execute();
2029}
2030
2031TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2032 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2033 // If only the middle layer has a preference, that that is what is chosen.
2034 verify().ifTopLayerHasNoPreference()
2035 .andIfMiddleLayerHasNoPreference()
2036 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2037 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2038 .execute();
2039}
2040
2041TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2042 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2043 // If multiple layers have a preference, the topmost value is what is used.
2044 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2045 .andIfMiddleLayerHasNoPreference()
2046 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2047 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2048 .execute();
2049}
2050
2051TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2052 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2053 // If multiple layers have a preference, the topmost value is what is used.
2054 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2055 .andIfMiddleLayerHasNoPreference()
2056 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2057 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2058 .execute();
2059}
2060
2061struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2062 : public OutputUpdateColorProfileTest {
2063 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2064 // values, it overrides the layer dataspace choice.
2065
2066 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2067 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2068 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2069
2070 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2071
Lloyd Pique0a456232020-01-16 17:51:13 -08002072 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002073 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2074 }
2075
2076 struct IfForceOutputColorModeState
2077 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2078 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2079 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2080 return nextState<ThenExpectBestColorModeCallUsesState>();
2081 }
2082 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2083 };
2084
2085 struct ThenExpectBestColorModeCallUsesState
2086 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2087 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2088 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2089 getBestColorMode(dataspace, _, _, _, _));
2090 return nextState<ExecuteState>();
2091 }
2092 };
2093
2094 // Call this member function to start using the mini-DSL defined above.
2095 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2096};
2097
2098TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2099 // By default the layer state is used to set the preferred dataspace
2100 verify().ifNoOverride()
2101 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2102 .execute();
2103}
2104
2105TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2106 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2107 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2108 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2109 .execute();
2110}
2111
2112TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2113 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2114 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2115 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2116 .execute();
2117}
2118
2119// HDR output requires all layers to be compatible with the chosen HDR
2120// dataspace, along with there being proper support.
2121struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2122 OutputUpdateColorProfileTest_Hdr() {
2123 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2124 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002125 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002126 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2127 }
2128
2129 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2130 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2131 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2132 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2133
2134 struct IfTopLayerDataspaceState
2135 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2136 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2137 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2138 return nextState<AndTopLayerCompositionTypeState>();
2139 }
2140 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2141 };
2142
2143 struct AndTopLayerCompositionTypeState
2144 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2145 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2146 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2147 return nextState<AndIfBottomLayerDataspaceState>();
2148 }
2149 };
2150
2151 struct AndIfBottomLayerDataspaceState
2152 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2153 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2154 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2155 return nextState<AndBottomLayerCompositionTypeState>();
2156 }
2157 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2158 return andIfBottomLayerIs(kNonHdrDataspace);
2159 }
2160 };
2161
2162 struct AndBottomLayerCompositionTypeState
2163 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2164 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2165 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2166 return nextState<AndIfHasLegacySupportState>();
2167 }
2168 };
2169
2170 struct AndIfHasLegacySupportState
2171 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2172 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2173 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2174 .WillOnce(Return(legacySupport));
2175 return nextState<ThenExpectBestColorModeCallUsesState>();
2176 }
2177 };
2178
2179 struct ThenExpectBestColorModeCallUsesState
2180 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2181 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2182 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2183 getBestColorMode(dataspace, _, _, _, _));
2184 return nextState<ExecuteState>();
2185 }
2186 };
2187
2188 // Call this member function to start using the mini-DSL defined above.
2189 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2190};
2191
2192TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2193 // If all layers use BT2020_PQ, and there are no other special conditions,
2194 // BT2020_PQ is used.
2195 verify().ifTopLayerIs(BT2020_PQ)
2196 .andTopLayerIsREComposed(false)
2197 .andIfBottomLayerIs(BT2020_PQ)
2198 .andBottomLayerIsREComposed(false)
2199 .andIfLegacySupportFor(BT2020_PQ, false)
2200 .thenExpectBestColorModeCallUses(BT2020_PQ)
2201 .execute();
2202}
2203
2204TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2205 // BT2020_PQ is not used if there is only legacy support for it.
2206 verify().ifTopLayerIs(BT2020_PQ)
2207 .andTopLayerIsREComposed(false)
2208 .andIfBottomLayerIs(BT2020_PQ)
2209 .andBottomLayerIsREComposed(false)
2210 .andIfLegacySupportFor(BT2020_PQ, true)
2211 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2212 .execute();
2213}
2214
2215TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2216 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2217 verify().ifTopLayerIs(BT2020_PQ)
2218 .andTopLayerIsREComposed(false)
2219 .andIfBottomLayerIs(BT2020_PQ)
2220 .andBottomLayerIsREComposed(true)
2221 .andIfLegacySupportFor(BT2020_PQ, false)
2222 .thenExpectBestColorModeCallUses(BT2020_PQ)
2223 .execute();
2224}
2225
2226TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2227 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2228 verify().ifTopLayerIs(BT2020_PQ)
2229 .andTopLayerIsREComposed(true)
2230 .andIfBottomLayerIs(BT2020_PQ)
2231 .andBottomLayerIsREComposed(false)
2232 .andIfLegacySupportFor(BT2020_PQ, false)
2233 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2234 .execute();
2235}
2236
2237TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2238 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2239 // are no other special conditions.
2240 verify().ifTopLayerIs(BT2020_PQ)
2241 .andTopLayerIsREComposed(false)
2242 .andIfBottomLayerIs(BT2020_HLG)
2243 .andBottomLayerIsREComposed(false)
2244 .andIfLegacySupportFor(BT2020_PQ, false)
2245 .thenExpectBestColorModeCallUses(BT2020_PQ)
2246 .execute();
2247}
2248
2249TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2250 // BT2020_PQ is not used if there is only legacy support for it.
2251 verify().ifTopLayerIs(BT2020_PQ)
2252 .andTopLayerIsREComposed(false)
2253 .andIfBottomLayerIs(BT2020_HLG)
2254 .andBottomLayerIsREComposed(false)
2255 .andIfLegacySupportFor(BT2020_PQ, true)
2256 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2261 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2262 verify().ifTopLayerIs(BT2020_PQ)
2263 .andTopLayerIsREComposed(false)
2264 .andIfBottomLayerIs(BT2020_HLG)
2265 .andBottomLayerIsREComposed(true)
2266 .andIfLegacySupportFor(BT2020_PQ, false)
2267 .thenExpectBestColorModeCallUses(BT2020_PQ)
2268 .execute();
2269}
2270
2271TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2272 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2273 verify().ifTopLayerIs(BT2020_PQ)
2274 .andTopLayerIsREComposed(true)
2275 .andIfBottomLayerIs(BT2020_HLG)
2276 .andBottomLayerIsREComposed(false)
2277 .andIfLegacySupportFor(BT2020_PQ, false)
2278 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2279 .execute();
2280}
2281
2282TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2283 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2284 // used if there are no other special conditions.
2285 verify().ifTopLayerIs(BT2020_HLG)
2286 .andTopLayerIsREComposed(false)
2287 .andIfBottomLayerIs(BT2020_PQ)
2288 .andBottomLayerIsREComposed(false)
2289 .andIfLegacySupportFor(BT2020_PQ, false)
2290 .thenExpectBestColorModeCallUses(BT2020_PQ)
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2295 // BT2020_PQ is not used if there is only legacy support for it.
2296 verify().ifTopLayerIs(BT2020_HLG)
2297 .andTopLayerIsREComposed(false)
2298 .andIfBottomLayerIs(BT2020_PQ)
2299 .andBottomLayerIsREComposed(false)
2300 .andIfLegacySupportFor(BT2020_PQ, true)
2301 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2306 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2307 verify().ifTopLayerIs(BT2020_HLG)
2308 .andTopLayerIsREComposed(false)
2309 .andIfBottomLayerIs(BT2020_PQ)
2310 .andBottomLayerIsREComposed(true)
2311 .andIfLegacySupportFor(BT2020_PQ, false)
2312 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2313 .execute();
2314}
2315
2316TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2317 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2318 verify().ifTopLayerIs(BT2020_HLG)
2319 .andTopLayerIsREComposed(true)
2320 .andIfBottomLayerIs(BT2020_PQ)
2321 .andBottomLayerIsREComposed(false)
2322 .andIfLegacySupportFor(BT2020_PQ, false)
2323 .thenExpectBestColorModeCallUses(BT2020_PQ)
2324 .execute();
2325}
2326
2327TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2328 // If all layers use HLG then HLG is used if there are no other special
2329 // conditions.
2330 verify().ifTopLayerIs(BT2020_HLG)
2331 .andTopLayerIsREComposed(false)
2332 .andIfBottomLayerIs(BT2020_HLG)
2333 .andBottomLayerIsREComposed(false)
2334 .andIfLegacySupportFor(BT2020_HLG, false)
2335 .thenExpectBestColorModeCallUses(BT2020_HLG)
2336 .execute();
2337}
2338
2339TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2340 // BT2020_HLG is not used if there is legacy support for it.
2341 verify().ifTopLayerIs(BT2020_HLG)
2342 .andTopLayerIsREComposed(false)
2343 .andIfBottomLayerIs(BT2020_HLG)
2344 .andBottomLayerIsREComposed(false)
2345 .andIfLegacySupportFor(BT2020_HLG, true)
2346 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2347 .execute();
2348}
2349
2350TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2351 // BT2020_HLG is used even if the bottom layer is client composed.
2352 verify().ifTopLayerIs(BT2020_HLG)
2353 .andTopLayerIsREComposed(false)
2354 .andIfBottomLayerIs(BT2020_HLG)
2355 .andBottomLayerIsREComposed(true)
2356 .andIfLegacySupportFor(BT2020_HLG, false)
2357 .thenExpectBestColorModeCallUses(BT2020_HLG)
2358 .execute();
2359}
2360
2361TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2362 // BT2020_HLG is used even if the top layer is client composed.
2363 verify().ifTopLayerIs(BT2020_HLG)
2364 .andTopLayerIsREComposed(true)
2365 .andIfBottomLayerIs(BT2020_HLG)
2366 .andBottomLayerIsREComposed(false)
2367 .andIfLegacySupportFor(BT2020_HLG, false)
2368 .thenExpectBestColorModeCallUses(BT2020_HLG)
2369 .execute();
2370}
2371
2372TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2373 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2374 verify().ifTopLayerIs(BT2020_PQ)
2375 .andTopLayerIsREComposed(false)
2376 .andIfBottomLayerIsNotHdr()
2377 .andBottomLayerIsREComposed(false)
2378 .andIfLegacySupportFor(BT2020_PQ, false)
2379 .thenExpectBestColorModeCallUses(BT2020_PQ)
2380 .execute();
2381}
2382
2383TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2384 // If all layers use HLG then HLG is used if there are no other special
2385 // conditions.
2386 verify().ifTopLayerIs(BT2020_HLG)
2387 .andTopLayerIsREComposed(false)
2388 .andIfBottomLayerIsNotHdr()
2389 .andBottomLayerIsREComposed(true)
2390 .andIfLegacySupportFor(BT2020_HLG, false)
2391 .thenExpectBestColorModeCallUses(BT2020_HLG)
2392 .execute();
2393}
2394
2395struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2396 : public OutputUpdateColorProfileTest {
2397 // The various values for CompositionRefreshArgs::outputColorSetting affect
2398 // the chosen renderIntent, along with whether the preferred dataspace is an
2399 // HDR dataspace or not.
2400
2401 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2402 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2403 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2404 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002405 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002406 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2407 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2408 .WillRepeatedly(Return(false));
2409 }
2410
2411 // The tests here involve enough state and GMock setup that using a mini-DSL
2412 // makes the tests much more readable, and allows the test to focus more on
2413 // the intent than on some of the details.
2414
2415 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2416 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2417
2418 struct IfDataspaceChosenState
2419 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2420 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2421 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2422 return nextState<AndOutputColorSettingState>();
2423 }
2424 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2425 return ifDataspaceChosenIs(kNonHdrDataspace);
2426 }
2427 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2428 };
2429
2430 struct AndOutputColorSettingState
2431 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2432 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2433 getInstance()->mRefreshArgs.outputColorSetting = setting;
2434 return nextState<ThenExpectBestColorModeCallUsesState>();
2435 }
2436 };
2437
2438 struct ThenExpectBestColorModeCallUsesState
2439 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2440 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2441 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2442 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2443 _, _));
2444 return nextState<ExecuteState>();
2445 }
2446 };
2447
2448 // Tests call one of these two helper member functions to start using the
2449 // mini-DSL defined above.
2450 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2451};
2452
2453TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2454 Managed_NonHdr_Prefers_Colorimetric) {
2455 verify().ifDataspaceChosenIsNonHdr()
2456 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2457 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2458 .execute();
2459}
2460
2461TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2462 Managed_Hdr_Prefers_ToneMapColorimetric) {
2463 verify().ifDataspaceChosenIsHdr()
2464 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2465 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2466 .execute();
2467}
2468
2469TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2470 verify().ifDataspaceChosenIsNonHdr()
2471 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2472 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2473 .execute();
2474}
2475
2476TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2477 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2478 verify().ifDataspaceChosenIsHdr()
2479 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2480 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2481 .execute();
2482}
2483
2484TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2485 verify().ifDataspaceChosenIsNonHdr()
2486 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2487 .thenExpectBestColorModeCallUses(
2488 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2489 .execute();
2490}
2491
2492TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2493 verify().ifDataspaceChosenIsHdr()
2494 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2495 .thenExpectBestColorModeCallUses(
2496 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2497 .execute();
2498}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002499
2500/*
2501 * Output::beginFrame()
2502 */
2503
Lloyd Piquee5965952019-11-18 16:16:32 -08002504struct OutputBeginFrameTest : public ::testing::Test {
2505 using TestType = OutputBeginFrameTest;
2506
2507 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002508 // Sets up the helper functions called by the function under test to use
2509 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002510 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2511 };
2512
2513 OutputBeginFrameTest() {
2514 mOutput.setDisplayColorProfileForTest(
2515 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2516 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2517 }
2518
2519 struct IfGetDirtyRegionExpectationState
2520 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2521 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2522 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2523 .WillOnce(Return(dirtyRegion));
2524 return nextState<AndIfGetOutputLayerCountExpectationState>();
2525 }
2526 };
2527
2528 struct AndIfGetOutputLayerCountExpectationState
2529 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2530 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2531 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2532 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2533 }
2534 };
2535
2536 struct AndIfLastCompositionHadVisibleLayersState
2537 : public CallOrderStateMachineHelper<TestType,
2538 AndIfLastCompositionHadVisibleLayersState> {
2539 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2540 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2541 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2542 }
2543 };
2544
2545 struct ThenExpectRenderSurfaceBeginFrameCallState
2546 : public CallOrderStateMachineHelper<TestType,
2547 ThenExpectRenderSurfaceBeginFrameCallState> {
2548 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2549 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2550 return nextState<ExecuteState>();
2551 }
2552 };
2553
2554 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2555 [[nodiscard]] auto execute() {
2556 getInstance()->mOutput.beginFrame();
2557 return nextState<CheckPostconditionHadVisibleLayersState>();
2558 }
2559 };
2560
2561 struct CheckPostconditionHadVisibleLayersState
2562 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2563 void checkPostconditionHadVisibleLayers(bool expected) {
2564 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2565 }
2566 };
2567
2568 // Tests call one of these two helper member functions to start using the
2569 // mini-DSL defined above.
2570 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2571
2572 static const Region kEmptyRegion;
2573 static const Region kNotEmptyRegion;
2574
2575 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2576 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2577 StrictMock<OutputPartialMock> mOutput;
2578};
2579
2580const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2581const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2582
2583TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2584 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2585 .andIfGetOutputLayerCountReturns(1u)
2586 .andIfLastCompositionHadVisibleLayersIs(true)
2587 .thenExpectRenderSurfaceBeginFrameCall(true)
2588 .execute()
2589 .checkPostconditionHadVisibleLayers(true);
2590}
2591
2592TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2593 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2594 .andIfGetOutputLayerCountReturns(0u)
2595 .andIfLastCompositionHadVisibleLayersIs(true)
2596 .thenExpectRenderSurfaceBeginFrameCall(true)
2597 .execute()
2598 .checkPostconditionHadVisibleLayers(false);
2599}
2600
2601TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2602 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2603 .andIfGetOutputLayerCountReturns(1u)
2604 .andIfLastCompositionHadVisibleLayersIs(false)
2605 .thenExpectRenderSurfaceBeginFrameCall(true)
2606 .execute()
2607 .checkPostconditionHadVisibleLayers(true);
2608}
2609
2610TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2611 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2612 .andIfGetOutputLayerCountReturns(0u)
2613 .andIfLastCompositionHadVisibleLayersIs(false)
2614 .thenExpectRenderSurfaceBeginFrameCall(false)
2615 .execute()
2616 .checkPostconditionHadVisibleLayers(false);
2617}
2618
2619TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2620 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2621 .andIfGetOutputLayerCountReturns(1u)
2622 .andIfLastCompositionHadVisibleLayersIs(true)
2623 .thenExpectRenderSurfaceBeginFrameCall(false)
2624 .execute()
2625 .checkPostconditionHadVisibleLayers(true);
2626}
2627
2628TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2629 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2630 .andIfGetOutputLayerCountReturns(0u)
2631 .andIfLastCompositionHadVisibleLayersIs(true)
2632 .thenExpectRenderSurfaceBeginFrameCall(false)
2633 .execute()
2634 .checkPostconditionHadVisibleLayers(true);
2635}
2636
2637TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2638 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2639 .andIfGetOutputLayerCountReturns(1u)
2640 .andIfLastCompositionHadVisibleLayersIs(false)
2641 .thenExpectRenderSurfaceBeginFrameCall(false)
2642 .execute()
2643 .checkPostconditionHadVisibleLayers(false);
2644}
2645
2646TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2647 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2648 .andIfGetOutputLayerCountReturns(0u)
2649 .andIfLastCompositionHadVisibleLayersIs(false)
2650 .thenExpectRenderSurfaceBeginFrameCall(false)
2651 .execute()
2652 .checkPostconditionHadVisibleLayers(false);
2653}
2654
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002655/*
2656 * Output::devOptRepaintFlash()
2657 */
2658
Lloyd Piquedb462d82019-11-19 17:58:46 -08002659struct OutputDevOptRepaintFlashTest : public testing::Test {
2660 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002661 // Sets up the helper functions called by the function under test to use
2662 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002663 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002664 MOCK_METHOD2(composeSurfaces,
2665 std::optional<base::unique_fd>(
2666 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002667 MOCK_METHOD0(postFramebuffer, void());
2668 MOCK_METHOD0(prepareFrame, void());
2669 };
2670
2671 OutputDevOptRepaintFlashTest() {
2672 mOutput.setDisplayColorProfileForTest(
2673 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2674 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2675 }
2676
2677 static const Region kEmptyRegion;
2678 static const Region kNotEmptyRegion;
2679
2680 StrictMock<OutputPartialMock> mOutput;
2681 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2682 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2683 CompositionRefreshArgs mRefreshArgs;
2684};
2685
2686const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2687const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2688
2689TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2690 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2691 mRefreshArgs.repaintEverything = true;
2692 mOutput.mState.isEnabled = true;
2693
2694 mOutput.devOptRepaintFlash(mRefreshArgs);
2695}
2696
2697TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2698 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2699 mRefreshArgs.repaintEverything = true;
2700 mOutput.mState.isEnabled = false;
2701
2702 InSequence seq;
2703 EXPECT_CALL(mOutput, postFramebuffer());
2704 EXPECT_CALL(mOutput, prepareFrame());
2705
2706 mOutput.devOptRepaintFlash(mRefreshArgs);
2707}
2708
2709TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2710 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2711 mRefreshArgs.repaintEverything = true;
2712 mOutput.mState.isEnabled = true;
2713
2714 InSequence seq;
2715 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2716 EXPECT_CALL(mOutput, postFramebuffer());
2717 EXPECT_CALL(mOutput, prepareFrame());
2718
2719 mOutput.devOptRepaintFlash(mRefreshArgs);
2720}
2721
2722TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2723 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2724 mRefreshArgs.repaintEverything = false;
2725 mOutput.mState.isEnabled = true;
2726
2727 InSequence seq;
2728 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002729 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002730 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2731 EXPECT_CALL(mOutput, postFramebuffer());
2732 EXPECT_CALL(mOutput, prepareFrame());
2733
2734 mOutput.devOptRepaintFlash(mRefreshArgs);
2735}
2736
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002737/*
2738 * Output::finishFrame()
2739 */
2740
Lloyd Pique03561a62019-11-19 18:34:52 -08002741struct OutputFinishFrameTest : public testing::Test {
2742 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002743 // Sets up the helper functions called by the function under test to use
2744 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002745 MOCK_METHOD2(composeSurfaces,
2746 std::optional<base::unique_fd>(
2747 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002748 MOCK_METHOD0(postFramebuffer, void());
2749 };
2750
2751 OutputFinishFrameTest() {
2752 mOutput.setDisplayColorProfileForTest(
2753 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2754 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2755 }
2756
2757 StrictMock<OutputPartialMock> mOutput;
2758 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2759 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2760 CompositionRefreshArgs mRefreshArgs;
2761};
2762
2763TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2764 mOutput.mState.isEnabled = false;
2765
2766 mOutput.finishFrame(mRefreshArgs);
2767}
2768
2769TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2770 mOutput.mState.isEnabled = true;
2771
2772 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002773 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002774
2775 mOutput.finishFrame(mRefreshArgs);
2776}
2777
2778TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2779 mOutput.mState.isEnabled = true;
2780
2781 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002782 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002783 .WillOnce(Return(ByMove(base::unique_fd())));
2784 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2785
2786 mOutput.finishFrame(mRefreshArgs);
2787}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002788
2789/*
2790 * Output::postFramebuffer()
2791 */
2792
Lloyd Pique07178e32019-11-19 19:15:26 -08002793struct OutputPostFramebufferTest : public testing::Test {
2794 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002795 // Sets up the helper functions called by the function under test to use
2796 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002797 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2798 };
2799
2800 struct Layer {
2801 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002802 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002803 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2804 }
2805
2806 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002807 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002808 StrictMock<HWC2::mock::Layer> hwc2Layer;
2809 };
2810
2811 OutputPostFramebufferTest() {
2812 mOutput.setDisplayColorProfileForTest(
2813 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2814 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2815
2816 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2817 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2818 .WillRepeatedly(Return(&mLayer1.outputLayer));
2819 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2820 .WillRepeatedly(Return(&mLayer2.outputLayer));
2821 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2822 .WillRepeatedly(Return(&mLayer3.outputLayer));
2823 }
2824
2825 StrictMock<OutputPartialMock> mOutput;
2826 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2827 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2828
2829 Layer mLayer1;
2830 Layer mLayer2;
2831 Layer mLayer3;
2832};
2833
2834TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2835 mOutput.mState.isEnabled = false;
2836
2837 mOutput.postFramebuffer();
2838}
2839
2840TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2841 mOutput.mState.isEnabled = true;
2842
2843 compositionengine::Output::FrameFences frameFences;
2844
2845 // This should happen even if there are no output layers.
2846 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2847
2848 // For this test in particular we want to make sure the call expectations
2849 // setup below are satisfied in the specific order.
2850 InSequence seq;
2851
2852 EXPECT_CALL(*mRenderSurface, flip());
2853 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2854 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2855
2856 mOutput.postFramebuffer();
2857}
2858
2859TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2860 // Simulate getting release fences from each layer, and ensure they are passed to the
2861 // front-end layer interface for each layer correctly.
2862
2863 mOutput.mState.isEnabled = true;
2864
2865 // Create three unique fence instances
2866 sp<Fence> layer1Fence = new Fence();
2867 sp<Fence> layer2Fence = new Fence();
2868 sp<Fence> layer3Fence = new Fence();
2869
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002870 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002871 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2872 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2873 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2874
2875 EXPECT_CALL(*mRenderSurface, flip());
2876 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2877 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2878
2879 // Compare the pointers values of each fence to make sure the correct ones
2880 // are passed. This happens to work with the current implementation, but
2881 // would not survive certain calls like Fence::merge() which would return a
2882 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002883 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002884 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002885 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002886 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002887 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002888 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2889
2890 mOutput.postFramebuffer();
2891}
2892
2893TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2894 mOutput.mState.isEnabled = true;
2895 mOutput.mState.usesClientComposition = true;
2896
2897 sp<Fence> clientTargetAcquireFence = new Fence();
2898 sp<Fence> layer1Fence = new Fence();
2899 sp<Fence> layer2Fence = new Fence();
2900 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002901 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002902 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2903 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2904 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2905 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2906
2907 EXPECT_CALL(*mRenderSurface, flip());
2908 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2909 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2910
2911 // Fence::merge is called, and since none of the fences are actually valid,
2912 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2913 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002914 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2915 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2916 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002917
2918 mOutput.postFramebuffer();
2919}
2920
2921TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2922 mOutput.mState.isEnabled = true;
2923 mOutput.mState.usesClientComposition = true;
2924
2925 // This should happen even if there are no (current) output layers.
2926 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2927
2928 // Load up the released layers with some mock instances
2929 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2930 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2931 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2932 Output::ReleasedLayers layers;
2933 layers.push_back(releasedLayer1);
2934 layers.push_back(releasedLayer2);
2935 layers.push_back(releasedLayer3);
2936 mOutput.setReleasedLayers(std::move(layers));
2937
2938 // Set up a fake present fence
2939 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002940 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002941 frameFences.presentFence = presentFence;
2942
2943 EXPECT_CALL(*mRenderSurface, flip());
2944 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2945 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2946
2947 // Each released layer should be given the presentFence.
2948 EXPECT_CALL(*releasedLayer1,
2949 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2950 EXPECT_CALL(*releasedLayer2,
2951 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2952 EXPECT_CALL(*releasedLayer3,
2953 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2954
2955 mOutput.postFramebuffer();
2956
2957 // After the call the list of released layers should have been cleared.
2958 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2959}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002960
2961/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002962 * Output::composeSurfaces()
2963 */
2964
2965struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002966 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002967
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002968 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002969 // Sets up the helper functions called by the function under test to use
2970 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002971 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002972 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002973 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002974 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002975 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002976 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2977 };
2978
2979 OutputComposeSurfacesTest() {
2980 mOutput.setDisplayColorProfileForTest(
2981 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2982 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002983 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002984
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002985 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2986 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002987 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002988 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002989 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002990 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002991 mOutput.mState.dataspace = kDefaultOutputDataspace;
2992 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2993 mOutput.mState.isSecure = false;
2994 mOutput.mState.needsFiltering = false;
2995 mOutput.mState.usesClientComposition = true;
2996 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002997 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002998 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002999
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003000 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003001 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003002 EXPECT_CALL(mCompositionEngine, getTimeStats())
3003 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003004 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3005 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003006 }
3007
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3009 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003010 getInstance()->mReadyFence =
3011 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003012 return nextState<FenceCheckState>();
3013 }
3014 };
3015
3016 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3017 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3018
3019 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3020 };
3021
3022 // Call this member function to start using the mini-DSL defined above.
3023 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3024
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003025 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3026 static constexpr uint32_t kDefaultOutputOrientationFlags =
3027 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003028 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3029 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3030 static constexpr float kDefaultMaxLuminance = 0.9f;
3031 static constexpr float kDefaultAvgLuminance = 0.7f;
3032 static constexpr float kDefaultMinLuminance = 0.1f;
3033
3034 static const Rect kDefaultOutputFrame;
3035 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003036 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003037 static const mat4 kDefaultColorTransformMat;
3038
3039 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003040 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003041 static const HdrCapabilities kHdrCapabilities;
3042
Lloyd Pique56eba802019-08-28 15:45:25 -07003043 StrictMock<mock::CompositionEngine> mCompositionEngine;
3044 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003045 // TODO: make this is a proper mock.
3046 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003047 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3048 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003049 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003050 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3051 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3052 renderengine::ExternalTexture::Usage::READABLE |
3053 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003054
3055 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003056};
3057
3058const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3059const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003060const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003061const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003062const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003063const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3064const HdrCapabilities OutputComposeSurfacesTest::
3065 kHdrCapabilities{{},
3066 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3067 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3068 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003069
Lloyd Piquea76ce462020-01-14 13:06:37 -08003070TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003071 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003072
Lloyd Piquee9eff972020-05-05 12:36:44 -07003073 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003074 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003075
Lloyd Piquea76ce462020-01-14 13:06:37 -08003076 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3077
Lloyd Pique6818fa52019-12-03 12:32:13 -08003078 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003079}
3080
Lloyd Piquee9eff972020-05-05 12:36:44 -07003081TEST_F(OutputComposeSurfacesTest,
3082 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3083 mOutput.mState.usesClientComposition = false;
3084 mOutput.mState.flipClientTarget = true;
3085
Lloyd Pique6818fa52019-12-03 12:32:13 -08003086 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003087 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003088
3089 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3090 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3091
3092 verify().execute().expectAFenceWasReturned();
3093}
3094
3095TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3096 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003097 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003098
3099 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3100
3101 verify().execute().expectNoFenceWasReturned();
3102}
3103
3104TEST_F(OutputComposeSurfacesTest,
3105 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3106 mOutput.mState.usesClientComposition = false;
3107 mOutput.mState.flipClientTarget = true;
3108
3109 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003110 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003111
Lloyd Pique6818fa52019-12-03 12:32:13 -08003112 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003113
Lloyd Pique6818fa52019-12-03 12:32:13 -08003114 verify().execute().expectNoFenceWasReturned();
3115}
Lloyd Pique56eba802019-08-28 15:45:25 -07003116
Lloyd Pique6818fa52019-12-03 12:32:13 -08003117TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3118 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3119 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3120 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003121 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003122 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003123 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003124 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3125 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003126
Lloyd Pique6818fa52019-12-03 12:32:13 -08003127 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003128 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003129 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003130
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131 verify().execute().expectAFenceWasReturned();
3132}
Lloyd Pique56eba802019-08-28 15:45:25 -07003133
Lloyd Pique6818fa52019-12-03 12:32:13 -08003134TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003135 LayerFE::LayerSettings r1;
3136 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003137
3138 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3139 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3140
3141 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3142 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3143 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003144 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003146 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003147 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3148 .WillRepeatedly(
3149 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003150 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003151 clientCompositionLayers.emplace_back(r2);
3152 }));
3153
3154 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003155 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3156 .WillRepeatedly(Return(NO_ERROR));
3157
3158 verify().execute().expectAFenceWasReturned();
3159}
3160
3161TEST_F(OutputComposeSurfacesTest,
3162 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3163 LayerFE::LayerSettings r1;
3164 LayerFE::LayerSettings r2;
3165
3166 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3167 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3168 const constexpr uint32_t kInternalLayerStack = 1234;
3169 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3170
3171 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3172 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3173 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3174 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3175 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3176 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3177 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3178 .WillRepeatedly(
3179 Invoke([&](const Region&,
3180 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3181 clientCompositionLayers.emplace_back(r2);
3182 }));
3183
3184 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003185 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003186 .WillRepeatedly(Return(NO_ERROR));
3187
3188 verify().execute().expectAFenceWasReturned();
3189}
3190
Vishnu Nair9b079a22020-01-21 14:36:08 -08003191TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3192 mOutput.cacheClientCompositionRequests(0);
3193 LayerFE::LayerSettings r1;
3194 LayerFE::LayerSettings r2;
3195
3196 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3197 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3198
3199 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3200 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3201 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003202 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003203 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3204 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3205 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3206 .WillRepeatedly(Return());
3207
3208 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003209 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003210 .Times(2)
3211 .WillOnce(Return(NO_ERROR));
3212
3213 verify().execute().expectAFenceWasReturned();
3214 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3215
3216 verify().execute().expectAFenceWasReturned();
3217 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3218}
3219
3220TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3221 mOutput.cacheClientCompositionRequests(3);
3222 LayerFE::LayerSettings r1;
3223 LayerFE::LayerSettings r2;
3224
3225 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3226 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3227
3228 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3229 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3230 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003231 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003232 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3233 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3234 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3235 .WillRepeatedly(Return());
3236
3237 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003238 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003239 .WillOnce(Return(NO_ERROR));
3240 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3241
3242 verify().execute().expectAFenceWasReturned();
3243 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3244
3245 // We do not expect another call to draw layers.
3246 verify().execute().expectAFenceWasReturned();
3247 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3248}
3249
3250TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3251 LayerFE::LayerSettings r1;
3252 LayerFE::LayerSettings r2;
3253
3254 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3255 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3256
3257 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3258 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3259 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003260 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003261 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3262 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3263 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3264 .WillRepeatedly(Return());
3265
Alec Mouria90a5702021-04-16 16:36:21 +00003266 const auto otherOutputBuffer = std::make_shared<
3267 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3268 renderengine::ExternalTexture::Usage::READABLE |
3269 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003270 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3271 .WillOnce(Return(mOutputBuffer))
3272 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003273 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003274 .WillRepeatedly(Return(NO_ERROR));
3275
3276 verify().execute().expectAFenceWasReturned();
3277 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3278
3279 verify().execute().expectAFenceWasReturned();
3280 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3281}
3282
3283TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3284 LayerFE::LayerSettings r1;
3285 LayerFE::LayerSettings r2;
3286 LayerFE::LayerSettings r3;
3287
3288 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3289 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3290 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3291
3292 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3293 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3294 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003295 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003296 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3297 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3298 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3299 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3300 .WillRepeatedly(Return());
3301
3302 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003303 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003304 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003305 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003306 .WillOnce(Return(NO_ERROR));
3307
3308 verify().execute().expectAFenceWasReturned();
3309 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3310
3311 verify().execute().expectAFenceWasReturned();
3312 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3313}
3314
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3316 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3317 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003318 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003320 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3322 .WillRepeatedly(Return());
3323 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3324 }
3325
3326 struct MixedCompositionState
3327 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3328 auto ifMixedCompositionIs(bool used) {
3329 getInstance()->mOutput.mState.usesDeviceComposition = used;
3330 return nextState<OutputUsesHdrState>();
3331 }
3332 };
3333
3334 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3335 auto andIfUsesHdr(bool used) {
3336 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3337 .WillOnce(Return(used));
3338 return nextState<SkipColorTransformState>();
3339 }
3340 };
3341
3342 struct SkipColorTransformState
3343 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3344 auto andIfSkipColorTransform(bool skip) {
3345 // May be called zero or one times.
3346 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3347 .WillRepeatedly(Return(skip));
3348 return nextState<ExpectDisplaySettingsState>();
3349 }
3350 };
3351
3352 struct ExpectDisplaySettingsState
3353 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3354 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003355 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003356 .WillOnce(Return(NO_ERROR));
3357 return nextState<ExecuteState>();
3358 }
3359 };
3360
3361 // Call this member function to start using the mini-DSL defined above.
3362 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3363};
3364
3365TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3366 verify().ifMixedCompositionIs(true)
3367 .andIfUsesHdr(true)
3368 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003369 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003370 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003371 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003372 .execute()
3373 .expectAFenceWasReturned();
3374}
3375
3376TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3377 verify().ifMixedCompositionIs(true)
3378 .andIfUsesHdr(false)
3379 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003380 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003381 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003382 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383 .execute()
3384 .expectAFenceWasReturned();
3385}
3386
3387TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3388 verify().ifMixedCompositionIs(false)
3389 .andIfUsesHdr(true)
3390 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003391 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003392 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003393 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003394 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003395 .execute()
3396 .expectAFenceWasReturned();
3397}
3398
3399TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3400 verify().ifMixedCompositionIs(false)
3401 .andIfUsesHdr(false)
3402 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003403 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003404 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003405 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003406 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003407 .execute()
3408 .expectAFenceWasReturned();
3409}
3410
3411TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3412 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3413 verify().ifMixedCompositionIs(false)
3414 .andIfUsesHdr(true)
3415 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003416 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003417 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003418 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003419 .execute()
3420 .expectAFenceWasReturned();
3421}
3422
3423struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3424 struct Layer {
3425 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003426 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3427 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428 }
3429
3430 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003431 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432 LayerFECompositionState mLayerFEState;
3433 };
3434
3435 OutputComposeSurfacesTest_HandlesProtectedContent() {
3436 mLayer1.mLayerFEState.hasProtectedContent = false;
3437 mLayer2.mLayerFEState.hasProtectedContent = false;
3438
3439 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3440 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3441 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3442 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3443 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3444
3445 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3446
3447 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3448
3449 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003450 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003451 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3452 .WillRepeatedly(Return());
3453 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003454 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003455 .WillRepeatedly(Return(NO_ERROR));
3456 }
3457
3458 Layer mLayer1;
3459 Layer mLayer2;
3460};
3461
3462TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3463 mOutput.mState.isSecure = false;
3464 mLayer2.mLayerFEState.hasProtectedContent = true;
3465 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003466 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3467 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003469 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003470}
3471
3472TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3473 mOutput.mState.isSecure = true;
3474 mLayer2.mLayerFEState.hasProtectedContent = true;
3475 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3476
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003477 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478}
3479
3480TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3481 mOutput.mState.isSecure = true;
3482 mLayer2.mLayerFEState.hasProtectedContent = false;
3483 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3484 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3485 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3486 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3487 EXPECT_CALL(*mRenderSurface, setProtected(false));
3488
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003489 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003490}
3491
3492TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3493 mOutput.mState.isSecure = true;
3494 mLayer2.mLayerFEState.hasProtectedContent = true;
3495 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3496
3497 // For this test, we also check the call order of key functions.
3498 InSequence seq;
3499
3500 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3501 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3502 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3503 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3504 EXPECT_CALL(*mRenderSurface, setProtected(true));
3505 // Must happen after setting the protected content state.
3506 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003507 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003508
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003509 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003510}
3511
3512TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3513 mOutput.mState.isSecure = true;
3514 mLayer2.mLayerFEState.hasProtectedContent = true;
3515 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3516 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3517 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3518
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003519 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003520}
3521
3522TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3523 mOutput.mState.isSecure = true;
3524 mLayer2.mLayerFEState.hasProtectedContent = true;
3525 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3526 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3527 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3528 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3529
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, ifAlreadyEnabledInRenderEngine) {
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)).WillOnce(Return(true));
3538 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3539 EXPECT_CALL(*mRenderSurface, setProtected(true));
3540
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003541 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003542}
3543
3544TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3545 mOutput.mState.isSecure = true;
3546 mLayer2.mLayerFEState.hasProtectedContent = true;
3547 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3548 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3549 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3550 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3551
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003552 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003553}
3554
3555struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3556 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3557 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3558 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3559 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003560 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003561 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3562 .WillRepeatedly(Return());
3563 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3564 }
3565};
3566
3567TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3568 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3569
3570 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003571 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003572
3573 // For this test, we also check the call order of key functions.
3574 InSequence seq;
3575
3576 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003577 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003578
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003579 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3580}
3581
3582struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3583 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3584 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3585 mLayer.layerFEState.backgroundBlurRadius = 10;
3586 mOutput.editState().isEnabled = true;
3587
Snild Dolkow9e217d62020-04-22 15:53:42 +02003588 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003589 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003590 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3591 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003592 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3593 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003594 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003595 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3596 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3597 .WillRepeatedly(Return(&mLayer.outputLayer));
3598 }
3599
3600 NonInjectedLayer mLayer;
3601 compositionengine::CompositionRefreshArgs mRefreshArgs;
3602};
3603
3604TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3605 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003606 mOutput.updateCompositionState(mRefreshArgs);
3607 mOutput.planComposition();
3608 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003609
3610 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3611 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3612}
3613
3614TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3615 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003616 mOutput.updateCompositionState(mRefreshArgs);
3617 mOutput.planComposition();
3618 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003619
3620 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3621 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003622}
3623
3624/*
3625 * Output::generateClientCompositionRequests()
3626 */
3627
3628struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003629 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003630 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003631 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003632 bool supportsProtectedContent, Region& clearRegion,
3633 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003634 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003635 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003636 }
3637 };
3638
Lloyd Piquea4863342019-12-04 18:45:02 -08003639 struct Layer {
3640 Layer() {
3641 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3642 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003643 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3644 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003645 }
3646
3647 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003648 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003649 LayerFECompositionState mLayerFEState;
3650 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003651 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003652 };
3653
Lloyd Pique56eba802019-08-28 15:45:25 -07003654 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003655 mOutput.mState.needsFiltering = false;
3656
Lloyd Pique56eba802019-08-28 15:45:25 -07003657 mOutput.setDisplayColorProfileForTest(
3658 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3659 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3660 }
3661
Lloyd Pique56eba802019-08-28 15:45:25 -07003662 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3663 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003664 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003665};
3666
Lloyd Piquea4863342019-12-04 18:45:02 -08003667struct GenerateClientCompositionRequestsTest_ThreeLayers
3668 : public GenerateClientCompositionRequestsTest {
3669 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003670 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3671 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3672 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003673 mOutput.mState.transform =
3674 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3675 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003676 mOutput.mState.needsFiltering = false;
3677 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003678
Lloyd Piquea4863342019-12-04 18:45:02 -08003679 for (size_t i = 0; i < mLayers.size(); i++) {
3680 mLayers[i].mOutputLayerState.clearClientTarget = false;
3681 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3682 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003683 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003684 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003685 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3686 mLayers[i].mLayerSettings.alpha = 1.0f;
3687 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003688
Lloyd Piquea4863342019-12-04 18:45:02 -08003689 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3690 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3691 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3692 .WillRepeatedly(Return(true));
3693 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3694 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003695
Lloyd Piquea4863342019-12-04 18:45:02 -08003696 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3697 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003698
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003699 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003700 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003701
Lloyd Piquea4863342019-12-04 18:45:02 -08003702 static const Rect kDisplayFrame;
3703 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003704 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003705
Lloyd Piquea4863342019-12-04 18:45:02 -08003706 std::array<Layer, 3> mLayers;
3707};
Lloyd Pique56eba802019-08-28 15:45:25 -07003708
Lloyd Piquea4863342019-12-04 18:45:02 -08003709const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3710const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003711const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3712 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003713
Lloyd Piquea4863342019-12-04 18:45:02 -08003714TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3715 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3716 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3717 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 Region accumClearRegion(Rect(10, 11, 12, 13));
3720 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3721 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003722 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003724}
3725
Lloyd Piquea4863342019-12-04 18:45:02 -08003726TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3727 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3728 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3729 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3730
3731 Region accumClearRegion(Rect(10, 11, 12, 13));
3732 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3733 accumClearRegion, kDisplayDataspace);
3734 EXPECT_EQ(0u, requests.size());
3735 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3736}
3737
3738TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003739 LayerFE::LayerSettings mShadowSettings;
3740 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003741
Ady Abrahameca9d752021-03-03 12:20:00 -08003742 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003743 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003744 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003745 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003746 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003747 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3748 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003749
3750 Region accumClearRegion(Rect(10, 11, 12, 13));
3751 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3752 accumClearRegion, kDisplayDataspace);
3753 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003754 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3755 EXPECT_EQ(mShadowSettings, requests[1]);
3756 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003757
3758 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3759
3760 // Check that a timestamp was set for the layers that generated requests
3761 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3762 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3763 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3764}
3765
3766TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3767 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3768 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3769 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3770 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3771
3772 mLayers[0].mOutputLayerState.clearClientTarget = false;
3773 mLayers[1].mOutputLayerState.clearClientTarget = false;
3774 mLayers[2].mOutputLayerState.clearClientTarget = false;
3775
3776 mLayers[0].mLayerFEState.isOpaque = true;
3777 mLayers[1].mLayerFEState.isOpaque = true;
3778 mLayers[2].mLayerFEState.isOpaque = true;
3779
Ady Abrahameca9d752021-03-03 12:20:00 -08003780 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003781 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003782
3783 Region accumClearRegion(Rect(10, 11, 12, 13));
3784 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3785 accumClearRegion, kDisplayDataspace);
3786 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003787 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003788
3789 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3790}
3791
3792TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3793 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3794 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3795 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3796 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3797
3798 mLayers[0].mOutputLayerState.clearClientTarget = true;
3799 mLayers[1].mOutputLayerState.clearClientTarget = true;
3800 mLayers[2].mOutputLayerState.clearClientTarget = true;
3801
3802 mLayers[0].mLayerFEState.isOpaque = false;
3803 mLayers[1].mLayerFEState.isOpaque = false;
3804 mLayers[2].mLayerFEState.isOpaque = false;
3805
Ady Abrahameca9d752021-03-03 12:20:00 -08003806 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003807 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003808
3809 Region accumClearRegion(Rect(10, 11, 12, 13));
3810 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3811 accumClearRegion, kDisplayDataspace);
3812 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003813 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003814
3815 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3816}
3817
3818TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003819 // If client composition is performed with some layers set to use device
3820 // composition, device layers after the first layer (device or client) will
3821 // clear the frame buffer if they are opaque and if that layer has a flag
3822 // set to do so. The first layer is skipped as the frame buffer is already
3823 // expected to be clear.
3824
Lloyd Piquea4863342019-12-04 18:45:02 -08003825 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3826 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3827 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003828
Lloyd Piquea4863342019-12-04 18:45:02 -08003829 mLayers[0].mOutputLayerState.clearClientTarget = true;
3830 mLayers[1].mOutputLayerState.clearClientTarget = true;
3831 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003832
Lloyd Piquea4863342019-12-04 18:45:02 -08003833 mLayers[0].mLayerFEState.isOpaque = true;
3834 mLayers[1].mLayerFEState.isOpaque = true;
3835 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003836 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003837 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003838
3839 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3840 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003841 false, /* needs filtering */
3842 false, /* secure */
3843 false, /* supports protected content */
3844 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003845 kDisplayViewport,
3846 kDisplayDataspace,
3847 false /* realContentIsVisible */,
3848 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003849 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003850 };
3851 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3852 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003853 false, /* needs filtering */
3854 false, /* secure */
3855 false, /* supports protected content */
3856 accumClearRegion,
3857 kDisplayViewport,
3858 kDisplayDataspace,
3859 true /* realContentIsVisible */,
3860 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003861 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003862 };
3863
3864 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3865 mBlackoutSettings.source.buffer.buffer = nullptr;
3866 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3867 mBlackoutSettings.alpha = 0.f;
3868 mBlackoutSettings.disableBlending = true;
3869
Ady Abrahameca9d752021-03-03 12:20:00 -08003870 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003871 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003872 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003873 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3874
Lloyd Piquea4863342019-12-04 18:45:02 -08003875 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3876 accumClearRegion, kDisplayDataspace);
3877 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003878
Lloyd Piquea4863342019-12-04 18:45:02 -08003879 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003880 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003881
Vishnu Nair9b079a22020-01-21 14:36:08 -08003882 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003883
Lloyd Piquea4863342019-12-04 18:45:02 -08003884 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3885}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003886
Lloyd Piquea4863342019-12-04 18:45:02 -08003887TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3888 clippedVisibleRegionUsedToGenerateRequest) {
3889 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3890 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3891 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003892
Lloyd Piquea4863342019-12-04 18:45:02 -08003893 Region accumClearRegion(Rect(10, 11, 12, 13));
3894
3895 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3896 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003897 false, /* needs filtering */
3898 false, /* secure */
3899 false, /* supports protected content */
3900 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003901 kDisplayViewport,
3902 kDisplayDataspace,
3903 true /* realContentIsVisible */,
3904 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003905 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003906 };
3907 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3908 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003909 false, /* needs filtering */
3910 false, /* secure */
3911 false, /* supports protected content */
3912 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 kDisplayViewport,
3914 kDisplayDataspace,
3915 true /* realContentIsVisible */,
3916 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003917 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003918 };
3919 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3920 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003921 false, /* needs filtering */
3922 false, /* secure */
3923 false, /* supports protected content */
3924 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003925 kDisplayViewport,
3926 kDisplayDataspace,
3927 true /* realContentIsVisible */,
3928 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003929 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003930 };
3931
Ady Abrahameca9d752021-03-03 12:20:00 -08003932 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003933 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003934 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003935 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003936 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003937 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003938
3939 static_cast<void>(
3940 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3941 accumClearRegion, kDisplayDataspace));
3942}
3943
3944TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3945 perLayerNeedsFilteringUsedToGenerateRequests) {
3946 mOutput.mState.needsFiltering = false;
3947 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3948
3949 Region accumClearRegion(Rect(10, 11, 12, 13));
3950
3951 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3952 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003953 true, /* needs filtering */
3954 false, /* secure */
3955 false, /* supports protected content */
3956 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003957 kDisplayViewport,
3958 kDisplayDataspace,
3959 true /* realContentIsVisible */,
3960 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003961 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003962 };
3963 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3964 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003965 false, /* needs filtering */
3966 false, /* secure */
3967 false, /* supports protected content */
3968 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003969 kDisplayViewport,
3970 kDisplayDataspace,
3971 true /* realContentIsVisible */,
3972 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003973 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003974 };
3975 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3976 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 false, /* needs filtering */
3978 false, /* secure */
3979 false, /* supports protected content */
3980 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003981 kDisplayViewport,
3982 kDisplayDataspace,
3983 true /* realContentIsVisible */,
3984 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003985 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003986 };
3987
Ady Abrahameca9d752021-03-03 12:20:00 -08003988 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003989 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003990 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003992 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003994
3995 static_cast<void>(
3996 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3997 accumClearRegion, kDisplayDataspace));
3998}
3999
4000TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4001 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4002 mOutput.mState.needsFiltering = true;
4003 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4004
4005 Region accumClearRegion(Rect(10, 11, 12, 13));
4006
4007 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4008 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004009 true, /* needs filtering */
4010 false, /* secure */
4011 false, /* supports protected content */
4012 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004013 kDisplayViewport,
4014 kDisplayDataspace,
4015 true /* realContentIsVisible */,
4016 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004017 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004018
Lloyd Piquea4863342019-12-04 18:45:02 -08004019 };
4020 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4021 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004022 true, /* needs filtering */
4023 false, /* secure */
4024 false, /* supports protected content */
4025 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004026 kDisplayViewport,
4027 kDisplayDataspace,
4028 true /* realContentIsVisible */,
4029 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004030 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004031 };
4032 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4033 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004034 true, /* needs filtering */
4035 false, /* secure */
4036 false, /* supports protected content */
4037 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004038 kDisplayViewport,
4039 kDisplayDataspace,
4040 true /* realContentIsVisible */,
4041 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004042 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004043 };
4044
Ady Abrahameca9d752021-03-03 12:20:00 -08004045 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004046 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004047 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004048 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004049 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004050 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004051
4052 static_cast<void>(
4053 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4054 accumClearRegion, kDisplayDataspace));
4055}
4056
4057TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4058 wholeOutputSecurityUsedToGenerateRequests) {
4059 mOutput.mState.isSecure = true;
4060
4061 Region accumClearRegion(Rect(10, 11, 12, 13));
4062
4063 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4064 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004065 false, /* needs filtering */
4066 true, /* secure */
4067 false, /* supports protected content */
4068 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004069 kDisplayViewport,
4070 kDisplayDataspace,
4071 true /* realContentIsVisible */,
4072 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004073 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004074 };
4075 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4076 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004077 false, /* needs filtering */
4078 true, /* secure */
4079 false, /* supports protected content */
4080 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004081 kDisplayViewport,
4082 kDisplayDataspace,
4083 true /* realContentIsVisible */,
4084 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004085 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004086 };
4087 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4088 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004089 false, /* needs filtering */
4090 true, /* secure */
4091 false, /* supports protected content */
4092 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004093 kDisplayViewport,
4094 kDisplayDataspace,
4095 true /* realContentIsVisible */,
4096 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004097 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004098 };
4099
Ady Abrahameca9d752021-03-03 12:20:00 -08004100 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004101 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004102 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004103 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004104 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004105 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004106
4107 static_cast<void>(
4108 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4109 accumClearRegion, kDisplayDataspace));
4110}
4111
4112TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4113 protectedContentSupportUsedToGenerateRequests) {
4114 Region accumClearRegion(Rect(10, 11, 12, 13));
4115
4116 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4117 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004118 false, /* needs filtering */
4119 false, /* secure */
4120 true, /* supports protected content */
4121 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004122 kDisplayViewport,
4123 kDisplayDataspace,
4124 true /* realContentIsVisible */,
4125 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004126 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004127 };
4128 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4129 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004130 false, /* needs filtering */
4131 false, /* secure */
4132 true, /* supports protected content */
4133 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004134 kDisplayViewport,
4135 kDisplayDataspace,
4136 true /* realContentIsVisible */,
4137 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004138 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 };
4140 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4141 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004142 false, /* needs filtering */
4143 false, /* secure */
4144 true, /* supports protected content */
4145 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004146 kDisplayViewport,
4147 kDisplayDataspace,
4148 true /* realContentIsVisible */,
4149 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004150 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004151 };
4152
Ady Abrahameca9d752021-03-03 12:20:00 -08004153 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004154 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004155 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004156 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004157 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004158 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004159
4160 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4161 accumClearRegion,
4162 kDisplayDataspace));
4163}
4164
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004165TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004166 InjectedLayer layer1;
4167 InjectedLayer layer2;
4168 InjectedLayer layer3;
4169
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004170 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004171 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004172 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004173 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004174 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4175 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004176 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004177 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004178 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4179 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004180 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004181 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004182 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4183 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004184
Lloyd Piquede196652020-01-22 17:29:58 -08004185 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004186
Lloyd Piquede196652020-01-22 17:29:58 -08004187 injectOutputLayer(layer1);
4188 injectOutputLayer(layer2);
4189 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004190
4191 mOutput->editState().isEnabled = true;
4192
4193 CompositionRefreshArgs args;
4194 args.updatingGeometryThisFrame = false;
4195 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004196 mOutput->updateCompositionState(args);
4197 mOutput->planComposition();
4198 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004199}
4200
Lucas Dupinc3800b82020-10-02 16:24:48 -07004201TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4202 InjectedLayer layer1;
4203 InjectedLayer layer2;
4204 InjectedLayer layer3;
4205
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004206 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004207 // Layer requesting blur, or below, should request client composition.
4208 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004209 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004210 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4211 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004212 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004213 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004214 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4215 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004216 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004217 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004218 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4219 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004220
4221 BlurRegion region;
4222 layer2.layerFEState.blurRegions.push_back(region);
4223
4224 injectOutputLayer(layer1);
4225 injectOutputLayer(layer2);
4226 injectOutputLayer(layer3);
4227
4228 mOutput->editState().isEnabled = true;
4229
4230 CompositionRefreshArgs args;
4231 args.updatingGeometryThisFrame = false;
4232 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004233 mOutput->updateCompositionState(args);
4234 mOutput->planComposition();
4235 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004236}
4237
Lloyd Piquea4863342019-12-04 18:45:02 -08004238TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4239 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4240 // one layer on the left covering the left side of the output, and one layer
4241 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004242
4243 const Rect kPortraitFrame(0, 0, 1000, 2000);
4244 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004245 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004246 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004247 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004248
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004249 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4250 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4251 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004252 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4253 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004254 mOutput.mState.needsFiltering = false;
4255 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004256
Lloyd Piquea4863342019-12-04 18:45:02 -08004257 Layer leftLayer;
4258 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004259
Lloyd Piquea4863342019-12-04 18:45:02 -08004260 leftLayer.mOutputLayerState.clearClientTarget = false;
4261 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4262 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004263 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004264
Lloyd Piquea4863342019-12-04 18:45:02 -08004265 rightLayer.mOutputLayerState.clearClientTarget = false;
4266 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4267 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004268 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004269
4270 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4271 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4272 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4273 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4274 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4275
4276 Region accumClearRegion(Rect(10, 11, 12, 13));
4277
4278 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4279 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004280 false, /* needs filtering */
4281 true, /* secure */
4282 true, /* supports protected content */
4283 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004284 kPortraitViewport,
4285 kOutputDataspace,
4286 true /* realContentIsVisible */,
4287 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004288 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004289 };
4290
4291 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4292 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004293 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004294 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004295
4296 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4297 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004298 false, /* needs filtering */
4299 true, /* secure */
4300 true, /* supports protected content */
4301 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004302 kPortraitViewport,
4303 kOutputDataspace,
4304 true /* realContentIsVisible */,
4305 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004306 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004307 };
4308
4309 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4310 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004311 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004312 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004313
4314 constexpr bool supportsProtectedContent = true;
4315 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4316 accumClearRegion, kOutputDataspace);
4317 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004318 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4319 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004320}
4321
Vishnu Naira483b4a2019-12-12 15:07:52 -08004322TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4323 shadowRegionOnlyVisibleSkipsContentComposition) {
4324 const Rect kContentWithShadow(40, 40, 70, 90);
4325 const Rect kContent(50, 50, 60, 80);
4326 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4327 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4328
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004329 Region accumClearRegion(Rect(10, 11, 12, 13));
4330 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4331 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004332 false, /* needs filtering */
4333 false, /* secure */
4334 false, /* supports protected content */
4335 accumClearRegion,
4336 kDisplayViewport,
4337 kDisplayDataspace,
4338 false /* realContentIsVisible */,
4339 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004340 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004341 };
4342
Vishnu Nair9b079a22020-01-21 14:36:08 -08004343 LayerFE::LayerSettings mShadowSettings;
4344 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004345
4346 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4347 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4348
4349 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4350 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004351 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004352 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004353
Vishnu Naira483b4a2019-12-12 15:07:52 -08004354 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4355 accumClearRegion, kDisplayDataspace);
4356 ASSERT_EQ(1u, requests.size());
4357
Vishnu Nair9b079a22020-01-21 14:36:08 -08004358 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004359}
4360
4361TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4362 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4363 const Rect kContentWithShadow(40, 40, 70, 90);
4364 const Rect kContent(50, 50, 60, 80);
4365 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4366 const Region kPartialContentWithPartialShadowRegion =
4367 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4368
Vishnu Nair9b079a22020-01-21 14:36:08 -08004369 LayerFE::LayerSettings mShadowSettings;
4370 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004371
4372 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4373 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4374
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004375 Region accumClearRegion(Rect(10, 11, 12, 13));
4376 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4377 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004378 false, /* needs filtering */
4379 false, /* secure */
4380 false, /* supports protected content */
4381 accumClearRegion,
4382 kDisplayViewport,
4383 kDisplayDataspace,
4384 true /* realContentIsVisible */,
4385 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004386 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004387 };
4388
Vishnu Naira483b4a2019-12-12 15:07:52 -08004389 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4390 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004391 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004392 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4393 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004394
Vishnu Naira483b4a2019-12-12 15:07:52 -08004395 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4396 accumClearRegion, kDisplayDataspace);
4397 ASSERT_EQ(2u, requests.size());
4398
Vishnu Nair9b079a22020-01-21 14:36:08 -08004399 EXPECT_EQ(mShadowSettings, requests[0]);
4400 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004401}
4402
Lloyd Pique32cbe282018-10-19 13:09:22 -07004403} // namespace
4404} // namespace android::compositionengine