1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android-base/stringprintf.h>
18 #include <compositionengine/LayerFECompositionState.h>
19 #include <compositionengine/impl/Output.h>
20 #include <compositionengine/impl/OutputCompositionState.h>
21 #include <compositionengine/impl/OutputLayerCompositionState.h>
22 #include <compositionengine/mock/CompositionEngine.h>
23 #include <compositionengine/mock/DisplayColorProfile.h>
24 #include <compositionengine/mock/LayerFE.h>
25 #include <compositionengine/mock/OutputLayer.h>
26 #include <compositionengine/mock/RenderSurface.h>
27 #include <ftl/future.h>
28 #include <gtest/gtest.h>
29 #include <renderengine/ExternalTexture.h>
30 #include <renderengine/impl/ExternalTexture.h>
31 #include <renderengine/mock/FakeExternalTexture.h>
32 #include <renderengine/mock/RenderEngine.h>
33 #include <ui/Rect.h>
34 #include <ui/Region.h>
35
36 #include <cmath>
37 #include <cstdint>
38
39 #include "CallOrderStateMachineHelper.h"
40 #include "MockHWC2.h"
41 #include "RegionMatcher.h"
42
43 namespace android::compositionengine {
44 namespace {
45
46 using testing::_;
47 using testing::ByMove;
48 using testing::ByRef;
49 using testing::DoAll;
50 using testing::ElementsAre;
51 using testing::ElementsAreArray;
52 using testing::Eq;
53 using testing::InSequence;
54 using testing::Invoke;
55 using testing::IsEmpty;
56 using testing::Mock;
57 using testing::Pointee;
58 using testing::Property;
59 using testing::Ref;
60 using testing::Return;
61 using testing::ReturnRef;
62 using testing::SetArgPointee;
63 using testing::StrictMock;
64
65 constexpr auto TR_IDENT = 0u;
66 constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
67 constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
68
69 const mat4 kIdentity;
70 const mat4 kNonIdentityHalf = mat4() * 0.5f;
71 const mat4 kNonIdentityQuarter = mat4() * 0.25f;
72
73 constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
76 using CompositionStrategyPredictionState = android::compositionengine::impl::
77 OutputCompositionState::CompositionStrategyPredictionState;
78
79 struct OutputPartialMockBase : public impl::Output {
80 // compositionengine::Output overrides
getStateandroid::compositionengine::__anon479079190111::OutputPartialMockBase81 const OutputCompositionState& getState() const override { return mState; }
editStateandroid::compositionengine::__anon479079190111::OutputPartialMockBase82 OutputCompositionState& editState() override { return mState; }
83
84 // Use mocks for all the remaining virtual functions
85 // not implemented by the base implementation class.
86 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
87 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
88 MOCK_METHOD2(ensureOutputLayer,
89 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
90 MOCK_METHOD0(finalizePendingOutputLayers, void());
91 MOCK_METHOD0(clearOutputLayers, void());
92 MOCK_CONST_METHOD1(dumpState, void(std::string&));
93 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
94 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
95 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
96
97 impl::OutputCompositionState mState;
98 };
99
100 struct InjectedLayer {
InjectedLayerandroid::compositionengine::__anon479079190111::InjectedLayer101 InjectedLayer() {
102 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
103 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
104 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
105
106 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
107 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
108 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
109 }
110
111 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
112 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
113 LayerFECompositionState layerFEState;
114 impl::OutputLayerCompositionState outputLayerState;
115 };
116
117 struct NonInjectedLayer {
NonInjectedLayerandroid::compositionengine::__anon479079190111::NonInjectedLayer118 NonInjectedLayer() {
119 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
120 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
121 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
122
123 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
124 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
125 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
126 }
127
128 mock::OutputLayer outputLayer;
129 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
130 LayerFECompositionState layerFEState;
131 impl::OutputLayerCompositionState outputLayerState;
132 };
133
134 struct OutputTest : public testing::Test {
135 class Output : public impl::Output {
136 public:
137 using impl::Output::injectOutputLayerForTest;
138 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
139 };
140
createOutputandroid::compositionengine::__anon479079190111::OutputTest141 static std::shared_ptr<Output> createOutput(
142 const compositionengine::CompositionEngine& compositionEngine) {
143 return impl::createOutputTemplated<Output>(compositionEngine);
144 }
145
OutputTestandroid::compositionengine::__anon479079190111::OutputTest146 OutputTest() {
147 mOutput->setDisplayColorProfileForTest(
148 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
149 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
150
151 mOutput->editState().displaySpace.setBounds(
152 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
153 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
154 }
155
injectOutputLayerandroid::compositionengine::__anon479079190111::OutputTest156 void injectOutputLayer(InjectedLayer& layer) {
157 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
158 }
159
injectNullOutputLayerandroid::compositionengine::__anon479079190111::OutputTest160 void injectNullOutputLayer() {
161 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
162 }
163
164 static const Rect kDefaultDisplaySize;
165
166 StrictMock<mock::CompositionEngine> mCompositionEngine;
167 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
170 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
171 };
172
173 const Rect OutputTest::kDefaultDisplaySize{100, 200};
174
175 using ColorProfile = compositionengine::Output::ColorProfile;
176
dumpColorProfile(ColorProfile profile,std::string & result,const char * name)177 void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
178 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
179 toString(profile.mode).c_str(), profile.mode,
180 toString(profile.dataspace).c_str(), profile.dataspace,
181 toString(profile.renderIntent).c_str(), profile.renderIntent,
182 toString(profile.colorSpaceAgnosticDataspace).c_str(),
183 profile.colorSpaceAgnosticDataspace);
184 }
185
186 // Checks for a ColorProfile match
187 MATCHER_P(ColorProfileEq, expected, "") {
188 std::string buf;
189 buf.append("ColorProfiles are not equal\n");
190 dumpColorProfile(expected, buf, "expected value");
191 dumpColorProfile(arg, buf, "actual value");
192 *result_listener << buf;
193
194 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
195 (expected.renderIntent == arg.renderIntent) &&
196 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
197 }
198
199 /*
200 * Basic construction
201 */
202
TEST_F(OutputTest,canInstantiateOutput)203 TEST_F(OutputTest, canInstantiateOutput) {
204 // The validation check checks each required component.
205 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
206 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
207
208 EXPECT_TRUE(mOutput->isValid());
209
210 // If we take away the required components, it is no longer valid.
211 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
212
213 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
214
215 EXPECT_FALSE(mOutput->isValid());
216 }
217
218 /*
219 * Output::setCompositionEnabled()
220 */
221
TEST_F(OutputTest,setCompositionEnabledDoesNothingIfAlreadyEnabled)222 TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
223 mOutput->editState().isEnabled = true;
224
225 mOutput->setCompositionEnabled(true);
226
227 EXPECT_TRUE(mOutput->getState().isEnabled);
228 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
229 }
230
TEST_F(OutputTest,setCompositionEnabledSetsEnabledAndDirtiesEntireOutput)231 TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
232 mOutput->editState().isEnabled = false;
233
234 mOutput->setCompositionEnabled(true);
235
236 EXPECT_TRUE(mOutput->getState().isEnabled);
237 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
238 }
239
TEST_F(OutputTest,setCompositionEnabledSetsDisabledAndDirtiesEntireOutput)240 TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
241 mOutput->editState().isEnabled = true;
242
243 mOutput->setCompositionEnabled(false);
244
245 EXPECT_FALSE(mOutput->getState().isEnabled);
246 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
247 }
248
249 /*
250 * Output::setTreat170mAsSrgb()
251 */
252
TEST_F(OutputTest,setTreat170mAsSrgb)253 TEST_F(OutputTest, setTreat170mAsSrgb) {
254 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
255
256 mOutput->setTreat170mAsSrgb(true);
257 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
258
259 mOutput->setTreat170mAsSrgb(false);
260 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
261 }
262
263 /*
264 * Output::setLayerCachingEnabled()
265 */
266
TEST_F(OutputTest,setLayerCachingEnabled_enablesCaching)267 TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
268 const auto kSize = ui::Size(1, 1);
269 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
270 mOutput->setLayerCachingEnabled(false);
271 mOutput->setLayerCachingEnabled(true);
272
273 EXPECT_TRUE(mOutput->plannerEnabled());
274 }
275
TEST_F(OutputTest,setLayerCachingEnabled_disablesCaching)276 TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
277 const auto kSize = ui::Size(1, 1);
278 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
279 mOutput->setLayerCachingEnabled(true);
280 mOutput->setLayerCachingEnabled(false);
281
282 EXPECT_FALSE(mOutput->plannerEnabled());
283 }
284
TEST_F(OutputTest,setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo)285 TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
286 renderengine::mock::RenderEngine renderEngine;
287 const auto kSize = ui::Size(1, 1);
288 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
289 mOutput->setLayerCachingEnabled(true);
290
291 // Inject some layers
292 InjectedLayer layer;
293 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
294 renderengine::impl::
295 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
296 renderengine::impl::ExternalTexture::Usage::READABLE |
297 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
298 injectOutputLayer(layer);
299 // inject a null layer to check for null exceptions
300 injectNullOutputLayer();
301
302 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
303 mOutput->setLayerCachingEnabled(false);
304 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
305 }
306
307 /*
308 * Output::setProjection()
309 */
310
TEST_F(OutputTest,setProjectionWorks)311 TEST_F(OutputTest, setProjectionWorks) {
312 const Rect displayRect{0, 0, 1000, 2000};
313 mOutput->editState().displaySpace.setBounds(
314 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
315 mOutput->editState().framebufferSpace.setBounds(
316 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
317
318 const ui::Rotation orientation = ui::ROTATION_90;
319 const Rect frame{50, 60, 100, 100};
320 const Rect viewport{10, 20, 30, 40};
321
322 mOutput->setProjection(orientation, viewport, frame);
323
324 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
325 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
326 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
327
328 const auto state = mOutput->getState();
329 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
330 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
331 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
332
333 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
334 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
335 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
336
337 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
338 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
339 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
340
341 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
342 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
343 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
344
345 EXPECT_EQ(state.displaySpace.getContent(),
346 state.transform.transform(state.layerStackSpace.getContent()));
347
348 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
349 }
350
TEST_F(OutputTest,setProjectionWithSmallFramebufferWorks)351 TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
352 const Rect displayRect{0, 0, 1000, 2000};
353 const Rect framebufferRect{0, 0, 500, 1000};
354 mOutput->editState().displaySpace.setBounds(
355 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
356 mOutput->editState().framebufferSpace.setBounds(
357 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
358
359 const ui::Rotation orientation = ui::ROTATION_90;
360 const Rect frame{50, 60, 100, 100};
361 const Rect viewport{10, 20, 30, 40};
362
363 mOutput->setProjection(orientation, viewport, frame);
364
365 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
366 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
367 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
368
369 const auto state = mOutput->getState();
370 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
371 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
372 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
373
374 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
375 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
376 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
377
378 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
379 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
380 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
381
382 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
383 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
384 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
385
386 EXPECT_EQ(state.displaySpace.getContent(),
387 state.transform.transform(state.layerStackSpace.getContent()));
388 }
389
390 /*
391 * Output::setDisplaySize()
392 */
393
TEST_F(OutputTest,setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput)394 TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
395 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
396 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
397 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
398 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
399 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
400 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
401 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
402 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
403 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
404 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
405
406 const ui::Size newDisplaySize{500, 1000};
407
408 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
409
410 mOutput->setDisplaySize(newDisplaySize);
411
412 const auto state = mOutput->getState();
413
414 const Rect displayRect(newDisplaySize);
415 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
416 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
417 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
418
419 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
420 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
421
422 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
423 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
424
425 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
426 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
427
428 EXPECT_EQ(state.displaySpace.getContent(),
429 state.transform.transform(state.layerStackSpace.getContent()));
430
431 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
432 }
433
434 /*
435 * Output::setLayerFilter()
436 */
437
TEST_F(OutputTest,setLayerFilterSetsFilterAndDirtiesEntireOutput)438 TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
439 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
440 mOutput->setLayerFilter(kFilter);
441
442 const auto& state = mOutput->getState();
443 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
444 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
445
446 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
447 }
448
449 /*
450 * Output::setColorTransform
451 */
452
TEST_F(OutputTest,setColorTransformWithNoChangeFlaggedSkipsUpdates)453 TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
454 mOutput->editState().colorTransformMatrix = kIdentity;
455
456 // If no colorTransformMatrix is set the update should be skipped.
457 CompositionRefreshArgs refreshArgs;
458 refreshArgs.colorTransformMatrix = std::nullopt;
459
460 mOutput->setColorTransform(refreshArgs);
461
462 // The internal state should be unchanged
463 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
464
465 // No dirty region should be set
466 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
467 }
468
TEST_F(OutputTest,setColorTransformWithNoActualChangeSkipsUpdates)469 TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
470 mOutput->editState().colorTransformMatrix = kIdentity;
471
472 // Attempting to set the same colorTransformMatrix that is already set should
473 // also skip the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kIdentity;
476
477 mOutput->setColorTransform(refreshArgs);
478
479 // The internal state should be unchanged
480 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
481
482 // No dirty region should be set
483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
484 }
485
TEST_F(OutputTest,setColorTransformPerformsUpdateToIdentity)486 TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
487 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
488
489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kIdentity;
492
493 mOutput->setColorTransform(refreshArgs);
494
495 // The internal state should have been updated
496 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
497
498 // The dirtyRegion should be set to the full display size
499 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
500 }
501
TEST_F(OutputTest,setColorTransformPerformsUpdateForIdentityToHalf)502 TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
503 mOutput->editState().colorTransformMatrix = kIdentity;
504
505 // Setting a different colorTransformMatrix should perform the update.
506 CompositionRefreshArgs refreshArgs;
507 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
508
509 mOutput->setColorTransform(refreshArgs);
510
511 // The internal state should have been updated
512 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
513
514 // The dirtyRegion should be set to the full display size
515 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
516 }
517
TEST_F(OutputTest,setColorTransformPerformsUpdateForHalfToQuarter)518 TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
519 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
520
521 // Setting a different colorTransformMatrix should perform the update.
522 CompositionRefreshArgs refreshArgs;
523 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
524
525 mOutput->setColorTransform(refreshArgs);
526
527 // The internal state should have been updated
528 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
529
530 // The dirtyRegion should be set to the full display size
531 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
532 }
533
534 /*
535 * Output::setColorProfile
536 */
537
538 using OutputSetColorProfileTest = OutputTest;
539
TEST_F(OutputSetColorProfileTest,setsStateAndDirtiesOutputIfChanged)540 TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
541 using ColorProfile = Output::ColorProfile;
542
543 EXPECT_CALL(*mDisplayColorProfile,
544 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
545 ui::Dataspace::UNKNOWN))
546 .WillOnce(Return(ui::Dataspace::UNKNOWN));
547 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
548
549 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
550 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
551 ui::Dataspace::UNKNOWN});
552
553 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
554 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
555 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
556 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
557
558 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
559 }
560
TEST_F(OutputSetColorProfileTest,doesNothingIfNoChange)561 TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
562 using ColorProfile = Output::ColorProfile;
563
564 EXPECT_CALL(*mDisplayColorProfile,
565 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
566 ui::Dataspace::UNKNOWN))
567 .WillOnce(Return(ui::Dataspace::UNKNOWN));
568
569 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
570 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
571 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
572 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
573
574 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
575 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
576 ui::Dataspace::UNKNOWN});
577
578 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
579 }
580
581 /*
582 * Output::setRenderSurface()
583 */
584
TEST_F(OutputTest,setRenderSurfaceResetsBounds)585 TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
586 const ui::Size newDisplaySize{640, 480};
587
588 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
589 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
590
591 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
592
593 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
594 }
595
596 /**
597 * Output::setDisplayBrightness()
598 */
599
TEST_F(OutputTest,setNextBrightness)600 TEST_F(OutputTest, setNextBrightness) {
601 constexpr float kDisplayBrightness = 0.5f;
602 mOutput->setNextBrightness(kDisplayBrightness);
603 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
604 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
605 }
606
607 /*
608 * Output::getDirtyRegion()
609 */
610
TEST_F(OutputTest,getDirtyRegion)611 TEST_F(OutputTest, getDirtyRegion) {
612 const Rect viewport{100, 200};
613 mOutput->editState().layerStackSpace.setContent(viewport);
614 mOutput->editState().dirtyRegion.set(50, 300);
615
616 // The dirty region should be clipped to the display bounds.
617 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
618 }
619
620 /*
621 * Output::includesLayer()
622 */
623
TEST_F(OutputTest,layerFiltering)624 TEST_F(OutputTest, layerFiltering) {
625 const ui::LayerStack layerStack1{123u};
626 const ui::LayerStack layerStack2{456u};
627
628 // If the output is associated to layerStack1 and to an internal display...
629 mOutput->setLayerFilter({layerStack1, true});
630
631 // It excludes layers with no layer stack, internal-only or not.
632 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
633 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
634
635 // It includes layers on layerStack1, internal-only or not.
636 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
637 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
638 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
640
641 // If the output is associated to layerStack1 but not to an internal display...
642 mOutput->setLayerFilter({layerStack1, false});
643
644 // It includes layers on layerStack1, unless they are internal-only.
645 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
646 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
647 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
648 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
649 }
650
TEST_F(OutputTest,layerFilteringWithoutCompositionState)651 TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
652 NonInjectedLayer layer;
653 sp<LayerFE> layerFE(layer.layerFE);
654
655 // Layers without composition state are excluded.
656 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
657 EXPECT_FALSE(mOutput->includesLayer(layerFE));
658 }
659
TEST_F(OutputTest,layerFilteringWithCompositionState)660 TEST_F(OutputTest, layerFilteringWithCompositionState) {
661 NonInjectedLayer layer;
662 sp<LayerFE> layerFE(layer.layerFE);
663
664 const ui::LayerStack layerStack1{123u};
665 const ui::LayerStack layerStack2{456u};
666
667 // If the output is associated to layerStack1 and to an internal display...
668 mOutput->setLayerFilter({layerStack1, true});
669
670 // It excludes layers with no layer stack, internal-only or not.
671 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
673
674 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
676
677 // It includes layers on layerStack1, internal-only or not.
678 layer.layerFEState.outputFilter = {layerStack1, false};
679 EXPECT_TRUE(mOutput->includesLayer(layerFE));
680
681 layer.layerFEState.outputFilter = {layerStack1, true};
682 EXPECT_TRUE(mOutput->includesLayer(layerFE));
683
684 layer.layerFEState.outputFilter = {layerStack2, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
686
687 layer.layerFEState.outputFilter = {layerStack2, false};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
689
690 // If the output is associated to layerStack1 but not to an internal display...
691 mOutput->setLayerFilter({layerStack1, false});
692
693 // It includes layers on layerStack1, unless they are internal-only.
694 layer.layerFEState.outputFilter = {layerStack1, false};
695 EXPECT_TRUE(mOutput->includesLayer(layerFE));
696
697 layer.layerFEState.outputFilter = {layerStack1, true};
698 EXPECT_FALSE(mOutput->includesLayer(layerFE));
699
700 layer.layerFEState.outputFilter = {layerStack2, true};
701 EXPECT_FALSE(mOutput->includesLayer(layerFE));
702
703 layer.layerFEState.outputFilter = {layerStack2, false};
704 EXPECT_FALSE(mOutput->includesLayer(layerFE));
705 }
706
707 /*
708 * Output::getOutputLayerForLayer()
709 */
710
TEST_F(OutputTest,getOutputLayerForLayerWorks)711 TEST_F(OutputTest, getOutputLayerForLayerWorks) {
712 InjectedLayer layer1;
713 InjectedLayer layer2;
714 NonInjectedLayer layer3;
715
716 injectOutputLayer(layer1);
717 injectNullOutputLayer();
718 injectOutputLayer(layer2);
719
720 // If the input layer matches the first OutputLayer, it will be returned.
721 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
722 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
723
724 // If the input layer matches the second OutputLayer, it will be returned.
725 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
726 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
727 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
728
729 // If the input layer does not match an output layer, null will be returned.
730 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
731 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
732 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
733 }
734
735 /*
736 * Output::setReleasedLayers()
737 */
738
739 using OutputSetReleasedLayersTest = OutputTest;
740
TEST_F(OutputSetReleasedLayersTest,setReleasedLayersTakesGivenLayers)741 TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
742 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
743 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
744 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
745
746 Output::ReleasedLayers layers;
747 layers.push_back(layer1FE);
748 layers.push_back(layer2FE);
749 layers.push_back(layer3FE);
750
751 mOutput->setReleasedLayers(std::move(layers));
752
753 const auto& setLayers = mOutput->getReleasedLayersForTest();
754 ASSERT_EQ(3u, setLayers.size());
755 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
756 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
757 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
758 }
759
760 /*
761 * Output::updateAndWriteCompositionState()
762 */
763
764 using OutputUpdateAndWriteCompositionStateTest = OutputTest;
765
TEST_F(OutputUpdateAndWriteCompositionStateTest,doesNothingIfLayers)766 TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
767 mOutput->editState().isEnabled = true;
768
769 CompositionRefreshArgs args;
770 mOutput->updateCompositionState(args);
771 mOutput->planComposition();
772 mOutput->writeCompositionState(args);
773 }
774
TEST_F(OutputUpdateAndWriteCompositionStateTest,doesNothingIfOutputNotEnabled)775 TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
779
780 mOutput->editState().isEnabled = false;
781
782 injectOutputLayer(layer1);
783 injectOutputLayer(layer2);
784 injectOutputLayer(layer3);
785
786 CompositionRefreshArgs args;
787 mOutput->updateCompositionState(args);
788 mOutput->planComposition();
789 mOutput->writeCompositionState(args);
790 }
791
TEST_F(OutputUpdateAndWriteCompositionStateTest,updatesLayerContentForAllLayers)792 TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
793 InjectedLayer layer1;
794 InjectedLayer layer2;
795 InjectedLayer layer3;
796
797 uint32_t z = 0;
798 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
799 EXPECT_CALL(*layer1.outputLayer,
800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
802 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
803 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
804 EXPECT_CALL(*layer2.outputLayer,
805 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
806 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
807 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
808 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
809 EXPECT_CALL(*layer3.outputLayer,
810 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
811 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
812 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
813
814 injectOutputLayer(layer1);
815 injectOutputLayer(layer2);
816 injectOutputLayer(layer3);
817
818 mOutput->editState().isEnabled = true;
819
820 CompositionRefreshArgs args;
821 args.updatingGeometryThisFrame = false;
822 args.devOptForceClientComposition = false;
823 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
824 mOutput->updateCompositionState(args);
825 mOutput->planComposition();
826 mOutput->writeCompositionState(args);
827 }
828
TEST_F(OutputUpdateAndWriteCompositionStateTest,updatesLayerGeometryAndContentForAllLayers)829 TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
830 InjectedLayer layer1;
831 InjectedLayer layer2;
832 InjectedLayer layer3;
833
834 uint32_t z = 0;
835 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
836 EXPECT_CALL(*layer1.outputLayer,
837 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
839 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
840 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
841 EXPECT_CALL(*layer2.outputLayer,
842 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
843 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
844 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
845 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
846 EXPECT_CALL(*layer3.outputLayer,
847 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
848 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
849 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
850
851 injectOutputLayer(layer1);
852 injectOutputLayer(layer2);
853 injectOutputLayer(layer3);
854
855 mOutput->editState().isEnabled = true;
856
857 CompositionRefreshArgs args;
858 args.updatingGeometryThisFrame = true;
859 args.devOptForceClientComposition = false;
860 mOutput->updateCompositionState(args);
861 mOutput->planComposition();
862 mOutput->writeCompositionState(args);
863 }
864
TEST_F(OutputUpdateAndWriteCompositionStateTest,forcesClientCompositionForAllLayers)865 TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
866 InjectedLayer layer1;
867 InjectedLayer layer2;
868 InjectedLayer layer3;
869
870 uint32_t z = 0;
871 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
872 EXPECT_CALL(*layer1.outputLayer,
873 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
875 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
876 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
877 EXPECT_CALL(*layer2.outputLayer,
878 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
879 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
880 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
881 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
882 EXPECT_CALL(*layer3.outputLayer,
883 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
884 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
885 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
886
887 injectOutputLayer(layer1);
888 injectOutputLayer(layer2);
889 injectOutputLayer(layer3);
890
891 mOutput->editState().isEnabled = true;
892
893 CompositionRefreshArgs args;
894 args.updatingGeometryThisFrame = false;
895 args.devOptForceClientComposition = true;
896 mOutput->updateCompositionState(args);
897 mOutput->planComposition();
898 mOutput->writeCompositionState(args);
899 }
900
TEST_F(OutputUpdateAndWriteCompositionStateTest,peekThroughLayerChangesOrder)901 TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
902 renderengine::mock::RenderEngine renderEngine;
903 InjectedLayer layer0;
904 InjectedLayer layer1;
905 InjectedLayer layer2;
906 InjectedLayer layer3;
907
908 InSequence seq;
909 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
910 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
911 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
912 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
913 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
914
915 uint32_t z = 0;
916 EXPECT_CALL(*layer0.outputLayer,
917 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
918 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
919 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
920
921 // After calling planComposition (which clears overrideInfo), this test sets
922 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
923 // comes first, setting isPeekingThrough to true and zIsOverridden to true
924 // for it and the following layers.
925 EXPECT_CALL(*layer3.outputLayer,
926 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
927 /*zIsOverridden*/ true, /*isPeekingThrough*/
928 true));
929 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
930 EXPECT_CALL(*layer1.outputLayer,
931 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
932 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
933 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
934 EXPECT_CALL(*layer2.outputLayer,
935 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
936 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
937 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
938
939 injectOutputLayer(layer0);
940 injectOutputLayer(layer1);
941 injectOutputLayer(layer2);
942 injectOutputLayer(layer3);
943
944 mOutput->editState().isEnabled = true;
945
946 CompositionRefreshArgs args;
947 args.updatingGeometryThisFrame = true;
948 args.devOptForceClientComposition = false;
949 mOutput->updateCompositionState(args);
950 mOutput->planComposition();
951
952 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
953 renderengine::impl::
954 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
955 renderengine::impl::ExternalTexture::Usage::READABLE |
956 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
957 layer1.outputLayerState.overrideInfo.buffer = buffer;
958 layer2.outputLayerState.overrideInfo.buffer = buffer;
959 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
960 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
961
962 mOutput->writeCompositionState(args);
963 }
964
965 /*
966 * Output::prepareFrame()
967 */
968
969 struct OutputPrepareFrameTest : public testing::Test {
970 struct OutputPartialMock : public OutputPartialMockBase {
971 // Sets up the helper functions called by the function under test to use
972 // mock implementations.
973 MOCK_METHOD1(chooseCompositionStrategy,
974 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
975 MOCK_METHOD0(resetCompositionStrategy, void());
976 };
977
OutputPrepareFrameTestandroid::compositionengine::__anon479079190111::OutputPrepareFrameTest978 OutputPrepareFrameTest() {
979 mOutput.setDisplayColorProfileForTest(
980 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
981 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
982 }
983
984 StrictMock<mock::CompositionEngine> mCompositionEngine;
985 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
986 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
987 StrictMock<OutputPartialMock> mOutput;
988 };
989
TEST_F(OutputPrepareFrameTest,takesEarlyOutIfNotEnabled)990 TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
991 mOutput.editState().isEnabled = false;
992
993 mOutput.prepareFrame();
994 }
995
TEST_F(OutputPrepareFrameTest,delegatesToChooseCompositionStrategyAndRenderSurface)996 TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
997 mOutput.editState().isEnabled = true;
998 mOutput.editState().usesClientComposition = false;
999 mOutput.editState().usesDeviceComposition = true;
1000
1001 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1002 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1003 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1004 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1005
1006 mOutput.prepareFrame();
1007 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
1008 }
1009
1010 // Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1011 // base chooseCompositionStrategy() is invoked.
TEST_F(OutputTest,prepareFrameSetsClientCompositionOnlyByDefault)1012 TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
1013 mOutput->editState().isEnabled = true;
1014 mOutput->editState().usesClientComposition = false;
1015 mOutput->editState().usesDeviceComposition = true;
1016
1017 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1018
1019 mOutput->prepareFrame();
1020
1021 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1022 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
1023 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
1024 }
1025
1026 struct OutputPrepareFrameAsyncTest : public testing::Test {
1027 struct OutputPartialMock : public OutputPartialMockBase {
1028 // Sets up the helper functions called by the function under test to use
1029 // mock implementations.
1030 MOCK_METHOD1(chooseCompositionStrategy,
1031 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1032 MOCK_METHOD0(updateProtectedContentState, void());
1033 MOCK_METHOD2(dequeueRenderBuffer,
1034 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1035 MOCK_METHOD1(
1036 chooseCompositionStrategyAsync,
1037 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1038 MOCK_METHOD3(composeSurfaces,
1039 std::optional<base::unique_fd>(const Region&,
1040 std::shared_ptr<renderengine::ExternalTexture>,
1041 base::unique_fd&));
1042 MOCK_METHOD0(resetCompositionStrategy, void());
1043 };
1044
OutputPrepareFrameAsyncTestandroid::compositionengine::__anon479079190111::OutputPrepareFrameAsyncTest1045 OutputPrepareFrameAsyncTest() {
1046 mOutput.setDisplayColorProfileForTest(
1047 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1048 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1049 }
1050
1051 StrictMock<mock::CompositionEngine> mCompositionEngine;
1052 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1053 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1054 StrictMock<OutputPartialMock> mOutput;
1055 CompositionRefreshArgs mRefreshArgs;
1056 };
1057
TEST_F(OutputPrepareFrameAsyncTest,delegatesToChooseCompositionStrategyAndRenderSurface)1058 TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1059 mOutput.editState().isEnabled = true;
1060 mOutput.editState().usesClientComposition = false;
1061 mOutput.editState().usesDeviceComposition = true;
1062 mOutput.editState().previousDeviceRequestedChanges =
1063 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1064 std::promise<bool> p;
1065 p.set_value(true);
1066
1067 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1068 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1069 EXPECT_CALL(mOutput, updateProtectedContentState());
1070 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1071 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1072 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1073 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1074 Return(ByMove(p.get_future()))));
1075 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
1076
1077 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
1078 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
1079 EXPECT_FALSE(result.bufferAvailable());
1080 }
1081
TEST_F(OutputPrepareFrameAsyncTest,skipCompositionOnDequeueFailure)1082 TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1083 mOutput.editState().isEnabled = true;
1084 mOutput.editState().usesClientComposition = false;
1085 mOutput.editState().usesDeviceComposition = true;
1086 mOutput.editState().previousDeviceRequestedChanges =
1087 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1088 std::promise<bool> p;
1089 p.set_value(true);
1090
1091 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1092 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1093 EXPECT_CALL(mOutput, updateProtectedContentState());
1094 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1095 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1096 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1097 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1098 Return(ByMove(p.get_future()))));
1099
1100 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
1101 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
1102 EXPECT_FALSE(result.bufferAvailable());
1103 }
1104
1105 // Tests that in the event of hwc error when choosing composition strategy, we would fall back
1106 // client composition
TEST_F(OutputPrepareFrameAsyncTest,chooseCompositionStrategyFailureCallsPrepareFrame)1107 TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1108 mOutput.editState().isEnabled = true;
1109 mOutput.editState().usesClientComposition = false;
1110 mOutput.editState().usesDeviceComposition = true;
1111 mOutput.editState().previousDeviceRequestedChanges =
1112 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1113 std::promise<bool> p;
1114 p.set_value(false);
1115 std::shared_ptr<renderengine::ExternalTexture> tex =
1116 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1117 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1118 2);
1119 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1120 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1121 EXPECT_CALL(mOutput, updateProtectedContentState());
1122 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1123 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1124 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1125 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1126 return p.get_future();
1127 });
1128 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
1129
1130 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
1131 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
1132 EXPECT_TRUE(result.bufferAvailable());
1133 }
1134
TEST_F(OutputPrepareFrameAsyncTest,predictionMiss)1135 TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1136 mOutput.editState().isEnabled = true;
1137 mOutput.editState().usesClientComposition = false;
1138 mOutput.editState().usesDeviceComposition = true;
1139 mOutput.editState().previousDeviceRequestedChanges =
1140 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1141 auto newDeviceRequestedChanges =
1142 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1143 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1144 std::promise<bool> p;
1145 p.set_value(false);
1146 std::shared_ptr<renderengine::ExternalTexture> tex =
1147 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1148 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1149 2);
1150
1151 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1152 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1153 EXPECT_CALL(mOutput, updateProtectedContentState());
1154 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1155 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1156 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1157 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1158 return p.get_future();
1159 });
1160 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
1161
1162 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
1163 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
1164 EXPECT_TRUE(result.bufferAvailable());
1165 }
1166
1167 /*
1168 * Output::prepare()
1169 */
1170
1171 struct OutputPrepareTest : public testing::Test {
1172 struct OutputPartialMock : public OutputPartialMockBase {
1173 // Sets up the helper functions called by the function under test to use
1174 // mock implementations.
1175 MOCK_METHOD2(rebuildLayerStacks,
1176 void(const compositionengine::CompositionRefreshArgs&,
1177 compositionengine::LayerFESet&));
1178 };
1179
OutputPrepareTestandroid::compositionengine::__anon479079190111::OutputPrepareTest1180 OutputPrepareTest() {
1181 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1182 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1183 .WillRepeatedly(Return(&mLayer1.outputLayer));
1184 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1185 .WillRepeatedly(Return(&mLayer2.outputLayer));
1186
1187 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1188 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1189 }
1190
1191 struct Layer {
1192 StrictMock<mock::OutputLayer> outputLayer;
1193 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1194 };
1195
1196 StrictMock<OutputPartialMock> mOutput;
1197 CompositionRefreshArgs mRefreshArgs;
1198 LayerFESet mGeomSnapshots;
1199 Layer mLayer1;
1200 Layer mLayer2;
1201 };
1202
TEST_F(OutputPrepareTest,callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks)1203 TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
1204 InSequence seq;
1205
1206 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1207
1208 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1209 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1210 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1211
1212 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1213 }
1214
TEST_F(OutputPrepareTest,skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks)1215 TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1216 InSequence seq;
1217
1218 mRefreshArgs.bufferIdsToUncache = {};
1219
1220 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1221 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1222 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
1223
1224 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1225 }
1226
1227 /*
1228 * Output::rebuildLayerStacks()
1229 */
1230
1231 struct OutputRebuildLayerStacksTest : public testing::Test {
1232 struct OutputPartialMock : public OutputPartialMockBase {
1233 // Sets up the helper functions called by the function under test to use
1234 // mock implementations.
1235 MOCK_METHOD2(collectVisibleLayers,
1236 void(const compositionengine::CompositionRefreshArgs&,
1237 compositionengine::Output::CoverageState&));
1238 };
1239
OutputRebuildLayerStacksTestandroid::compositionengine::__anon479079190111::OutputRebuildLayerStacksTest1240 OutputRebuildLayerStacksTest() {
1241 mOutput.mState.isEnabled = true;
1242 mOutput.mState.transform = kIdentityTransform;
1243 mOutput.mState.displaySpace.setBounds(
1244 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
1245
1246 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1247
1248 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1249
1250 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1251 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1252 }
1253
setTestCoverageValuesandroid::compositionengine::__anon479079190111::OutputRebuildLayerStacksTest1254 void setTestCoverageValues(const CompositionRefreshArgs&,
1255 compositionengine::Output::CoverageState& state) {
1256 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1257 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1258 state.dirtyRegion = mCoverageDirtyRegionToSet;
1259 }
1260
1261 static const ui::Transform kIdentityTransform;
1262 static const ui::Transform kRotate90Transform;
1263 static const Rect kOutputBounds;
1264
1265 StrictMock<OutputPartialMock> mOutput;
1266 CompositionRefreshArgs mRefreshArgs;
1267 LayerFESet mGeomSnapshots;
1268 Region mCoverageAboveCoveredLayersToSet;
1269 Region mCoverageAboveOpaqueLayersToSet;
1270 Region mCoverageDirtyRegionToSet;
1271 };
1272
1273 const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1274 const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1275 const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1276
TEST_F(OutputRebuildLayerStacksTest,doesNothingIfNotEnabled)1277 TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1278 mOutput.mState.isEnabled = false;
1279
1280 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1281 }
1282
TEST_F(OutputRebuildLayerStacksTest,doesNothingIfNotUpdatingGeometryThisFrame)1283 TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1284 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1285
1286 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1287 }
1288
TEST_F(OutputRebuildLayerStacksTest,computesUndefinedRegionWithNoRotationAndFullCoverage)1289 TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1290 mOutput.mState.transform = kIdentityTransform;
1291
1292 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1293
1294 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1295
1296 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1297 }
1298
TEST_F(OutputRebuildLayerStacksTest,computesUndefinedRegionWithNoRotationAndPartialCoverage)1299 TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1300 mOutput.mState.transform = kIdentityTransform;
1301
1302 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1303
1304 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1305
1306 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1307 }
1308
TEST_F(OutputRebuildLayerStacksTest,computesUndefinedRegionWith90RotationAndFullCoverage)1309 TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1310 mOutput.mState.transform = kRotate90Transform;
1311
1312 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1313
1314 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1315
1316 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1317 }
1318
TEST_F(OutputRebuildLayerStacksTest,computesUndefinedRegionWith90RotationAndPartialCoverage)1319 TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1320 mOutput.mState.transform = kRotate90Transform;
1321
1322 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1323
1324 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1325
1326 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1327 }
1328
TEST_F(OutputRebuildLayerStacksTest,addsToDirtyRegionWithNoRotation)1329 TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1330 mOutput.mState.transform = kIdentityTransform;
1331 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1332
1333 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1334
1335 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1336
1337 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1338 }
1339
TEST_F(OutputRebuildLayerStacksTest,addsToDirtyRegionWith90Rotation)1340 TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1341 mOutput.mState.transform = kRotate90Transform;
1342 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1343
1344 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1345
1346 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1347
1348 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1349 }
1350
1351 /*
1352 * Output::collectVisibleLayers()
1353 */
1354
1355 struct OutputCollectVisibleLayersTest : public testing::Test {
1356 struct OutputPartialMock : public OutputPartialMockBase {
1357 // Sets up the helper functions called by the function under test to use
1358 // mock implementations.
1359 MOCK_METHOD2(ensureOutputLayerIfVisible,
1360 void(sp<compositionengine::LayerFE>&,
1361 compositionengine::Output::CoverageState&));
1362 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1363 MOCK_METHOD0(finalizePendingOutputLayers, void());
1364 };
1365
1366 struct Layer {
Layerandroid::compositionengine::__anon479079190111::OutputCollectVisibleLayersTest::Layer1367 Layer() {
1368 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1369 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1370 }
1371
1372 StrictMock<mock::OutputLayer> outputLayer;
1373 impl::OutputLayerCompositionState outputLayerState;
1374 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1375 };
1376
OutputCollectVisibleLayersTestandroid::compositionengine::__anon479079190111::OutputCollectVisibleLayersTest1377 OutputCollectVisibleLayersTest() {
1378 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
1379 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1380 .WillRepeatedly(Return(&mLayer1.outputLayer));
1381 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1382 .WillRepeatedly(Return(&mLayer2.outputLayer));
1383 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1384 .WillRepeatedly(Return(&mLayer3.outputLayer));
1385
1386 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1387 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1388 mRefreshArgs.layers.push_back(mLayer3.layerFE);
1389 }
1390
1391 StrictMock<OutputPartialMock> mOutput;
1392 CompositionRefreshArgs mRefreshArgs;
1393 LayerFESet mGeomSnapshots;
1394 Output::CoverageState mCoverageState{mGeomSnapshots};
1395 Layer mLayer1;
1396 Layer mLayer2;
1397 Layer mLayer3;
1398 };
1399
TEST_F(OutputCollectVisibleLayersTest,doesMinimalWorkIfNoLayers)1400 TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1401 mRefreshArgs.layers.clear();
1402 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1403
1404 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1405 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1406
1407 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1408 }
1409
TEST_F(OutputCollectVisibleLayersTest,processesCandidateLayersReversedAndSetsOutputLayerZ)1410 TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1411 // Enforce a call order sequence for this test.
1412 InSequence seq;
1413
1414 // Layer coverage is evaluated from front to back!
1415 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1416 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1417 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
1418
1419 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1420 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1421
1422 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1423 }
1424
1425 /*
1426 * Output::ensureOutputLayerIfVisible()
1427 */
1428
1429 struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1430 struct OutputPartialMock : public OutputPartialMockBase {
1431 // Sets up the helper functions called by the function under test to use
1432 // mock implementations.
1433 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1434 (const, override));
1435 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
1436 MOCK_METHOD2(ensureOutputLayer,
1437 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
1438 };
1439
OutputEnsureOutputLayerIfVisibleTestandroid::compositionengine::__anon479079190111::OutputEnsureOutputLayerIfVisibleTest1440 OutputEnsureOutputLayerIfVisibleTest() {
1441 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
1442 .WillRepeatedly(Return(true));
1443 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
1444 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1445 .WillRepeatedly(Return(&mLayer.outputLayer));
1446
1447 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1448 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
1449 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1450
1451 mLayer.layerFEState.isVisible = true;
1452 mLayer.layerFEState.isOpaque = true;
1453 mLayer.layerFEState.contentDirty = true;
1454 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1455 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1456 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
1457
1458 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1459 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
1460
1461 mGeomSnapshots.insert(mLayer.layerFE);
1462 }
1463
ensureOutputLayerIfVisibleandroid::compositionengine::__anon479079190111::OutputEnsureOutputLayerIfVisibleTest1464 void ensureOutputLayerIfVisible() {
1465 sp<LayerFE> layerFE(mLayer.layerFE);
1466 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
1467 }
1468
1469 static const Region kEmptyRegion;
1470 static const Region kFullBoundsNoRotation;
1471 static const Region kRightHalfBoundsNoRotation;
1472 static const Region kLowerHalfBoundsNoRotation;
1473 static const Region kFullBounds90Rotation;
1474 static const Region kTransparentRegionHint;
1475 static const Region kTransparentRegionHintTwo;
1476 static const Region kTransparentRegionHintTwo90Rotation;
1477 static const Region kTransparentRegionHintNegative;
1478 static const Region kTransparentRegionHintNegativeIntersectsBounds;
1479
1480 StrictMock<OutputPartialMock> mOutput;
1481 LayerFESet mGeomSnapshots;
1482 Output::CoverageState mCoverageState{mGeomSnapshots};
1483
1484 NonInjectedLayer mLayer;
1485 };
1486
1487 const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1488 const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1489 Region(Rect(0, 0, 100, 200));
1490 const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1491 Region(Rect(0, 100, 100, 200));
1492 const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1493 Region(Rect(50, 0, 100, 200));
1494 const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1495 Region(Rect(0, 0, 200, 100));
1496 const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
1497 Region(Rect(0, 0, 100, 100));
1498 const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
1499 Region(Rect(25, 20, 50, 75));
1500 const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
1501 Region(Rect(125, 25, 180, 50));
1502 const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1503 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1504 const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1505 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
1506
TEST_F(OutputEnsureOutputLayerIfVisibleTest,performsGeomLatchBeforeCheckingIfLayerIncluded)1507 TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1508 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1509 mGeomSnapshots.clear();
1510
1511 ensureOutputLayerIfVisible();
1512 }
1513
TEST_F(OutputEnsureOutputLayerIfVisibleTest,skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded)1514 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1515 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1516 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1517
1518 ensureOutputLayerIfVisible();
1519 }
1520
TEST_F(OutputEnsureOutputLayerIfVisibleTest,takesEarlyOutIfLayerHasNoCompositionState)1521 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1522 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1523
1524 ensureOutputLayerIfVisible();
1525 }
1526
TEST_F(OutputEnsureOutputLayerIfVisibleTest,takesEarlyOutIfLayerNotVisible)1527 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
1528 mLayer.layerFEState.isVisible = false;
1529
1530 ensureOutputLayerIfVisible();
1531 }
1532
TEST_F(OutputEnsureOutputLayerIfVisibleTest,takesEarlyOutIfLayerHasEmptyVisibleRegion)1533 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
1534 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
1535
1536 ensureOutputLayerIfVisible();
1537 }
1538
TEST_F(OutputEnsureOutputLayerIfVisibleTest,takesNotSoEarlyOutifDrawRegionEmpty)1539 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
1540 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
1541
1542 ensureOutputLayerIfVisible();
1543 }
1544
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer)1545 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1546 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
1547 mLayer.layerFEState.isOpaque = true;
1548 mLayer.layerFEState.contentDirty = true;
1549 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1550
1551 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1552 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1553 .WillOnce(Return(&mLayer.outputLayer));
1554
1555 ensureOutputLayerIfVisible();
1556
1557 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1559 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1560
1561 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1562 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1563 RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1565 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1566 }
1567
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer)1568 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1569 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
1570 mLayer.layerFEState.isOpaque = true;
1571 mLayer.layerFEState.contentDirty = true;
1572 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1573
1574 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1575 .WillOnce(Return(&mLayer.outputLayer));
1576
1577 ensureOutputLayerIfVisible();
1578
1579 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1581 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1582
1583 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1584 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1585 RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1587 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1588 }
1589
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer)1590 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1591 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
1592 mLayer.layerFEState.isOpaque = false;
1593 mLayer.layerFEState.contentDirty = true;
1594 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1595
1596 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1597 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1598 .WillOnce(Return(&mLayer.outputLayer));
1599
1600 ensureOutputLayerIfVisible();
1601
1602 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1603 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1604 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1605
1606 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1607 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1608 RegionEq(kRightHalfBoundsNoRotation));
1609 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1610 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1611 }
1612
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer)1613 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1614 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
1615 mLayer.layerFEState.isOpaque = false;
1616 mLayer.layerFEState.contentDirty = true;
1617 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1618
1619 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1620 .WillOnce(Return(&mLayer.outputLayer));
1621
1622 ensureOutputLayerIfVisible();
1623
1624 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1625 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1626 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1627
1628 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1629 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1630 RegionEq(kRightHalfBoundsNoRotation));
1631 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1633 }
1634
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer)1635 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1636 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
1637 mLayer.layerFEState.isOpaque = true;
1638 mLayer.layerFEState.contentDirty = false;
1639 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1640
1641 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1642 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1643 .WillOnce(Return(&mLayer.outputLayer));
1644
1645 ensureOutputLayerIfVisible();
1646
1647 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1648 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1649 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1650
1651 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1652 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1653 RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1655 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1656 }
1657
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer)1658 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1659 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
1660 mLayer.layerFEState.isOpaque = true;
1661 mLayer.layerFEState.contentDirty = false;
1662 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1663
1664 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1665 .WillOnce(Return(&mLayer.outputLayer));
1666
1667 ensureOutputLayerIfVisible();
1668
1669 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1670 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1671 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1672
1673 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1674 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1675 RegionEq(kFullBoundsNoRotation));
1676 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1677 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1678 }
1679
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer)1680 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1681 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
1682 mLayer.layerFEState.isOpaque = true;
1683 mLayer.layerFEState.contentDirty = true;
1684 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1685 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1686 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1687 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
1688
1689 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1690 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1691 .WillOnce(Return(&mLayer.outputLayer));
1692
1693 ensureOutputLayerIfVisible();
1694
1695 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1696 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1697 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1698
1699 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1700 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1701 RegionEq(kFullBoundsNoRotation));
1702 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1703 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1704 }
1705
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer)1706 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1707 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
1708 mLayer.layerFEState.isOpaque = true;
1709 mLayer.layerFEState.contentDirty = true;
1710 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1711 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1712 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1713 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
1714
1715 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1716 .WillOnce(Return(&mLayer.outputLayer));
1717
1718 ensureOutputLayerIfVisible();
1719
1720 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1721 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1722 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1723
1724 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1725 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1726 RegionEq(kFullBoundsNoRotation));
1727 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1728 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1729 }
1730
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput)1731 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1732 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
1733 mLayer.layerFEState.isOpaque = true;
1734 mLayer.layerFEState.contentDirty = true;
1735 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1736
1737 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1738 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1739
1740 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1741 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1742 .WillOnce(Return(&mLayer.outputLayer));
1743
1744 ensureOutputLayerIfVisible();
1745
1746 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1747 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1748 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1749
1750 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1751 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1752 RegionEq(kFullBoundsNoRotation));
1753 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1754 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
1755 }
1756
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput)1757 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1758 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
1759 mLayer.layerFEState.isOpaque = true;
1760 mLayer.layerFEState.contentDirty = true;
1761 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1762
1763 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1764 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1765
1766 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1767 .WillOnce(Return(&mLayer.outputLayer));
1768
1769 ensureOutputLayerIfVisible();
1770
1771 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1772 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1773 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1774
1775 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1776 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1777 RegionEq(kFullBoundsNoRotation));
1778 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1779 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
1780 }
1781
TEST_F(OutputEnsureOutputLayerIfVisibleTest,handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer)1782 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1783 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1784 ui::Transform arbitraryTransform;
1785 arbitraryTransform.set(1, 1, -1, 1);
1786 arbitraryTransform.set(0, 100);
1787
1788 mLayer.layerFEState.isOpaque = true;
1789 mLayer.layerFEState.contentDirty = true;
1790 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1791 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
1792
1793 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1794 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1795 .WillOnce(Return(&mLayer.outputLayer));
1796
1797 ensureOutputLayerIfVisible();
1798
1799 const Region kRegion = Region(Rect(0, 0, 300, 300));
1800 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1801
1802 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1803 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1804 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1805
1806 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1807 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1808 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1809 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
1810 }
1811
TEST_F(OutputEnsureOutputLayerIfVisibleTest,coverageAccumulatesTest)1812 TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
1813 mLayer.layerFEState.isOpaque = false;
1814 mLayer.layerFEState.contentDirty = true;
1815 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1816
1817 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1818 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1819 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1820
1821 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1822 .WillOnce(Return(&mLayer.outputLayer));
1823
1824 ensureOutputLayerIfVisible();
1825
1826 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1827 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1828 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1829 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1830 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1831 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1832
1833 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1834 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1835 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1836
1837 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1838 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1839 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
1840 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1841 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1842 RegionEq(kExpectedLayerVisibleRegion));
1843 }
1844
TEST_F(OutputEnsureOutputLayerIfVisibleTest,coverageAccumulatesWithShadowsTest)1845 TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1846 ui::Transform translate;
1847 translate.set(50, 50);
1848 mLayer.layerFEState.geomLayerTransform = translate;
1849 mLayer.layerFEState.shadowRadius = 10.0f;
1850
1851 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1852 // half of the layer including the casting shadow is covered and opaque
1853 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1854 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1855
1856 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1857 .WillOnce(Return(&mLayer.outputLayer));
1858
1859 ensureOutputLayerIfVisible();
1860
1861 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1862 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1863 // add starting opaque region to the opaque half of the casting layer bounds
1864 const Region kExpectedAboveOpaqueRegion =
1865 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1866 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1867 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1868 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1869 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1870 const Region kExpectedLayerShadowRegion =
1871 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1872
1873 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1874 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1875 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1876
1877 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1878 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1879 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
1880 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1881 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1882 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
1883 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
1884 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1885 }
1886
TEST_F(OutputEnsureOutputLayerIfVisibleTest,shadowRegionOnlyTest)1887 TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1888 ui::Transform translate;
1889 translate.set(50, 50);
1890 mLayer.layerFEState.geomLayerTransform = translate;
1891 mLayer.layerFEState.shadowRadius = 10.0f;
1892
1893 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1894 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1895 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1896 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1897
1898 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1899 .WillOnce(Return(&mLayer.outputLayer));
1900
1901 ensureOutputLayerIfVisible();
1902
1903 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1904 const Region kExpectedLayerShadowRegion =
1905 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1906
1907 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1908 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
1909 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1910 }
1911
TEST_F(OutputEnsureOutputLayerIfVisibleTest,takesNotSoEarlyOutifLayerWithShadowIsCovered)1912 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
1913 ui::Transform translate;
1914 translate.set(50, 50);
1915 mLayer.layerFEState.geomLayerTransform = translate;
1916 mLayer.layerFEState.shadowRadius = 10.0f;
1917
1918 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1919 // Casting layer and its shadows are covered by an opaque region
1920 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1921 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1922
1923 ensureOutputLayerIfVisible();
1924 }
1925
TEST_F(OutputEnsureOutputLayerIfVisibleTest,displayDecorSetsBlockingFromTransparentRegion)1926 TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1927 mLayer.layerFEState.isOpaque = false;
1928 mLayer.layerFEState.contentDirty = true;
1929 mLayer.layerFEState.compositionType =
1930 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1931
1932 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1933 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1934 .WillOnce(Return(&mLayer.outputLayer));
1935 ensureOutputLayerIfVisible();
1936
1937 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1938 RegionEq(kTransparentRegionHint));
1939 }
1940
TEST_F(OutputEnsureOutputLayerIfVisibleTest,normalLayersDoNotSetBlockingRegion)1941 TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1942 mLayer.layerFEState.isOpaque = false;
1943 mLayer.layerFEState.contentDirty = true;
1944
1945 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1946 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1947 .WillOnce(Return(&mLayer.outputLayer));
1948 ensureOutputLayerIfVisible();
1949
1950 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1951 }
1952
TEST_F(OutputEnsureOutputLayerIfVisibleTest,blockingRegionIsInOutputSpace)1953 TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1954 mLayer.layerFEState.isOpaque = false;
1955 mLayer.layerFEState.contentDirty = true;
1956 mLayer.layerFEState.compositionType =
1957 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1958 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
1959
1960 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1961 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1962
1963 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1964 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1965 .WillOnce(Return(&mLayer.outputLayer));
1966 ensureOutputLayerIfVisible();
1967
1968 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1969 RegionEq(kTransparentRegionHintTwo90Rotation));
1970 }
1971
TEST_F(OutputEnsureOutputLayerIfVisibleTest,transparentRegionExcludesOutputLayer)1972 TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1973 mLayer.layerFEState.isOpaque = false;
1974 mLayer.layerFEState.contentDirty = true;
1975 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1976 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1977
1978 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1979 }
1980
TEST_F(OutputEnsureOutputLayerIfVisibleTest,transparentRegionIgnoredWhenOutsideBounds)1981 TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1982 mLayer.layerFEState.isOpaque = false;
1983 mLayer.layerFEState.contentDirty = true;
1984 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1985 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1986
1987 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1988 }
1989
TEST_F(OutputEnsureOutputLayerIfVisibleTest,transparentRegionClipsWhenOutsideBounds)1990 TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1991 mLayer.layerFEState.isOpaque = false;
1992 mLayer.layerFEState.contentDirty = true;
1993 mLayer.layerFEState.compositionType =
1994 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1995 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1996
1997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1998 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1999 .WillOnce(Return(&mLayer.outputLayer));
2000 ensureOutputLayerIfVisible();
2001
2002 // Check that the blocking region clips an out-of-bounds transparent region.
2003 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2004 RegionEq(kTransparentRegionHint));
2005 }
2006
2007 /*
2008 * Output::present()
2009 */
2010
2011 struct OutputPresentTest : public testing::Test {
2012 struct OutputPartialMock : public OutputPartialMockBase {
2013 // Sets up the helper functions called by the function under test to use
2014 // mock implementations.
2015 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
2016 MOCK_METHOD1(updateCompositionState,
2017 void(const compositionengine::CompositionRefreshArgs&));
2018 MOCK_METHOD0(planComposition, void());
2019 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
2020 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2021 MOCK_METHOD0(beginFrame, void());
2022 MOCK_METHOD0(prepareFrame, void());
2023 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
2024 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
2025 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
2026 MOCK_METHOD0(postFramebuffer, void());
2027 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
2028 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
2029 };
2030
2031 StrictMock<OutputPartialMock> mOutput;
2032 };
2033
TEST_F(OutputPresentTest,justInvokesChildFunctionsInSequence)2034 TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2035 CompositionRefreshArgs args;
2036
2037 InSequence seq;
2038 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2039 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2040 EXPECT_CALL(mOutput, planComposition());
2041 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2042 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2043 EXPECT_CALL(mOutput, beginFrame());
2044 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
2045 EXPECT_CALL(mOutput, prepareFrame());
2046 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2047 EXPECT_CALL(mOutput, finishFrame(_));
2048 EXPECT_CALL(mOutput, postFramebuffer());
2049 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2050
2051 mOutput.present(args);
2052 }
2053
TEST_F(OutputPresentTest,predictingCompositionStrategyInvokesPrepareFrameAsync)2054 TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2055 CompositionRefreshArgs args;
2056
2057 InSequence seq;
2058 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2059 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2060 EXPECT_CALL(mOutput, planComposition());
2061 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2062 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2063 EXPECT_CALL(mOutput, beginFrame());
2064 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2065 EXPECT_CALL(mOutput, prepareFrameAsync());
2066 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2067 EXPECT_CALL(mOutput, finishFrame(_));
2068 EXPECT_CALL(mOutput, postFramebuffer());
2069 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2070
2071 mOutput.present(args);
2072 }
2073
2074 /*
2075 * Output::updateColorProfile()
2076 */
2077
2078 struct OutputUpdateColorProfileTest : public testing::Test {
2079 using TestType = OutputUpdateColorProfileTest;
2080
2081 struct OutputPartialMock : public OutputPartialMockBase {
2082 // Sets up the helper functions called by the function under test to use
2083 // mock implementations.
2084 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2085 };
2086
2087 struct Layer {
Layerandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest::Layer2088 Layer() {
2089 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2090 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
2091 }
2092
2093 StrictMock<mock::OutputLayer> mOutputLayer;
2094 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
2095 LayerFECompositionState mLayerFEState;
2096 };
2097
OutputUpdateColorProfileTestandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest2098 OutputUpdateColorProfileTest() {
2099 mOutput.setDisplayColorProfileForTest(
2100 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2101 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2102 mOutput.editState().isEnabled = true;
2103
2104 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2105 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2106 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2107 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2108 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2109 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2110 }
2111
2112 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
executeandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest::ExecuteState2113 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2114 };
2115
2116 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2117 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2118 StrictMock<OutputPartialMock> mOutput;
2119
2120 Layer mLayer1;
2121 Layer mLayer2;
2122 Layer mLayer3;
2123
2124 CompositionRefreshArgs mRefreshArgs;
2125 };
2126
2127 // TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2128 // to make it easier to write unit tests.
2129
TEST_F(OutputUpdateColorProfileTest,setsAColorProfileWhenUnmanaged)2130 TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2131 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2132 // a simple default color profile without looking at anything else.
2133
2134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2135 EXPECT_CALL(mOutput,
2136 setColorProfile(ColorProfileEq(
2137 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2138 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2139
2140 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2141 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2142
2143 mOutput.updateColorProfile(mRefreshArgs);
2144 }
2145
2146 struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2147 : public OutputUpdateColorProfileTest {
OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfileandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile2148 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
2149 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
2150 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2151 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2152 }
2153
2154 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2155 : public CallOrderStateMachineHelper<
2156 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
expectBestColorModeCallResultUsedToSetColorProfileandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile::ExpectBestColorModeCallResultUsedToSetColorProfileState2157 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2158 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2159 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2160 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2161 _))
2162 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2163 SetArgPointee<4>(renderIntent)));
2164 EXPECT_CALL(getInstance()->mOutput,
2165 setColorProfile(
2166 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2167 ui::Dataspace::UNKNOWN})));
2168 return nextState<ExecuteState>();
2169 }
2170 };
2171
2172 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile2173 [[nodiscard]] auto verify() {
2174 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2175 }
2176 };
2177
TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,Native_Unknown_Colorimetric_Set)2178 TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2179 Native_Unknown_Colorimetric_Set) {
2180 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2181 ui::Dataspace::UNKNOWN,
2182 ui::RenderIntent::COLORIMETRIC)
2183 .execute();
2184 }
2185
TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,DisplayP3_DisplayP3_Enhance_Set)2186 TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2187 DisplayP3_DisplayP3_Enhance_Set) {
2188 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2189 ui::Dataspace::DISPLAY_P3,
2190 ui::RenderIntent::ENHANCE)
2191 .execute();
2192 }
2193
2194 struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2195 : public OutputUpdateColorProfileTest {
OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfileandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile2196 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
2197 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
2198 EXPECT_CALL(*mDisplayColorProfile,
2199 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2200 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2201 SetArgPointee<3>(ui::ColorMode::NATIVE),
2202 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2203 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2204 }
2205
2206 struct IfColorSpaceAgnosticDataspaceSetToState
2207 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
ifColorSpaceAgnosticDataspaceSetToandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile::IfColorSpaceAgnosticDataspaceSetToState2208 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2209 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2210 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2211 }
2212 };
2213
2214 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2215 : public CallOrderStateMachineHelper<
2216 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile::ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState2217 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2218 ui::Dataspace dataspace) {
2219 EXPECT_CALL(getInstance()->mOutput,
2220 setColorProfile(ColorProfileEq(
2221 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2222 ui::RenderIntent::COLORIMETRIC, dataspace})));
2223 return nextState<ExecuteState>();
2224 }
2225 };
2226
2227 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile2228 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2229 };
2230
TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile,DisplayP3)2231 TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2232 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2233 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2234 .execute();
2235 }
2236
TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile,V0_SRGB)2237 TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2238 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2239 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2240 .execute();
2241 }
2242
2243 struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2244 : public OutputUpdateColorProfileTest {
2245 // Internally the implementation looks through the dataspaces of all the
2246 // visible layers. The topmost one that also has an actual dataspace
2247 // preference set is used to drive subsequent choices.
2248
OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreferenceandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference2249 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2250 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2251 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2252
2253 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2254 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2255 }
2256
2257 struct IfTopLayerDataspaceState
2258 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
ifTopLayerIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::IfTopLayerDataspaceState2259 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2260 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2261 return nextState<AndIfMiddleLayerDataspaceState>();
2262 }
ifTopLayerHasNoPreferenceandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::IfTopLayerDataspaceState2263 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2264 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2265 }
2266 };
2267
2268 struct AndIfMiddleLayerDataspaceState
2269 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
andIfMiddleLayerIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::AndIfMiddleLayerDataspaceState2270 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2271 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2272 return nextState<AndIfBottomLayerDataspaceState>();
2273 }
andIfMiddleLayerHasNoPreferenceandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::AndIfMiddleLayerDataspaceState2274 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2275 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2276 }
2277 };
2278
2279 struct AndIfBottomLayerDataspaceState
2280 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
andIfBottomLayerIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::AndIfBottomLayerDataspaceState2281 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2282 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2283 return nextState<ThenExpectBestColorModeCallUsesState>();
2284 }
andIfBottomLayerHasNoPreferenceandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::AndIfBottomLayerDataspaceState2285 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2286 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2287 }
2288 };
2289
2290 struct ThenExpectBestColorModeCallUsesState
2291 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
thenExpectBestColorModeCallUsesandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference::ThenExpectBestColorModeCallUsesState2292 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2293 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2294 getBestColorMode(dataspace, _, _, _, _));
2295 return nextState<ExecuteState>();
2296 }
2297 };
2298
2299 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference2300 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2301 };
2302
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,noStrongLayerPrefenceUses_V0_SRGB)2303 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2304 noStrongLayerPrefenceUses_V0_SRGB) {
2305 // If none of the layers indicate a preference, then V0_SRGB is the
2306 // preferred choice (subject to additional checks).
2307 verify().ifTopLayerHasNoPreference()
2308 .andIfMiddleLayerHasNoPreference()
2309 .andIfBottomLayerHasNoPreference()
2310 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2311 .execute();
2312 }
2313
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen)2314 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2315 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2316 // If only the topmost layer has a preference, then that is what is chosen.
2317 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2318 .andIfMiddleLayerHasNoPreference()
2319 .andIfBottomLayerHasNoPreference()
2320 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2321 .execute();
2322 }
2323
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen)2324 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2325 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2326 // If only the middle layer has a preference, that that is what is chosen.
2327 verify().ifTopLayerHasNoPreference()
2328 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2329 .andIfBottomLayerHasNoPreference()
2330 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2331 .execute();
2332 }
2333
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,ifBottomUses_DisplayP3_Then_DisplayP3_Chosen)2334 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2335 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2336 // If only the middle layer has a preference, that that is what is chosen.
2337 verify().ifTopLayerHasNoPreference()
2338 .andIfMiddleLayerHasNoPreference()
2339 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2340 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2341 .execute();
2342 }
2343
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen)2344 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2345 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2346 // If multiple layers have a preference, the topmost value is what is used.
2347 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2348 .andIfMiddleLayerHasNoPreference()
2349 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2350 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2351 .execute();
2352 }
2353
TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen)2354 TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2355 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2356 // If multiple layers have a preference, the topmost value is what is used.
2357 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2358 .andIfMiddleLayerHasNoPreference()
2359 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2360 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2361 .execute();
2362 }
2363
2364 struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2365 : public OutputUpdateColorProfileTest {
2366 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2367 // values, it overrides the layer dataspace choice.
2368
OutputUpdateColorProfileTest_ForceOutputColorOverridesandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ForceOutputColorOverrides2369 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2370 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2371 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2372
2373 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2374
2375 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
2376 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2377 }
2378
2379 struct IfForceOutputColorModeState
2380 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
ifForceOutputColorModeandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ForceOutputColorOverrides::IfForceOutputColorModeState2381 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2382 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2383 return nextState<ThenExpectBestColorModeCallUsesState>();
2384 }
ifNoOverrideandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ForceOutputColorOverrides::IfForceOutputColorModeState2385 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2386 };
2387
2388 struct ThenExpectBestColorModeCallUsesState
2389 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
thenExpectBestColorModeCallUsesandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ForceOutputColorOverrides::ThenExpectBestColorModeCallUsesState2390 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2391 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2392 getBestColorMode(dataspace, _, _, _, _));
2393 return nextState<ExecuteState>();
2394 }
2395 };
2396
2397 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_ForceOutputColorOverrides2398 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2399 };
2400
TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides,NoOverride_DoesNotOverride)2401 TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2402 // By default the layer state is used to set the preferred dataspace
2403 verify().ifNoOverride()
2404 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2405 .execute();
2406 }
2407
TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides,SRGB_Override_USES_V0_SRGB)2408 TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2409 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2410 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2411 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2412 .execute();
2413 }
2414
TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides,DisplayP3_Override_Uses_DisplayP3)2415 TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2416 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2417 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2418 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2419 .execute();
2420 }
2421
2422 // HDR output requires all layers to be compatible with the chosen HDR
2423 // dataspace, along with there being proper support.
2424 struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
OutputUpdateColorProfileTest_Hdrandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr2425 OutputUpdateColorProfileTest_Hdr() {
2426 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2427 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2428 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
2429 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2430 }
2431
2432 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2433 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2434 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2435 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2436
2437 struct IfTopLayerDataspaceState
2438 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
ifTopLayerIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::IfTopLayerDataspaceState2439 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2440 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2441 return nextState<AndTopLayerCompositionTypeState>();
2442 }
ifTopLayerIsNotHdrandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::IfTopLayerDataspaceState2443 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2444 };
2445
2446 struct AndTopLayerCompositionTypeState
2447 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
andTopLayerIsREComposedandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::AndTopLayerCompositionTypeState2448 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2449 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2450 return nextState<AndIfBottomLayerDataspaceState>();
2451 }
2452 };
2453
2454 struct AndIfBottomLayerDataspaceState
2455 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
andIfBottomLayerIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::AndIfBottomLayerDataspaceState2456 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2457 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2458 return nextState<AndBottomLayerCompositionTypeState>();
2459 }
andIfBottomLayerIsNotHdrandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::AndIfBottomLayerDataspaceState2460 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2461 return andIfBottomLayerIs(kNonHdrDataspace);
2462 }
2463 };
2464
2465 struct AndBottomLayerCompositionTypeState
2466 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
andBottomLayerIsREComposedandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::AndBottomLayerCompositionTypeState2467 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2468 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2469 return nextState<AndIfHasLegacySupportState>();
2470 }
2471 };
2472
2473 struct AndIfHasLegacySupportState
2474 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
andIfLegacySupportForandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::AndIfHasLegacySupportState2475 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2476 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2477 .WillOnce(Return(legacySupport));
2478 return nextState<ThenExpectBestColorModeCallUsesState>();
2479 }
2480 };
2481
2482 struct ThenExpectBestColorModeCallUsesState
2483 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
thenExpectBestColorModeCallUsesandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr::ThenExpectBestColorModeCallUsesState2484 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2485 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2486 getBestColorMode(dataspace, _, _, _, _));
2487 return nextState<ExecuteState>();
2488 }
2489 };
2490
2491 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfileTest_Hdr2492 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2493 };
2494
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_PQ_HW_Uses_PQ)2495 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2496 // If all layers use BT2020_PQ, and there are no other special conditions,
2497 // BT2020_PQ is used.
2498 verify().ifTopLayerIs(BT2020_PQ)
2499 .andTopLayerIsREComposed(false)
2500 .andIfBottomLayerIs(BT2020_PQ)
2501 .andBottomLayerIsREComposed(false)
2502 .andIfLegacySupportFor(BT2020_PQ, false)
2503 .thenExpectBestColorModeCallUses(BT2020_PQ)
2504 .execute();
2505 }
2506
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3)2507 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2508 // BT2020_PQ is not used if there is only legacy support for it.
2509 verify().ifTopLayerIs(BT2020_PQ)
2510 .andTopLayerIsREComposed(false)
2511 .andIfBottomLayerIs(BT2020_PQ)
2512 .andBottomLayerIsREComposed(false)
2513 .andIfLegacySupportFor(BT2020_PQ, true)
2514 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2515 .execute();
2516 }
2517
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_PQ_RE_Uses_PQ)2518 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2519 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2520 verify().ifTopLayerIs(BT2020_PQ)
2521 .andTopLayerIsREComposed(false)
2522 .andIfBottomLayerIs(BT2020_PQ)
2523 .andBottomLayerIsREComposed(true)
2524 .andIfLegacySupportFor(BT2020_PQ, false)
2525 .thenExpectBestColorModeCallUses(BT2020_PQ)
2526 .execute();
2527 }
2528
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_RE_On_PQ_HW_Uses_DisplayP3)2529 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2530 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2531 verify().ifTopLayerIs(BT2020_PQ)
2532 .andTopLayerIsREComposed(true)
2533 .andIfBottomLayerIs(BT2020_PQ)
2534 .andBottomLayerIsREComposed(false)
2535 .andIfLegacySupportFor(BT2020_PQ, false)
2536 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2537 .execute();
2538 }
2539
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_HLG_HW_Uses_PQ)2540 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2541 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2542 // are no other special conditions.
2543 verify().ifTopLayerIs(BT2020_PQ)
2544 .andTopLayerIsREComposed(false)
2545 .andIfBottomLayerIs(BT2020_HLG)
2546 .andBottomLayerIsREComposed(false)
2547 .andIfLegacySupportFor(BT2020_PQ, false)
2548 .thenExpectBestColorModeCallUses(BT2020_PQ)
2549 .execute();
2550 }
2551
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3)2552 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2553 // BT2020_PQ is not used if there is only legacy support for it.
2554 verify().ifTopLayerIs(BT2020_PQ)
2555 .andTopLayerIsREComposed(false)
2556 .andIfBottomLayerIs(BT2020_HLG)
2557 .andBottomLayerIsREComposed(false)
2558 .andIfLegacySupportFor(BT2020_PQ, true)
2559 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2560 .execute();
2561 }
2562
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_HLG_RE_Uses_PQ)2563 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2564 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2565 verify().ifTopLayerIs(BT2020_PQ)
2566 .andTopLayerIsREComposed(false)
2567 .andIfBottomLayerIs(BT2020_HLG)
2568 .andBottomLayerIsREComposed(true)
2569 .andIfLegacySupportFor(BT2020_PQ, false)
2570 .thenExpectBestColorModeCallUses(BT2020_PQ)
2571 .execute();
2572 }
2573
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_RE_On_HLG_HW_Uses_DisplayP3)2574 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2575 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2576 verify().ifTopLayerIs(BT2020_PQ)
2577 .andTopLayerIsREComposed(true)
2578 .andIfBottomLayerIs(BT2020_HLG)
2579 .andBottomLayerIsREComposed(false)
2580 .andIfLegacySupportFor(BT2020_PQ, false)
2581 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2582 .execute();
2583 }
2584
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_PQ_HW_Uses_PQ)2585 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2586 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2587 // used if there are no other special conditions.
2588 verify().ifTopLayerIs(BT2020_HLG)
2589 .andTopLayerIsREComposed(false)
2590 .andIfBottomLayerIs(BT2020_PQ)
2591 .andBottomLayerIsREComposed(false)
2592 .andIfLegacySupportFor(BT2020_PQ, false)
2593 .thenExpectBestColorModeCallUses(BT2020_PQ)
2594 .execute();
2595 }
2596
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3)2597 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2598 // BT2020_PQ is not used if there is only legacy support for it.
2599 verify().ifTopLayerIs(BT2020_HLG)
2600 .andTopLayerIsREComposed(false)
2601 .andIfBottomLayerIs(BT2020_PQ)
2602 .andBottomLayerIsREComposed(false)
2603 .andIfLegacySupportFor(BT2020_PQ, true)
2604 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2605 .execute();
2606 }
2607
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_PQ_RE_Uses_DisplayP3)2608 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2609 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2610 verify().ifTopLayerIs(BT2020_HLG)
2611 .andTopLayerIsREComposed(false)
2612 .andIfBottomLayerIs(BT2020_PQ)
2613 .andBottomLayerIsREComposed(true)
2614 .andIfLegacySupportFor(BT2020_PQ, false)
2615 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2616 .execute();
2617 }
2618
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_RE_On_PQ_HW_Uses_PQ)2619 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2620 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2621 verify().ifTopLayerIs(BT2020_HLG)
2622 .andTopLayerIsREComposed(true)
2623 .andIfBottomLayerIs(BT2020_PQ)
2624 .andBottomLayerIsREComposed(false)
2625 .andIfLegacySupportFor(BT2020_PQ, false)
2626 .thenExpectBestColorModeCallUses(BT2020_PQ)
2627 .execute();
2628 }
2629
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_HLG_HW_Uses_HLG)2630 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2631 // If all layers use HLG then HLG is used if there are no other special
2632 // conditions.
2633 verify().ifTopLayerIs(BT2020_HLG)
2634 .andTopLayerIsREComposed(false)
2635 .andIfBottomLayerIs(BT2020_HLG)
2636 .andBottomLayerIsREComposed(false)
2637 .andIfLegacySupportFor(BT2020_HLG, false)
2638 .thenExpectBestColorModeCallUses(BT2020_HLG)
2639 .execute();
2640 }
2641
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3)2642 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2643 // BT2020_HLG is not used if there is legacy support for it.
2644 verify().ifTopLayerIs(BT2020_HLG)
2645 .andTopLayerIsREComposed(false)
2646 .andIfBottomLayerIs(BT2020_HLG)
2647 .andBottomLayerIsREComposed(false)
2648 .andIfLegacySupportFor(BT2020_HLG, true)
2649 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2650 .execute();
2651 }
2652
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_HLG_RE_Uses_HLG)2653 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2654 // BT2020_HLG is used even if the bottom layer is client composed.
2655 verify().ifTopLayerIs(BT2020_HLG)
2656 .andTopLayerIsREComposed(false)
2657 .andIfBottomLayerIs(BT2020_HLG)
2658 .andBottomLayerIsREComposed(true)
2659 .andIfLegacySupportFor(BT2020_HLG, false)
2660 .thenExpectBestColorModeCallUses(BT2020_HLG)
2661 .execute();
2662 }
2663
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_RE_On_HLG_HW_Uses_HLG)2664 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2665 // BT2020_HLG is used even if the top layer is client composed.
2666 verify().ifTopLayerIs(BT2020_HLG)
2667 .andTopLayerIsREComposed(true)
2668 .andIfBottomLayerIs(BT2020_HLG)
2669 .andBottomLayerIsREComposed(false)
2670 .andIfLegacySupportFor(BT2020_HLG, false)
2671 .thenExpectBestColorModeCallUses(BT2020_HLG)
2672 .execute();
2673 }
2674
TEST_F(OutputUpdateColorProfileTest_Hdr,PQ_HW_On_NonHdr_HW_Uses_PQ)2675 TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2676 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2677 verify().ifTopLayerIs(BT2020_PQ)
2678 .andTopLayerIsREComposed(false)
2679 .andIfBottomLayerIsNotHdr()
2680 .andBottomLayerIsREComposed(false)
2681 .andIfLegacySupportFor(BT2020_PQ, false)
2682 .thenExpectBestColorModeCallUses(BT2020_PQ)
2683 .execute();
2684 }
2685
TEST_F(OutputUpdateColorProfileTest_Hdr,HLG_HW_On_NonHdr_RE_Uses_HLG)2686 TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2687 // If all layers use HLG then HLG is used if there are no other special
2688 // conditions.
2689 verify().ifTopLayerIs(BT2020_HLG)
2690 .andTopLayerIsREComposed(false)
2691 .andIfBottomLayerIsNotHdr()
2692 .andBottomLayerIsREComposed(true)
2693 .andIfLegacySupportFor(BT2020_HLG, false)
2694 .thenExpectBestColorModeCallUses(BT2020_HLG)
2695 .execute();
2696 }
2697
2698 struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2699 : public OutputUpdateColorProfileTest {
2700 // The various values for CompositionRefreshArgs::outputColorSetting affect
2701 // the chosen renderIntent, along with whether the preferred dataspace is an
2702 // HDR dataspace or not.
2703
OutputUpdateColorProfile_AffectsChosenRenderIntentTestandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest2704 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2705 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2706 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2707 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
2708 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
2709 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2710 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2711 .WillRepeatedly(Return(false));
2712 }
2713
2714 // The tests here involve enough state and GMock setup that using a mini-DSL
2715 // makes the tests much more readable, and allows the test to focus more on
2716 // the intent than on some of the details.
2717
2718 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2719 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2720
2721 struct IfDataspaceChosenState
2722 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
ifDataspaceChosenIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest::IfDataspaceChosenState2723 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2724 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2725 return nextState<AndOutputColorSettingState>();
2726 }
ifDataspaceChosenIsNonHdrandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest::IfDataspaceChosenState2727 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2728 return ifDataspaceChosenIs(kNonHdrDataspace);
2729 }
ifDataspaceChosenIsHdrandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest::IfDataspaceChosenState2730 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2731 };
2732
2733 struct AndOutputColorSettingState
2734 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
andOutputColorSettingIsandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest::AndOutputColorSettingState2735 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2736 getInstance()->mRefreshArgs.outputColorSetting = setting;
2737 return nextState<ThenExpectBestColorModeCallUsesState>();
2738 }
2739 };
2740
2741 struct ThenExpectBestColorModeCallUsesState
2742 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
thenExpectBestColorModeCallUsesandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest::ThenExpectBestColorModeCallUsesState2743 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2744 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2745 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2746 _, _));
2747 return nextState<ExecuteState>();
2748 }
2749 };
2750
2751 // Tests call one of these two helper member functions to start using the
2752 // mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputUpdateColorProfile_AffectsChosenRenderIntentTest2753 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2754 };
2755
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Managed_NonHdr_Prefers_Colorimetric)2756 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2757 Managed_NonHdr_Prefers_Colorimetric) {
2758 verify().ifDataspaceChosenIsNonHdr()
2759 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2760 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2761 .execute();
2762 }
2763
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Managed_Hdr_Prefers_ToneMapColorimetric)2764 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2765 Managed_Hdr_Prefers_ToneMapColorimetric) {
2766 verify().ifDataspaceChosenIsHdr()
2767 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2768 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2769 .execute();
2770 }
2771
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Enhanced_NonHdr_Prefers_Enhance)2772 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2773 verify().ifDataspaceChosenIsNonHdr()
2774 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2775 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2776 .execute();
2777 }
2778
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Enhanced_Hdr_Prefers_ToneMapEnhance)2779 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2780 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2781 verify().ifDataspaceChosenIsHdr()
2782 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2783 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2784 .execute();
2785 }
2786
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Vendor_NonHdr_Prefers_Vendor)2787 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2788 verify().ifDataspaceChosenIsNonHdr()
2789 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2790 .thenExpectBestColorModeCallUses(
2791 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2792 .execute();
2793 }
2794
TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,Vendor_Hdr_Prefers_Vendor)2795 TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2796 verify().ifDataspaceChosenIsHdr()
2797 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2798 .thenExpectBestColorModeCallUses(
2799 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2800 .execute();
2801 }
2802
2803 /*
2804 * Output::beginFrame()
2805 */
2806
2807 struct OutputBeginFrameTest : public ::testing::Test {
2808 using TestType = OutputBeginFrameTest;
2809
2810 struct OutputPartialMock : public OutputPartialMockBase {
2811 // Sets up the helper functions called by the function under test to use
2812 // mock implementations.
2813 MOCK_METHOD(Region, getDirtyRegion, (), (const));
2814 };
2815
OutputBeginFrameTestandroid::compositionengine::__anon479079190111::OutputBeginFrameTest2816 OutputBeginFrameTest() {
2817 mOutput.setDisplayColorProfileForTest(
2818 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2819 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2820 }
2821
2822 struct IfGetDirtyRegionExpectationState
2823 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
ifGetDirtyRegionReturnsandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::IfGetDirtyRegionExpectationState2824 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2825 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
2826 return nextState<AndIfGetOutputLayerCountExpectationState>();
2827 }
2828 };
2829
2830 struct AndIfGetOutputLayerCountExpectationState
2831 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
andIfGetOutputLayerCountReturnsandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::AndIfGetOutputLayerCountExpectationState2832 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2833 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2834 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2835 }
2836 };
2837
2838 struct AndIfLastCompositionHadVisibleLayersState
2839 : public CallOrderStateMachineHelper<TestType,
2840 AndIfLastCompositionHadVisibleLayersState> {
andIfLastCompositionHadVisibleLayersIsandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::AndIfLastCompositionHadVisibleLayersState2841 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2842 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2843 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2844 }
2845 };
2846
2847 struct ThenExpectRenderSurfaceBeginFrameCallState
2848 : public CallOrderStateMachineHelper<TestType,
2849 ThenExpectRenderSurfaceBeginFrameCallState> {
thenExpectRenderSurfaceBeginFrameCallandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::ThenExpectRenderSurfaceBeginFrameCallState2850 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2851 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2852 return nextState<ExecuteState>();
2853 }
2854 };
2855
2856 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
executeandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::ExecuteState2857 [[nodiscard]] auto execute() {
2858 getInstance()->mOutput.beginFrame();
2859 return nextState<CheckPostconditionHadVisibleLayersState>();
2860 }
2861 };
2862
2863 struct CheckPostconditionHadVisibleLayersState
2864 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
checkPostconditionHadVisibleLayersandroid::compositionengine::__anon479079190111::OutputBeginFrameTest::CheckPostconditionHadVisibleLayersState2865 void checkPostconditionHadVisibleLayers(bool expected) {
2866 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2867 }
2868 };
2869
2870 // Tests call one of these two helper member functions to start using the
2871 // mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputBeginFrameTest2872 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2873
2874 static const Region kEmptyRegion;
2875 static const Region kNotEmptyRegion;
2876
2877 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2878 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2879 StrictMock<OutputPartialMock> mOutput;
2880 };
2881
2882 const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2883 const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2884
TEST_F(OutputBeginFrameTest,hasDirtyHasLayersHadLayersLastFrame)2885 TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2886 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2887 .andIfGetOutputLayerCountReturns(1u)
2888 .andIfLastCompositionHadVisibleLayersIs(true)
2889 .thenExpectRenderSurfaceBeginFrameCall(true)
2890 .execute()
2891 .checkPostconditionHadVisibleLayers(true);
2892 }
2893
TEST_F(OutputBeginFrameTest,hasDirtyNotHasLayersHadLayersLastFrame)2894 TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2895 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2896 .andIfGetOutputLayerCountReturns(0u)
2897 .andIfLastCompositionHadVisibleLayersIs(true)
2898 .thenExpectRenderSurfaceBeginFrameCall(true)
2899 .execute()
2900 .checkPostconditionHadVisibleLayers(false);
2901 }
2902
TEST_F(OutputBeginFrameTest,hasDirtyHasLayersNotHadLayersLastFrame)2903 TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2904 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2905 .andIfGetOutputLayerCountReturns(1u)
2906 .andIfLastCompositionHadVisibleLayersIs(false)
2907 .thenExpectRenderSurfaceBeginFrameCall(true)
2908 .execute()
2909 .checkPostconditionHadVisibleLayers(true);
2910 }
2911
TEST_F(OutputBeginFrameTest,hasDirtyNotHasLayersNotHadLayersLastFrame)2912 TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2913 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2914 .andIfGetOutputLayerCountReturns(0u)
2915 .andIfLastCompositionHadVisibleLayersIs(false)
2916 .thenExpectRenderSurfaceBeginFrameCall(false)
2917 .execute()
2918 .checkPostconditionHadVisibleLayers(false);
2919 }
2920
TEST_F(OutputBeginFrameTest,notHasDirtyHasLayersHadLayersLastFrame)2921 TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2922 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2923 .andIfGetOutputLayerCountReturns(1u)
2924 .andIfLastCompositionHadVisibleLayersIs(true)
2925 .thenExpectRenderSurfaceBeginFrameCall(false)
2926 .execute()
2927 .checkPostconditionHadVisibleLayers(true);
2928 }
2929
TEST_F(OutputBeginFrameTest,notHasDirtyNotHasLayersHadLayersLastFrame)2930 TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2931 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2932 .andIfGetOutputLayerCountReturns(0u)
2933 .andIfLastCompositionHadVisibleLayersIs(true)
2934 .thenExpectRenderSurfaceBeginFrameCall(false)
2935 .execute()
2936 .checkPostconditionHadVisibleLayers(true);
2937 }
2938
TEST_F(OutputBeginFrameTest,notHasDirtyHasLayersNotHadLayersLastFrame)2939 TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2940 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2941 .andIfGetOutputLayerCountReturns(1u)
2942 .andIfLastCompositionHadVisibleLayersIs(false)
2943 .thenExpectRenderSurfaceBeginFrameCall(false)
2944 .execute()
2945 .checkPostconditionHadVisibleLayers(false);
2946 }
2947
TEST_F(OutputBeginFrameTest,notHasDirtyNotHasLayersNotHadLayersLastFrame)2948 TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2949 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2950 .andIfGetOutputLayerCountReturns(0u)
2951 .andIfLastCompositionHadVisibleLayersIs(false)
2952 .thenExpectRenderSurfaceBeginFrameCall(false)
2953 .execute()
2954 .checkPostconditionHadVisibleLayers(false);
2955 }
2956
2957 /*
2958 * Output::devOptRepaintFlash()
2959 */
2960
2961 struct OutputDevOptRepaintFlashTest : public testing::Test {
2962 struct OutputPartialMock : public OutputPartialMockBase {
2963 // Sets up the helper functions called by the function under test to use
2964 // mock implementations.
2965 MOCK_METHOD(Region, getDirtyRegion, (), (const));
2966 MOCK_METHOD3(composeSurfaces,
2967 std::optional<base::unique_fd>(const Region&,
2968 std::shared_ptr<renderengine::ExternalTexture>,
2969 base::unique_fd&));
2970 MOCK_METHOD0(postFramebuffer, void());
2971 MOCK_METHOD0(prepareFrame, void());
2972 MOCK_METHOD0(updateProtectedContentState, void());
2973 MOCK_METHOD2(dequeueRenderBuffer,
2974 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
2975 };
2976
OutputDevOptRepaintFlashTestandroid::compositionengine::__anon479079190111::OutputDevOptRepaintFlashTest2977 OutputDevOptRepaintFlashTest() {
2978 mOutput.setDisplayColorProfileForTest(
2979 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2980 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2981 }
2982
2983 static const Region kEmptyRegion;
2984 static const Region kNotEmptyRegion;
2985
2986 StrictMock<OutputPartialMock> mOutput;
2987 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2988 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2989 CompositionRefreshArgs mRefreshArgs;
2990 };
2991
2992 const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2993 const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2994
TEST_F(OutputDevOptRepaintFlashTest,doesNothingIfFlashDelayNotSet)2995 TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2996 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2997 mOutput.mState.isEnabled = true;
2998
2999 mOutput.devOptRepaintFlash(mRefreshArgs);
3000 }
3001
TEST_F(OutputDevOptRepaintFlashTest,postsAndPreparesANewFrameIfNotEnabled)3002 TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
3003 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
3004 mOutput.mState.isEnabled = false;
3005
3006 InSequence seq;
3007 EXPECT_CALL(mOutput, postFramebuffer());
3008 EXPECT_CALL(mOutput, prepareFrame());
3009
3010 mOutput.devOptRepaintFlash(mRefreshArgs);
3011 }
3012
TEST_F(OutputDevOptRepaintFlashTest,postsAndPreparesANewFrameIfEnabled)3013 TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
3014 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
3015 mOutput.mState.isEnabled = true;
3016
3017 InSequence seq;
3018 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
3019 EXPECT_CALL(mOutput, postFramebuffer());
3020 EXPECT_CALL(mOutput, prepareFrame());
3021
3022 mOutput.devOptRepaintFlash(mRefreshArgs);
3023 }
3024
TEST_F(OutputDevOptRepaintFlashTest,alsoComposesSurfacesAndQueuesABufferIfDirty)3025 TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3026 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
3027 mOutput.mState.isEnabled = true;
3028
3029 InSequence seq;
3030 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
3031 EXPECT_CALL(mOutput, updateProtectedContentState());
3032 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3033 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
3034 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3035 EXPECT_CALL(mOutput, postFramebuffer());
3036 EXPECT_CALL(mOutput, prepareFrame());
3037
3038 mOutput.devOptRepaintFlash(mRefreshArgs);
3039 }
3040
3041 /*
3042 * Output::finishFrame()
3043 */
3044
3045 struct OutputFinishFrameTest : public testing::Test {
3046 struct OutputPartialMock : public OutputPartialMockBase {
3047 // Sets up the helper functions called by the function under test to use
3048 // mock implementations.
3049 MOCK_METHOD3(composeSurfaces,
3050 std::optional<base::unique_fd>(const Region&,
3051 std::shared_ptr<renderengine::ExternalTexture>,
3052 base::unique_fd&));
3053 MOCK_METHOD0(postFramebuffer, void());
3054 MOCK_METHOD0(updateProtectedContentState, void());
3055 MOCK_METHOD2(dequeueRenderBuffer,
3056 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
3057 };
3058
OutputFinishFrameTestandroid::compositionengine::__anon479079190111::OutputFinishFrameTest3059 OutputFinishFrameTest() {
3060 mOutput.setDisplayColorProfileForTest(
3061 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3062 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3063 }
3064
3065 StrictMock<OutputPartialMock> mOutput;
3066 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3067 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3068 };
3069
TEST_F(OutputFinishFrameTest,ifNotEnabledDoesNothing)3070 TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3071 mOutput.mState.isEnabled = false;
3072
3073 impl::GpuCompositionResult result;
3074 mOutput.finishFrame(std::move(result));
3075 }
3076
TEST_F(OutputFinishFrameTest,takesEarlyOutifComposeSurfacesReturnsNoFence)3077 TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3078 mOutput.mState.isEnabled = true;
3079 EXPECT_CALL(mOutput, updateProtectedContentState());
3080 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3081 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
3082
3083 impl::GpuCompositionResult result;
3084 mOutput.finishFrame(std::move(result));
3085 }
3086
TEST_F(OutputFinishFrameTest,queuesBufferIfComposeSurfacesReturnsAFence)3087 TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3088 mOutput.mState.isEnabled = true;
3089
3090 InSequence seq;
3091 EXPECT_CALL(mOutput, updateProtectedContentState());
3092 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3093 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3094 .WillOnce(Return(ByMove(base::unique_fd())));
3095 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3096
3097 impl::GpuCompositionResult result;
3098 mOutput.finishFrame(std::move(result));
3099 }
3100
TEST_F(OutputFinishFrameTest,predictionSucceeded)3101 TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3102 mOutput.mState.isEnabled = true;
3103 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
3104 InSequence seq;
3105 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3106
3107 impl::GpuCompositionResult result;
3108 mOutput.finishFrame(std::move(result));
3109 }
3110
TEST_F(OutputFinishFrameTest,predictionFailedAndBufferIsReused)3111 TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3112 mOutput.mState.isEnabled = true;
3113 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
3114
3115 InSequence seq;
3116
3117 impl::GpuCompositionResult result;
3118 result.buffer =
3119 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3120 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3121 2);
3122
3123 EXPECT_CALL(mOutput,
3124 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
3125 Eq(ByRef(result.fence))))
3126 .WillOnce(Return(ByMove(base::unique_fd())));
3127 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3128 mOutput.finishFrame(std::move(result));
3129 }
3130
3131 /*
3132 * Output::postFramebuffer()
3133 */
3134
3135 struct OutputPostFramebufferTest : public testing::Test {
3136 struct OutputPartialMock : public OutputPartialMockBase {
3137 // Sets up the helper functions called by the function under test to use
3138 // mock implementations.
3139 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3140 };
3141
3142 struct Layer {
Layerandroid::compositionengine::__anon479079190111::OutputPostFramebufferTest::Layer3143 Layer() {
3144 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
3145 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3146 }
3147
3148 StrictMock<mock::OutputLayer> outputLayer;
3149 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
3150 StrictMock<HWC2::mock::Layer> hwc2Layer;
3151 };
3152
OutputPostFramebufferTestandroid::compositionengine::__anon479079190111::OutputPostFramebufferTest3153 OutputPostFramebufferTest() {
3154 mOutput.setDisplayColorProfileForTest(
3155 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3156 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3157
3158 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3159 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3160 .WillRepeatedly(Return(&mLayer1.outputLayer));
3161 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3162 .WillRepeatedly(Return(&mLayer2.outputLayer));
3163 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3164 .WillRepeatedly(Return(&mLayer3.outputLayer));
3165 }
3166
3167 StrictMock<OutputPartialMock> mOutput;
3168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3170
3171 Layer mLayer1;
3172 Layer mLayer2;
3173 Layer mLayer3;
3174 };
3175
TEST_F(OutputPostFramebufferTest,ifNotEnabledDoesNothing)3176 TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3177 mOutput.mState.isEnabled = false;
3178
3179 mOutput.postFramebuffer();
3180 }
3181
TEST_F(OutputPostFramebufferTest,ifEnabledMustFlipThenPresentThenSendPresentCompleted)3182 TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3183 mOutput.mState.isEnabled = true;
3184
3185 compositionengine::Output::FrameFences frameFences;
3186
3187 // This should happen even if there are no output layers.
3188 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3189
3190 // For this test in particular we want to make sure the call expectations
3191 // setup below are satisfied in the specific order.
3192 InSequence seq;
3193
3194 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3195 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3196
3197 mOutput.postFramebuffer();
3198 }
3199
TEST_F(OutputPostFramebufferTest,releaseFencesAreSentToLayerFE)3200 TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3201 // Simulate getting release fences from each layer, and ensure they are passed to the
3202 // front-end layer interface for each layer correctly.
3203
3204 mOutput.mState.isEnabled = true;
3205
3206 // Create three unique fence instances
3207 sp<Fence> layer1Fence = sp<Fence>::make();
3208 sp<Fence> layer2Fence = sp<Fence>::make();
3209 sp<Fence> layer3Fence = sp<Fence>::make();
3210
3211 Output::FrameFences frameFences;
3212 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3213 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3214 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3215
3216 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3217 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3218
3219 // Compare the pointers values of each fence to make sure the correct ones
3220 // are passed. This happens to work with the current implementation, but
3221 // would not survive certain calls like Fence::merge() which would return a
3222 // new instance.
3223 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
3224 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3225 ui::LayerStack) {
3226 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
3227 });
3228 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
3229 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3230 ui::LayerStack) {
3231 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
3232 });
3233 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
3234 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3235 ui::LayerStack) {
3236 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
3237 });
3238
3239 mOutput.postFramebuffer();
3240 }
3241
TEST_F(OutputPostFramebufferTest,releaseFencesIncludeClientTargetAcquireFence)3242 TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3243 mOutput.mState.isEnabled = true;
3244 mOutput.mState.usesClientComposition = true;
3245
3246 Output::FrameFences frameFences;
3247 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3248 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3249 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3250 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3251
3252 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3253 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3254
3255 // Fence::merge is called, and since none of the fences are actually valid,
3256 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3257 // This is the best we can do without creating a real kernel fence object.
3258 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3259 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3260 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
3261
3262 mOutput.postFramebuffer();
3263 }
3264
TEST_F(OutputPostFramebufferTest,releasedLayersSentPresentFence)3265 TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3266 mOutput.mState.isEnabled = true;
3267 mOutput.mState.usesClientComposition = true;
3268
3269 // This should happen even if there are no (current) output layers.
3270 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3271
3272 // Load up the released layers with some mock instances
3273 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3274 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3275 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3276 Output::ReleasedLayers layers;
3277 layers.push_back(releasedLayer1);
3278 layers.push_back(releasedLayer2);
3279 layers.push_back(releasedLayer3);
3280 mOutput.setReleasedLayers(std::move(layers));
3281
3282 // Set up a fake present fence
3283 sp<Fence> presentFence = sp<Fence>::make();
3284 Output::FrameFences frameFences;
3285 frameFences.presentFence = presentFence;
3286
3287 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3288 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3289
3290 // Each released layer should be given the presentFence.
3291 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
3292 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3293 ui::LayerStack) {
3294 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
3295 });
3296 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
3297 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3298 ui::LayerStack) {
3299 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
3300 });
3301 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
3302 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3303 ui::LayerStack) {
3304 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
3305 });
3306
3307 mOutput.postFramebuffer();
3308
3309 // After the call the list of released layers should have been cleared.
3310 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3311 }
3312
3313 /*
3314 * Output::composeSurfaces()
3315 */
3316
3317 struct OutputComposeSurfacesTest : public testing::Test {
3318 using TestType = OutputComposeSurfacesTest;
3319
3320 struct OutputPartialMock : public OutputPartialMockBase {
3321 // Sets up the helper functions called by the function under test to use
3322 // mock implementations.
3323 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
3324 MOCK_METHOD3(generateClientCompositionRequests,
3325 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3326 std::vector<LayerFE*>&));
3327 MOCK_METHOD2(appendRegionFlashRequests,
3328 void(const Region&, std::vector<LayerFE::LayerSettings>&));
3329 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3330 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3331 (override));
3332 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
3333 };
3334
OutputComposeSurfacesTestandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest3335 OutputComposeSurfacesTest() {
3336 mOutput.setDisplayColorProfileForTest(
3337 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3338 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3339 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
3340
3341 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3342 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3343 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3344 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3345 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
3346 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
3347 mOutput.mState.dataspace = kDefaultOutputDataspace;
3348 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3349 mOutput.mState.isSecure = false;
3350 mOutput.mState.needsFiltering = false;
3351 mOutput.mState.usesClientComposition = true;
3352 mOutput.mState.usesDeviceComposition = false;
3353 mOutput.mState.reusedClientComposition = false;
3354 mOutput.mState.flipClientTarget = false;
3355 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
3356
3357 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3358 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
3359 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
3360 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3361 .WillRepeatedly(ReturnRef(kHdrCapabilities));
3362 }
3363
3364 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
executeandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest::ExecuteState3365 auto execute() {
3366 base::unique_fd fence;
3367 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3368 const bool success =
3369 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3370 if (success) {
3371 getInstance()->mReadyFence =
3372 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3373 fence);
3374 }
3375 return nextState<FenceCheckState>();
3376 }
3377 };
3378
3379 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
expectNoFenceWasReturnedandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest::FenceCheckState3380 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3381
expectAFenceWasReturnedandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest::FenceCheckState3382 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3383 };
3384
3385 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest3386 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3387
3388 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3389 static constexpr uint32_t kDefaultOutputOrientationFlags =
3390 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
3391 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3392 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3393 static constexpr float kDefaultMaxLuminance = 0.9f;
3394 static constexpr float kDefaultAvgLuminance = 0.7f;
3395 static constexpr float kDefaultMinLuminance = 0.1f;
3396 static constexpr float kDisplayLuminance = 400.f;
3397 static constexpr float kClientTargetLuminanceNits = 200.f;
3398 static constexpr float kClientTargetBrightness = 0.5f;
3399
3400 static const Rect kDefaultOutputFrame;
3401 static const Rect kDefaultOutputViewport;
3402 static const Rect kDefaultOutputDestinationClip;
3403 static const mat4 kDefaultColorTransformMat;
3404
3405 static const Region kDebugRegion;
3406 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
3407 static const HdrCapabilities kHdrCapabilities;
3408
3409 StrictMock<mock::CompositionEngine> mCompositionEngine;
3410 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
3411 // TODO: make this is a proper mock.
3412 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
3413 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3414 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3415 StrictMock<OutputPartialMock> mOutput;
3416 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3417 renderengine::impl::
3418 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3419 renderengine::impl::ExternalTexture::Usage::READABLE |
3420 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3421
3422 std::optional<base::unique_fd> mReadyFence;
3423 };
3424
3425 const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3426 const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
3427 const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
3428 const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
3429 const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
3430 const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3431
3432 const HdrCapabilities OutputComposeSurfacesTest::
3433 kHdrCapabilities{{},
3434 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3435 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3436 OutputComposeSurfacesTest::kDefaultMinLuminance};
3437
TEST_F(OutputComposeSurfacesTest,doesNothingButSignalNoExpensiveRenderingIfNoClientComposition)3438 TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
3439 mOutput.mState.usesClientComposition = false;
3440
3441 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3442 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3443
3444 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3445
3446 verify().execute().expectAFenceWasReturned();
3447 }
3448
TEST_F(OutputComposeSurfacesTest,dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested)3449 TEST_F(OutputComposeSurfacesTest,
3450 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3451 mOutput.mState.usesClientComposition = false;
3452 mOutput.mState.flipClientTarget = true;
3453
3454 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3455 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3456
3457 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3458 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3459
3460 verify().execute().expectAFenceWasReturned();
3461 }
3462
TEST_F(OutputComposeSurfacesTest,doesMinimalWorkIfDequeueBufferFailsForClientComposition)3463 TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3464 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3465 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3466
3467 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3468
3469 verify().execute().expectNoFenceWasReturned();
3470 }
3471
TEST_F(OutputComposeSurfacesTest,doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested)3472 TEST_F(OutputComposeSurfacesTest,
3473 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3474 mOutput.mState.usesClientComposition = false;
3475 mOutput.mState.flipClientTarget = true;
3476
3477 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3478 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3479
3480 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3481
3482 verify().execute().expectNoFenceWasReturned();
3483 }
3484
TEST_F(OutputComposeSurfacesTest,handlesZeroCompositionRequests)3485 TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3486 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3487 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3488 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3489 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3490 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3491 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
3492 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3493 .WillRepeatedly(Return());
3494
3495 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3496 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3497 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3498 const std::vector<renderengine::LayerSettings>&,
3499 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3500 base::unique_fd&&) -> ftl::Future<FenceResult> {
3501 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3502 });
3503 verify().execute().expectAFenceWasReturned();
3504 }
3505
TEST_F(OutputComposeSurfacesTest,buildsAndRendersRequestList)3506 TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
3507 LayerFE::LayerSettings r1;
3508 LayerFE::LayerSettings r2;
3509
3510 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3511 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3512
3513 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3514 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3515 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3516 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3517 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3518 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3519 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3520 .WillRepeatedly(
3521 Invoke([&](const Region&,
3522 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3523 clientCompositionLayers.emplace_back(r2);
3524 }));
3525
3526 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3527 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
3528 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3529 const std::vector<renderengine::LayerSettings>&,
3530 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3531 base::unique_fd&&) -> ftl::Future<FenceResult> {
3532 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3533 });
3534
3535 verify().execute().expectAFenceWasReturned();
3536 }
3537
TEST_F(OutputComposeSurfacesTest,buildsAndRendersRequestListAndCachesFramebufferForInternalLayers)3538 TEST_F(OutputComposeSurfacesTest,
3539 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3540 LayerFE::LayerSettings r1;
3541 LayerFE::LayerSettings r2;
3542
3543 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3544 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3545 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
3546
3547 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3548 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3549 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3550 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3551 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3552 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3553 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3554 .WillRepeatedly(
3555 Invoke([&](const Region&,
3556 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3557 clientCompositionLayers.emplace_back(r2);
3558 }));
3559
3560 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3561 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
3562 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3563 const std::vector<renderengine::LayerSettings>&,
3564 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3565 base::unique_fd&&) -> ftl::Future<FenceResult> {
3566 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3567 });
3568
3569 verify().execute().expectAFenceWasReturned();
3570 }
3571
TEST_F(OutputComposeSurfacesTest,renderDuplicateClientCompositionRequestsWithoutCache)3572 TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3573 mOutput.cacheClientCompositionRequests(0);
3574 LayerFE::LayerSettings r1;
3575 LayerFE::LayerSettings r2;
3576
3577 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3578 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3579
3580 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3581 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3582 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3583 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3584 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3585 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3586 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3587 .WillRepeatedly(Return());
3588
3589 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3590 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
3591 .Times(2)
3592 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3593 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
3594
3595 verify().execute().expectAFenceWasReturned();
3596 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3597
3598 verify().execute().expectAFenceWasReturned();
3599 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3600 }
3601
TEST_F(OutputComposeSurfacesTest,skipDuplicateClientCompositionRequests)3602 TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3603 mOutput.cacheClientCompositionRequests(3);
3604 LayerFE::LayerSettings r1;
3605 LayerFE::LayerSettings r2;
3606
3607 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3608 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3609
3610 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3611 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3612 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3613 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3614 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3615 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3616 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3617 .WillRepeatedly(Return());
3618
3619 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3620 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
3621 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
3622 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3623
3624 verify().execute().expectAFenceWasReturned();
3625 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3626
3627 // We do not expect another call to draw layers.
3628 verify().execute().expectAFenceWasReturned();
3629 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3630 }
3631
TEST_F(OutputComposeSurfacesTest,clientCompositionIfBufferChanges)3632 TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3633 LayerFE::LayerSettings r1;
3634 LayerFE::LayerSettings r2;
3635
3636 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3637 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3638
3639 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3640 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3641 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3642 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3643 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3644 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3645 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3646 .WillRepeatedly(Return());
3647
3648 const auto otherOutputBuffer = std::make_shared<
3649 renderengine::impl::
3650 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3651 renderengine::impl::ExternalTexture::Usage::READABLE |
3652 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3653 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3654 .WillOnce(Return(mOutputBuffer))
3655 .WillOnce(Return(otherOutputBuffer));
3656 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
3657 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3658 const std::vector<renderengine::LayerSettings>&,
3659 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3660 base::unique_fd&&) -> ftl::Future<FenceResult> {
3661 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3662 });
3663
3664 verify().execute().expectAFenceWasReturned();
3665 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3666
3667 verify().execute().expectAFenceWasReturned();
3668 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3669 }
3670
TEST_F(OutputComposeSurfacesTest,clientCompositionIfRequestChanges)3671 TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3672 LayerFE::LayerSettings r1;
3673 LayerFE::LayerSettings r2;
3674 LayerFE::LayerSettings r3;
3675
3676 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3677 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3678 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3679
3680 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3681 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3682 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3683 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3684 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3685 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3686 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3687 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3688 .WillRepeatedly(Return());
3689
3690 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3691 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
3692 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
3693 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
3694 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
3695
3696 verify().execute().expectAFenceWasReturned();
3697 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3698
3699 verify().execute().expectAFenceWasReturned();
3700 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3701 }
3702
3703 struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
OutputComposeSurfacesTest_UsesExpectedDisplaySettingsandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings3704 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3705 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3706 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3707 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3708 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
3709 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3710 .WillRepeatedly(Return());
3711 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3712 }
3713
3714 struct MixedCompositionState
3715 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
ifMixedCompositionIsandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::MixedCompositionState3716 auto ifMixedCompositionIs(bool used) {
3717 getInstance()->mOutput.mState.usesDeviceComposition = used;
3718 return nextState<OutputUsesHdrState>();
3719 }
3720 };
3721
3722 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
andIfUsesHdrandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::OutputUsesHdrState3723 auto andIfUsesHdr(bool used) {
3724 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3725 .WillOnce(Return(used));
3726 return nextState<OutputWithDisplayBrightnessNits>();
3727 }
3728 };
3729
3730 struct OutputWithDisplayBrightnessNits
3731 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
withDisplayBrightnessNitsandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::OutputWithDisplayBrightnessNits3732 auto withDisplayBrightnessNits(float nits) {
3733 getInstance()->mOutput.mState.displayBrightnessNits = nits;
3734 return nextState<OutputWithDimmingStage>();
3735 }
3736 };
3737
3738 struct OutputWithDimmingStage
3739 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
withDimmingStageandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::OutputWithDimmingStage3740 auto withDimmingStage(
3741 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3742 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
3743 return nextState<OutputWithRenderIntent>();
3744 }
3745 };
3746
3747 struct OutputWithRenderIntent
3748 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
withRenderIntentandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::OutputWithRenderIntent3749 auto withRenderIntent(
3750 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3751 getInstance()->mOutput.mState.renderIntent =
3752 static_cast<ui::RenderIntent>(renderIntent);
3753 return nextState<SkipColorTransformState>();
3754 }
3755 };
3756
3757 struct SkipColorTransformState
3758 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
andIfSkipColorTransformandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::SkipColorTransformState3759 auto andIfSkipColorTransform(bool skip) {
3760 // May be called zero or one times.
3761 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3762 .WillRepeatedly(Return(skip));
3763 return nextState<ExpectDisplaySettingsState>();
3764 }
3765 };
3766
3767 struct ExpectDisplaySettingsState
3768 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
thenExpectDisplaySettingsUsedandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings::ExpectDisplaySettingsState3769 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3770 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3771 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
3772 return nextState<ExecuteState>();
3773 }
3774 };
3775
3776 // Call this member function to start using the mini-DSL defined above.
verifyandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_UsesExpectedDisplaySettings3777 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3778 };
3779
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forHdrMixedComposition)3780 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3781 verify().ifMixedCompositionIs(true)
3782 .andIfUsesHdr(true)
3783 .withDisplayBrightnessNits(kDisplayLuminance)
3784 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3785 .withRenderIntent(
3786 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3787 .andIfSkipColorTransform(false)
3788 .thenExpectDisplaySettingsUsed(
3789 {.physicalDisplay = kDefaultOutputDestinationClip,
3790 .clip = kDefaultOutputViewport,
3791 .maxLuminance = kDefaultMaxLuminance,
3792 .currentLuminanceNits = kDisplayLuminance,
3793 .outputDataspace = kDefaultOutputDataspace,
3794 .colorTransform = kDefaultColorTransformMat,
3795 .deviceHandlesColorTransform = true,
3796 .orientation = kDefaultOutputOrientationFlags,
3797 .targetLuminanceNits = kClientTargetLuminanceNits,
3798 .dimmingStage =
3799 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3800 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3801 COLORIMETRIC})
3802 .execute()
3803 .expectAFenceWasReturned();
3804 }
3805
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forHdrMixedCompositionWithDisplayBrightness)3806 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3807 forHdrMixedCompositionWithDisplayBrightness) {
3808 verify().ifMixedCompositionIs(true)
3809 .andIfUsesHdr(true)
3810 .withDisplayBrightnessNits(kDisplayLuminance)
3811 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3812 .withRenderIntent(
3813 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3814 .andIfSkipColorTransform(false)
3815 .thenExpectDisplaySettingsUsed(
3816 {.physicalDisplay = kDefaultOutputDestinationClip,
3817 .clip = kDefaultOutputViewport,
3818 .maxLuminance = kDefaultMaxLuminance,
3819 .currentLuminanceNits = kDisplayLuminance,
3820 .outputDataspace = kDefaultOutputDataspace,
3821 .colorTransform = kDefaultColorTransformMat,
3822 .deviceHandlesColorTransform = true,
3823 .orientation = kDefaultOutputOrientationFlags,
3824 .targetLuminanceNits = kClientTargetLuminanceNits,
3825 .dimmingStage =
3826 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3827 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3828 COLORIMETRIC})
3829 .execute()
3830 .expectAFenceWasReturned();
3831 }
3832
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forHdrMixedCompositionWithDimmingStage)3833 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3834 forHdrMixedCompositionWithDimmingStage) {
3835 verify().ifMixedCompositionIs(true)
3836 .andIfUsesHdr(true)
3837 .withDisplayBrightnessNits(kDisplayLuminance)
3838 .withDimmingStage(
3839 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
3840 .withRenderIntent(
3841 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3842 .andIfSkipColorTransform(false)
3843 .thenExpectDisplaySettingsUsed(
3844 {.physicalDisplay = kDefaultOutputDestinationClip,
3845 .clip = kDefaultOutputViewport,
3846 .maxLuminance = kDefaultMaxLuminance,
3847 .currentLuminanceNits = kDisplayLuminance,
3848 .outputDataspace = kDefaultOutputDataspace,
3849 .colorTransform = kDefaultColorTransformMat,
3850 .deviceHandlesColorTransform = true,
3851 .orientation = kDefaultOutputOrientationFlags,
3852 .targetLuminanceNits = kClientTargetLuminanceNits,
3853 .dimmingStage =
3854 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3855 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3856 COLORIMETRIC})
3857 .execute()
3858 .expectAFenceWasReturned();
3859 }
3860
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forHdrMixedCompositionWithRenderIntent)3861 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3862 forHdrMixedCompositionWithRenderIntent) {
3863 verify().ifMixedCompositionIs(true)
3864 .andIfUsesHdr(true)
3865 .withDisplayBrightnessNits(kDisplayLuminance)
3866 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3867 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3868 .andIfSkipColorTransform(false)
3869 .thenExpectDisplaySettingsUsed(
3870 {.physicalDisplay = kDefaultOutputDestinationClip,
3871 .clip = kDefaultOutputViewport,
3872 .maxLuminance = kDefaultMaxLuminance,
3873 .currentLuminanceNits = kDisplayLuminance,
3874 .outputDataspace = kDefaultOutputDataspace,
3875 .colorTransform = kDefaultColorTransformMat,
3876 .deviceHandlesColorTransform = true,
3877 .orientation = kDefaultOutputOrientationFlags,
3878 .targetLuminanceNits = kClientTargetLuminanceNits,
3879 .dimmingStage =
3880 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3881 .renderIntent =
3882 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3883 .execute()
3884 .expectAFenceWasReturned();
3885 }
3886
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forNonHdrMixedComposition)3887 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3888 verify().ifMixedCompositionIs(true)
3889 .andIfUsesHdr(false)
3890 .withDisplayBrightnessNits(kDisplayLuminance)
3891 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3892 .withRenderIntent(
3893 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3894 .andIfSkipColorTransform(false)
3895 .thenExpectDisplaySettingsUsed(
3896 {.physicalDisplay = kDefaultOutputDestinationClip,
3897 .clip = kDefaultOutputViewport,
3898 .maxLuminance = kDefaultMaxLuminance,
3899 .currentLuminanceNits = kDisplayLuminance,
3900 .outputDataspace = kDefaultOutputDataspace,
3901 .colorTransform = kDefaultColorTransformMat,
3902 .deviceHandlesColorTransform = true,
3903 .orientation = kDefaultOutputOrientationFlags,
3904 .targetLuminanceNits = kClientTargetLuminanceNits,
3905 .dimmingStage =
3906 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3907 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3908 COLORIMETRIC})
3909 .execute()
3910 .expectAFenceWasReturned();
3911 }
3912
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forHdrOnlyClientComposition)3913 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3914 verify().ifMixedCompositionIs(false)
3915 .andIfUsesHdr(true)
3916 .withDisplayBrightnessNits(kDisplayLuminance)
3917 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3918 .withRenderIntent(
3919 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3920 .andIfSkipColorTransform(false)
3921 .thenExpectDisplaySettingsUsed(
3922 {.physicalDisplay = kDefaultOutputDestinationClip,
3923 .clip = kDefaultOutputViewport,
3924 .maxLuminance = kDefaultMaxLuminance,
3925 .currentLuminanceNits = kDisplayLuminance,
3926 .outputDataspace = kDefaultOutputDataspace,
3927 .colorTransform = kDefaultColorTransformMat,
3928 .deviceHandlesColorTransform = false,
3929 .orientation = kDefaultOutputOrientationFlags,
3930 .targetLuminanceNits = kClientTargetLuminanceNits,
3931 .dimmingStage =
3932 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3933 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3934 COLORIMETRIC})
3935 .execute()
3936 .expectAFenceWasReturned();
3937 }
3938
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,forNonHdrOnlyClientComposition)3939 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3940 verify().ifMixedCompositionIs(false)
3941 .andIfUsesHdr(false)
3942 .withDisplayBrightnessNits(kDisplayLuminance)
3943 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3944 .withRenderIntent(
3945 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3946 .andIfSkipColorTransform(false)
3947 .thenExpectDisplaySettingsUsed(
3948 {.physicalDisplay = kDefaultOutputDestinationClip,
3949 .clip = kDefaultOutputViewport,
3950 .maxLuminance = kDefaultMaxLuminance,
3951 .currentLuminanceNits = kDisplayLuminance,
3952 .outputDataspace = kDefaultOutputDataspace,
3953 .colorTransform = kDefaultColorTransformMat,
3954 .deviceHandlesColorTransform = false,
3955 .orientation = kDefaultOutputOrientationFlags,
3956 .targetLuminanceNits = kClientTargetLuminanceNits,
3957 .dimmingStage =
3958 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3959 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3960 COLORIMETRIC})
3961 .execute()
3962 .expectAFenceWasReturned();
3963 }
3964
TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform)3965 TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3966 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3967 verify().ifMixedCompositionIs(false)
3968 .andIfUsesHdr(true)
3969 .withDisplayBrightnessNits(kDisplayLuminance)
3970 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3971 .withRenderIntent(
3972 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3973 .andIfSkipColorTransform(true)
3974 .thenExpectDisplaySettingsUsed(
3975 {.physicalDisplay = kDefaultOutputDestinationClip,
3976 .clip = kDefaultOutputViewport,
3977 .maxLuminance = kDefaultMaxLuminance,
3978 .currentLuminanceNits = kDisplayLuminance,
3979 .outputDataspace = kDefaultOutputDataspace,
3980 .colorTransform = kDefaultColorTransformMat,
3981 .deviceHandlesColorTransform = true,
3982 .orientation = kDefaultOutputOrientationFlags,
3983 .targetLuminanceNits = kClientTargetLuminanceNits,
3984 .dimmingStage =
3985 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3986 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3987 COLORIMETRIC})
3988 .execute()
3989 .expectAFenceWasReturned();
3990 }
3991
3992 struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3993 struct Layer {
Layerandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_HandlesProtectedContent::Layer3994 Layer() {
3995 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3996 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3997 }
3998
3999 StrictMock<mock::OutputLayer> mOutputLayer;
4000 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
4001 LayerFECompositionState mLayerFEState;
4002 };
4003
OutputComposeSurfacesTest_HandlesProtectedContentandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_HandlesProtectedContent4004 OutputComposeSurfacesTest_HandlesProtectedContent() {
4005 mLayer1.mLayerFEState.hasProtectedContent = false;
4006 mLayer2.mLayerFEState.hasProtectedContent = false;
4007
4008 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4009 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4010 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4011 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4012 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4013
4014 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4015
4016 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4017
4018 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
4019 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
4020 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4021 .WillRepeatedly(Return());
4022 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4023 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4024 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4025 const std::vector<renderengine::LayerSettings>&,
4026 const std::shared_ptr<renderengine::ExternalTexture>&,
4027 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
4028 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4029 });
4030 }
4031
4032 Layer mLayer1;
4033 Layer mLayer2;
4034 };
4035
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent,ifNoProtectedContentLayers)4036 TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4037 mOutput.mState.isSecure = true;
4038 mLayer2.mLayerFEState.hasProtectedContent = false;
4039 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4040 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4041 EXPECT_CALL(*mRenderSurface, setProtected(false));
4042
4043 base::unique_fd fd;
4044 std::shared_ptr<renderengine::ExternalTexture> tex;
4045 mOutput.updateProtectedContentState();
4046 mOutput.dequeueRenderBuffer(&fd, &tex);
4047 mOutput.composeSurfaces(kDebugRegion, tex, fd);
4048 }
4049
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent,ifNotEnabled)4050 TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4051 mOutput.mState.isSecure = true;
4052 mLayer2.mLayerFEState.hasProtectedContent = true;
4053 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4054
4055 // For this test, we also check the call order of key functions.
4056 InSequence seq;
4057
4058 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4059 EXPECT_CALL(*mRenderSurface, setProtected(true));
4060 // Must happen after setting the protected content state.
4061 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4062 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4063 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
4064
4065 base::unique_fd fd;
4066 std::shared_ptr<renderengine::ExternalTexture> tex;
4067 mOutput.updateProtectedContentState();
4068 mOutput.dequeueRenderBuffer(&fd, &tex);
4069 mOutput.composeSurfaces(kDebugRegion, tex, fd);
4070 }
4071
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent,ifAlreadyEnabledEverywhere)4072 TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4073 mOutput.mState.isSecure = true;
4074 mLayer2.mLayerFEState.hasProtectedContent = true;
4075 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4076 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4077
4078 base::unique_fd fd;
4079 std::shared_ptr<renderengine::ExternalTexture> tex;
4080 mOutput.updateProtectedContentState();
4081 mOutput.dequeueRenderBuffer(&fd, &tex);
4082 mOutput.composeSurfaces(kDebugRegion, tex, fd);
4083 }
4084
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent,ifAlreadyEnabledInRenderSurface)4085 TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4086 mOutput.mState.isSecure = true;
4087 mLayer2.mLayerFEState.hasProtectedContent = true;
4088 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4089 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4090
4091 base::unique_fd fd;
4092 std::shared_ptr<renderengine::ExternalTexture> tex;
4093 mOutput.updateProtectedContentState();
4094 mOutput.dequeueRenderBuffer(&fd, &tex);
4095 mOutput.composeSurfaces(kDebugRegion, tex, fd);
4096 }
4097
4098 struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
OutputComposeSurfacesTest_SetsExpensiveRenderingandroid::compositionengine::__anon479079190111::OutputComposeSurfacesTest_SetsExpensiveRendering4099 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4100 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4101 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4102 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4103 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
4104 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4105 .WillRepeatedly(Return());
4106 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4107 }
4108 };
4109
TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering,IfExepensiveOutputDataspaceIsUsed)4110 TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4111 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4112
4113 LayerFE::LayerSettings layerSettings;
4114 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
4115 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
4116
4117 // For this test, we also check the call order of key functions.
4118 InSequence seq;
4119
4120 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
4121 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4122 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
4123
4124 base::unique_fd fd;
4125 std::shared_ptr<renderengine::ExternalTexture> tex;
4126 mOutput.updateProtectedContentState();
4127 mOutput.dequeueRenderBuffer(&fd, &tex);
4128 mOutput.composeSurfaces(kDebugRegion, tex, fd);
4129 }
4130
4131 /*
4132 * Output::generateClientCompositionRequests()
4133 */
4134
4135 struct GenerateClientCompositionRequestsTest : public testing::Test {
4136 struct OutputPartialMock : public OutputPartialMockBase {
4137 // compositionengine::Output overrides
generateClientCompositionRequestsHelperandroid::compositionengine::__anon479079190111::GenerateClientCompositionRequestsTest::OutputPartialMock4138 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4139 bool supportsProtectedContent, ui::Dataspace dataspace) {
4140 std::vector<LayerFE*> ignore;
4141 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
4142 dataspace, ignore);
4143 }
4144 };
4145
4146 struct Layer {
Layerandroid::compositionengine::__anon479079190111::GenerateClientCompositionRequestsTest::Layer4147 Layer() {
4148 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4149 .WillRepeatedly(Return(std::nullopt));
4150 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4151 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4152 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4153 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4154 }
4155
4156 StrictMock<mock::OutputLayer> mOutputLayer;
4157 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
4158 LayerFECompositionState mLayerFEState;
4159 impl::OutputLayerCompositionState mOutputLayerState;
4160 LayerFE::LayerSettings mLayerSettings;
4161 };
4162
GenerateClientCompositionRequestsTestandroid::compositionengine::__anon479079190111::GenerateClientCompositionRequestsTest4163 GenerateClientCompositionRequestsTest() {
4164 mOutput.mState.needsFiltering = false;
4165
4166 mOutput.setDisplayColorProfileForTest(
4167 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4168 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4169 }
4170
4171 static constexpr float kLayerWhitePointNits = 200.f;
4172
4173 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4174 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
4175 StrictMock<OutputPartialMock> mOutput;
4176 };
4177
4178 struct GenerateClientCompositionRequestsTest_ThreeLayers
4179 : public GenerateClientCompositionRequestsTest {
GenerateClientCompositionRequestsTest_ThreeLayersandroid::compositionengine::__anon479079190111::GenerateClientCompositionRequestsTest_ThreeLayers4180 GenerateClientCompositionRequestsTest_ThreeLayers() {
4181 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4182 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4183 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
4184 mOutput.mState.transform =
4185 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
4186 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
4187 mOutput.mState.needsFiltering = false;
4188 mOutput.mState.isSecure = false;
4189
4190 for (size_t i = 0; i < mLayers.size(); i++) {
4191 mLayers[i].mOutputLayerState.clearClientTarget = false;
4192 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4193 mLayers[i].mLayerFEState.isOpaque = true;
4194 mLayers[i].mLayerSettings.geometry.boundaries =
4195 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
4196 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4197 mLayers[i].mLayerSettings.alpha = 1.0f;
4198 mLayers[i].mLayerSettings.disableBlending = false;
4199
4200 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4201 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4202 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4203 .WillRepeatedly(Return(true));
4204 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4205 }
4206
4207 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4208 }
4209
4210 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
4211 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
4212 static constexpr float kLayerWhitePointNits = 200.f;
4213
4214 static const Rect kDisplayFrame;
4215 static const Rect kDisplayViewport;
4216 static const Rect kDisplayDestinationClip;
4217
4218 std::array<Layer, 3> mLayers;
4219 };
4220
4221 const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4222 const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
4223 const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4224 203);
4225
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,handlesNoClientCompostionLayers)4226 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4227 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4228 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4229 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4230
4231 auto requests =
4232 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4233 kDisplayDataspace);
4234 EXPECT_EQ(0u, requests.size());
4235 }
4236
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,requiresVisibleRegionAfterViewportClip)4237 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4238 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4239 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4240 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4241
4242 auto requests =
4243 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4244 kDisplayDataspace);
4245 EXPECT_EQ(0u, requests.size());
4246 }
4247
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,gathersClientCompositionRequests)4248 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
4249 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4250 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4251 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4252 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4253 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4254 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4255
4256 auto requests =
4257 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4258 kDisplayDataspace);
4259 ASSERT_EQ(2u, requests.size());
4260 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4261 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
4262
4263 // Check that a timestamp was set for the layers that generated requests
4264 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4265 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4266 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4267 }
4268
4269 MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4270 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4271 *result_listener << "expected " << expectedBlurSetting << "\n";
4272 *result_listener << "actual " << arg.blurSetting << "\n";
4273
4274 return expectedBlurSetting == arg.blurSetting;
4275 }
4276
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,overridesBlur)4277 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4278 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4279
4280 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4281 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4282 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4283 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4284 EXPECT_CALL(*mLayers[2].mLayerFE,
4285 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
4286 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4287 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4288 auto requests =
4289 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4290 kDisplayDataspace);
4291 ASSERT_EQ(2u, requests.size());
4292 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4293 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
4294
4295 // Check that a timestamp was set for the layers that generated requests
4296 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4297 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4298 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4299 }
4300
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,onlyClientComposesClientComposedLayersIfNoClearingNeeded)4301 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4302 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4303 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4304 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4305 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4306
4307 mLayers[0].mOutputLayerState.clearClientTarget = false;
4308 mLayers[1].mOutputLayerState.clearClientTarget = false;
4309 mLayers[2].mOutputLayerState.clearClientTarget = false;
4310
4311 mLayers[0].mLayerFEState.isOpaque = true;
4312 mLayers[1].mLayerFEState.isOpaque = true;
4313 mLayers[2].mLayerFEState.isOpaque = true;
4314
4315 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4316 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4317
4318 auto requests =
4319 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4320 kDisplayDataspace);
4321 ASSERT_EQ(1u, requests.size());
4322 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
4323 }
4324
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,onlyClientComposesClientComposedLayersIfOthersAreNotOpaque)4325 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4326 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4327 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4328 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4329 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4330
4331 mLayers[0].mOutputLayerState.clearClientTarget = true;
4332 mLayers[1].mOutputLayerState.clearClientTarget = true;
4333 mLayers[2].mOutputLayerState.clearClientTarget = true;
4334
4335 mLayers[0].mLayerFEState.isOpaque = false;
4336 mLayers[1].mLayerFEState.isOpaque = false;
4337 mLayers[2].mLayerFEState.isOpaque = false;
4338
4339 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4340 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4341
4342 auto requests =
4343 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4344 kDisplayDataspace);
4345 ASSERT_EQ(1u, requests.size());
4346 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
4347 }
4348
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,clearsHWCLayersIfOpaqueAndNotFirst)4349 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
4350 // If client composition is performed with some layers set to use device
4351 // composition, device layers after the first layer (device or client) will
4352 // clear the frame buffer if they are opaque and if that layer has a flag
4353 // set to do so. The first layer is skipped as the frame buffer is already
4354 // expected to be clear.
4355
4356 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4357 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4358 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4359
4360 mLayers[0].mOutputLayerState.clearClientTarget = true;
4361 mLayers[1].mOutputLayerState.clearClientTarget = true;
4362 mLayers[2].mOutputLayerState.clearClientTarget = true;
4363
4364 mLayers[0].mLayerFEState.isOpaque = true;
4365 mLayers[1].mLayerFEState.isOpaque = true;
4366 mLayers[2].mLayerFEState.isOpaque = true;
4367
4368 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4369 Region(kDisplayFrame),
4370 false, /* needs filtering */
4371 false, /* secure */
4372 false, /* supports protected content */
4373 kDisplayViewport,
4374 kDisplayDataspace,
4375 false /* realContentIsVisible */,
4376 true /* clearContent */,
4377 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4378 kLayerWhitePointNits,
4379 false /* treat170mAsSrgb */,
4380 };
4381 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4382 Region(kDisplayFrame),
4383 false, /* needs filtering */
4384 false, /* secure */
4385 false, /* supports protected content */
4386 kDisplayViewport,
4387 kDisplayDataspace,
4388 true /* realContentIsVisible */,
4389 false /* clearContent */,
4390 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4391 kLayerWhitePointNits,
4392 false /* treat170mAsSrgb */,
4393 };
4394
4395 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4396 mBlackoutSettings.source.buffer.buffer = nullptr;
4397 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4398 mBlackoutSettings.alpha = 0.f;
4399 mBlackoutSettings.disableBlending = true;
4400
4401 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4402 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4403 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4404 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4405
4406 auto requests =
4407 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4408 kDisplayDataspace);
4409 ASSERT_EQ(2u, requests.size());
4410
4411 // The second layer is expected to be rendered as alpha=0 black with no blending
4412 EXPECT_EQ(mBlackoutSettings, requests[0]);
4413
4414 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
4415 }
4416
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,clippedVisibleRegionUsedToGenerateRequest)4417 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4418 clippedVisibleRegionUsedToGenerateRequest) {
4419 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4420 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4421 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
4422
4423 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4424 Region(Rect(10, 10, 20, 20)),
4425 false, /* needs filtering */
4426 false, /* secure */
4427 false, /* supports protected content */
4428 kDisplayViewport,
4429 kDisplayDataspace,
4430 true /* realContentIsVisible */,
4431 false /* clearContent */,
4432 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4433 kLayerWhitePointNits,
4434 false /* treat170mAsSrgb */,
4435 };
4436 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4437 Region(Rect(0, 0, 30, 30)),
4438 false, /* needs filtering */
4439 false, /* secure */
4440 false, /* supports protected content */
4441 kDisplayViewport,
4442 kDisplayDataspace,
4443 true /* realContentIsVisible */,
4444 false /* clearContent */,
4445 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4446 kLayerWhitePointNits,
4447 false /* treat170mAsSrgb */,
4448 };
4449 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4450 Region(Rect(0, 0, 40, 201)),
4451 false, /* needs filtering */
4452 false, /* secure */
4453 false, /* supports protected content */
4454 kDisplayViewport,
4455 kDisplayDataspace,
4456 true /* realContentIsVisible */,
4457 false /* clearContent */,
4458 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4459 kLayerWhitePointNits,
4460 false /* treat170mAsSrgb */,
4461 };
4462
4463 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4464 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4465 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4466 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4467 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4468 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4469
4470 static_cast<void>(
4471 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4472 kDisplayDataspace));
4473 }
4474
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,perLayerNeedsFilteringUsedToGenerateRequests)4475 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4476 perLayerNeedsFilteringUsedToGenerateRequests) {
4477 mOutput.mState.needsFiltering = false;
4478 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4479
4480 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4481 Region(kDisplayFrame),
4482 true, /* needs filtering */
4483 false, /* secure */
4484 false, /* supports protected content */
4485 kDisplayViewport,
4486 kDisplayDataspace,
4487 true /* realContentIsVisible */,
4488 false /* clearContent */,
4489 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4490 kLayerWhitePointNits,
4491 false /* treat170mAsSrgb */,
4492 };
4493 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4494 Region(kDisplayFrame),
4495 false, /* needs filtering */
4496 false, /* secure */
4497 false, /* supports protected content */
4498 kDisplayViewport,
4499 kDisplayDataspace,
4500 true /* realContentIsVisible */,
4501 false /* clearContent */,
4502 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4503 kLayerWhitePointNits,
4504 false /* treat170mAsSrgb */,
4505 };
4506 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4507 Region(kDisplayFrame),
4508 false, /* needs filtering */
4509 false, /* secure */
4510 false, /* supports protected content */
4511 kDisplayViewport,
4512 kDisplayDataspace,
4513 true /* realContentIsVisible */,
4514 false /* clearContent */,
4515 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4516 kLayerWhitePointNits,
4517 false /* treat170mAsSrgb */,
4518 };
4519
4520 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4521 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4522 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4523 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4524 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4525 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4526
4527 static_cast<void>(
4528 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4529 kDisplayDataspace));
4530 }
4531
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,wholeOutputNeedsFilteringUsedToGenerateRequests)4532 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4533 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4534 mOutput.mState.needsFiltering = true;
4535 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4536
4537 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4538 Region(kDisplayFrame),
4539 true, /* needs filtering */
4540 false, /* secure */
4541 false, /* supports protected content */
4542 kDisplayViewport,
4543 kDisplayDataspace,
4544 true /* realContentIsVisible */,
4545 false /* clearContent */,
4546 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4547 kLayerWhitePointNits,
4548 false /* treat170mAsSrgb */,
4549 };
4550 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4551 Region(kDisplayFrame),
4552 true, /* needs filtering */
4553 false, /* secure */
4554 false, /* supports protected content */
4555 kDisplayViewport,
4556 kDisplayDataspace,
4557 true /* realContentIsVisible */,
4558 false /* clearContent */,
4559 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4560 kLayerWhitePointNits,
4561 false /* treat170mAsSrgb */,
4562 };
4563 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4564 Region(kDisplayFrame),
4565 true, /* needs filtering */
4566 false, /* secure */
4567 false, /* supports protected content */
4568 kDisplayViewport,
4569 kDisplayDataspace,
4570 true /* realContentIsVisible */,
4571 false /* clearContent */,
4572 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4573 kLayerWhitePointNits,
4574 false /* treat170mAsSrgb */,
4575 };
4576
4577 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4578 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4579 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4580 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4581 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4582 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4583
4584 static_cast<void>(
4585 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4586 kDisplayDataspace));
4587 }
4588
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,wholeOutputSecurityUsedToGenerateRequests)4589 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4590 wholeOutputSecurityUsedToGenerateRequests) {
4591 mOutput.mState.isSecure = true;
4592
4593 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4594 Region(kDisplayFrame),
4595 false, /* needs filtering */
4596 true, /* secure */
4597 false, /* supports protected content */
4598 kDisplayViewport,
4599 kDisplayDataspace,
4600 true /* realContentIsVisible */,
4601 false /* clearContent */,
4602 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4603 kLayerWhitePointNits,
4604 false /* treat170mAsSrgb */,
4605 };
4606 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4607 Region(kDisplayFrame),
4608 false, /* needs filtering */
4609 true, /* secure */
4610 false, /* supports protected content */
4611 kDisplayViewport,
4612 kDisplayDataspace,
4613 true /* realContentIsVisible */,
4614 false /* clearContent */,
4615 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4616 kLayerWhitePointNits,
4617 false /* treat170mAsSrgb */,
4618 };
4619 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4620 Region(kDisplayFrame),
4621 false, /* needs filtering */
4622 true, /* secure */
4623 false, /* supports protected content */
4624 kDisplayViewport,
4625 kDisplayDataspace,
4626 true /* realContentIsVisible */,
4627 false /* clearContent */,
4628 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4629 kLayerWhitePointNits,
4630 false /* treat170mAsSrgb */,
4631 };
4632
4633 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4634 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4635 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4636 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4637 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4638 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4639
4640 static_cast<void>(
4641 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4642 kDisplayDataspace));
4643 }
4644
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,protectedContentSupportUsedToGenerateRequests)4645 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4646 protectedContentSupportUsedToGenerateRequests) {
4647 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4648 Region(kDisplayFrame),
4649 false, /* needs filtering */
4650 false, /* secure */
4651 true, /* supports protected content */
4652 kDisplayViewport,
4653 kDisplayDataspace,
4654 true /* realContentIsVisible */,
4655 false /* clearContent */,
4656 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4657 kLayerWhitePointNits,
4658 false /* treat170mAsSrgb */,
4659 };
4660 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4661 Region(kDisplayFrame),
4662 false, /* needs filtering */
4663 false, /* secure */
4664 true, /* supports protected content */
4665 kDisplayViewport,
4666 kDisplayDataspace,
4667 true /* realContentIsVisible */,
4668 false /* clearContent */,
4669 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4670 kLayerWhitePointNits,
4671 false /* treat170mAsSrgb */,
4672 };
4673 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4674 Region(kDisplayFrame),
4675 false, /* needs filtering */
4676 false, /* secure */
4677 true, /* supports protected content */
4678 kDisplayViewport,
4679 kDisplayDataspace,
4680 true /* realContentIsVisible */,
4681 false /* clearContent */,
4682 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4683 kLayerWhitePointNits,
4684 false /* treat170mAsSrgb */,
4685 };
4686
4687 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4688 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4689 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4690 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4691 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4692 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4693
4694 static_cast<void>(
4695 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4696 kDisplayDataspace));
4697 }
4698
TEST_F(OutputUpdateAndWriteCompositionStateTest,noBackgroundBlurWhenOpaque)4699 TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4700 InjectedLayer layer1;
4701 InjectedLayer layer2;
4702
4703 uint32_t z = 0;
4704 // Layer requesting blur, or below, should request client composition, unless opaque.
4705 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4706 EXPECT_CALL(*layer1.outputLayer,
4707 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4708 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4709 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4710 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4711 EXPECT_CALL(*layer2.outputLayer,
4712 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4713 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4714 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4715
4716 layer2.layerFEState.backgroundBlurRadius = 10;
4717 layer2.layerFEState.isOpaque = true;
4718
4719 injectOutputLayer(layer1);
4720 injectOutputLayer(layer2);
4721
4722 mOutput->editState().isEnabled = true;
4723
4724 CompositionRefreshArgs args;
4725 args.updatingGeometryThisFrame = false;
4726 args.devOptForceClientComposition = false;
4727 mOutput->updateCompositionState(args);
4728 mOutput->planComposition();
4729 mOutput->writeCompositionState(args);
4730 }
4731
TEST_F(OutputUpdateAndWriteCompositionStateTest,handlesBackgroundBlurRequests)4732 TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
4733 InjectedLayer layer1;
4734 InjectedLayer layer2;
4735 InjectedLayer layer3;
4736
4737 uint32_t z = 0;
4738 // Layer requesting blur, or below, should request client composition.
4739 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4740 EXPECT_CALL(*layer1.outputLayer,
4741 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4742 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4743 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4744 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4745 EXPECT_CALL(*layer2.outputLayer,
4746 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4747 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4748 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4749 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4750 EXPECT_CALL(*layer3.outputLayer,
4751 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4752 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4753 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4754
4755 layer2.layerFEState.backgroundBlurRadius = 10;
4756 layer2.layerFEState.isOpaque = false;
4757
4758 injectOutputLayer(layer1);
4759 injectOutputLayer(layer2);
4760 injectOutputLayer(layer3);
4761
4762 mOutput->editState().isEnabled = true;
4763
4764 CompositionRefreshArgs args;
4765 args.updatingGeometryThisFrame = false;
4766 args.devOptForceClientComposition = false;
4767 mOutput->updateCompositionState(args);
4768 mOutput->planComposition();
4769 mOutput->writeCompositionState(args);
4770 }
4771
TEST_F(OutputUpdateAndWriteCompositionStateTest,handlesBlurRegionRequests)4772 TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4773 InjectedLayer layer1;
4774 InjectedLayer layer2;
4775 InjectedLayer layer3;
4776
4777 uint32_t z = 0;
4778 // Layer requesting blur, or below, should request client composition.
4779 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4780 EXPECT_CALL(*layer1.outputLayer,
4781 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4782 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4783 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4784 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
4785 EXPECT_CALL(*layer2.outputLayer,
4786 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4787 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4788 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4789 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4790 EXPECT_CALL(*layer3.outputLayer,
4791 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4792 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4793 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
4794
4795 BlurRegion region;
4796 layer2.layerFEState.blurRegions.push_back(region);
4797 layer2.layerFEState.isOpaque = false;
4798
4799 injectOutputLayer(layer1);
4800 injectOutputLayer(layer2);
4801 injectOutputLayer(layer3);
4802
4803 mOutput->editState().isEnabled = true;
4804
4805 CompositionRefreshArgs args;
4806 args.updatingGeometryThisFrame = false;
4807 args.devOptForceClientComposition = false;
4808 mOutput->updateCompositionState(args);
4809 mOutput->planComposition();
4810 mOutput->writeCompositionState(args);
4811 }
4812
TEST_F(GenerateClientCompositionRequestsTest,handlesLandscapeModeSplitScreenRequests)4813 TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4814 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4815 // one layer on the left covering the left side of the output, and one layer
4816 // on the right covering that side of the output.
4817
4818 const Rect kPortraitFrame(0, 0, 1000, 2000);
4819 const Rect kPortraitViewport(0, 0, 2000, 1000);
4820 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
4821 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
4822 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
4823
4824 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4825 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4826 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
4827 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4828 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
4829 mOutput.mState.needsFiltering = false;
4830 mOutput.mState.isSecure = true;
4831
4832 Layer leftLayer;
4833 Layer rightLayer;
4834
4835 leftLayer.mOutputLayerState.clearClientTarget = false;
4836 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4837 leftLayer.mLayerFEState.isOpaque = true;
4838 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
4839
4840 rightLayer.mOutputLayerState.clearClientTarget = false;
4841 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4842 rightLayer.mLayerFEState.isOpaque = true;
4843 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
4844
4845 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4846 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4847 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4848 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4849 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4850
4851 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4852 Region(Rect(0, 0, 1000, 1000)),
4853 false, /* needs filtering */
4854 true, /* secure */
4855 true, /* supports protected content */
4856 kPortraitViewport,
4857 kOutputDataspace,
4858 true /* realContentIsVisible */,
4859 false /* clearContent */,
4860 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4861 kLayerWhitePointNits,
4862 false /* treat170mAsSrgb */,
4863 };
4864
4865 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4866 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4867 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4868 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
4869
4870 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4871 Region(Rect(1000, 0, 2000, 1000)),
4872 false, /* needs filtering */
4873 true, /* secure */
4874 true, /* supports protected content */
4875 kPortraitViewport,
4876 kOutputDataspace,
4877 true /* realContentIsVisible */,
4878 false /* clearContent */,
4879 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4880 kLayerWhitePointNits,
4881 false /* treat170mAsSrgb */,
4882 };
4883
4884 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4885 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4886 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4887 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
4888
4889 constexpr bool supportsProtectedContent = true;
4890 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
4891 kOutputDataspace);
4892 ASSERT_EQ(2u, requests.size());
4893 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4894 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
4895 }
4896
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,shadowRegionOnlyVisibleSkipsContentComposition)4897 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4898 shadowRegionOnlyVisibleSkipsContentComposition) {
4899 const Rect kContentWithShadow(40, 40, 70, 90);
4900 const Rect kContent(50, 50, 60, 80);
4901 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4902 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4903
4904 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4905 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4906 false, /* needs filtering */
4907 false, /* secure */
4908 false, /* supports protected content */
4909 kDisplayViewport,
4910 kDisplayDataspace,
4911 false /* realContentIsVisible */,
4912 false /* clearContent */,
4913 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4914 kLayerWhitePointNits,
4915 false /* treat170mAsSrgb */,
4916 };
4917
4918 LayerFE::LayerSettings mShadowSettings;
4919 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4920
4921 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4922 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4923
4924 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4925 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4926 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4927 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
4928
4929 auto requests =
4930 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4931 kDisplayDataspace);
4932 ASSERT_EQ(1u, requests.size());
4933
4934 EXPECT_EQ(mShadowSettings, requests[0]);
4935 }
4936
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,shadowRegionWithContentVisibleRequestsContentAndShadowComposition)4937 TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4938 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4939 const Rect kContentWithShadow(40, 40, 70, 90);
4940 const Rect kContent(50, 50, 60, 80);
4941 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4942 const Region kPartialContentWithPartialShadowRegion =
4943 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4944
4945 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4946 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4947
4948 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4949 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4950 false, /* needs filtering */
4951 false, /* secure */
4952 false, /* supports protected content */
4953 kDisplayViewport,
4954 kDisplayDataspace,
4955 true /* realContentIsVisible */,
4956 false /* clearContent */,
4957 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
4958 kLayerWhitePointNits,
4959 false /* treat170mAsSrgb */,
4960 };
4961
4962 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4963 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4964 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4965 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
4966
4967 auto requests =
4968 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4969 kDisplayDataspace);
4970 ASSERT_EQ(1u, requests.size());
4971
4972 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
4973 }
4974
4975 } // namespace
4976 } // namespace android::compositionengine
4977