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