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 <com_android_graphics_libgui_flags.h>
18 #include <compositionengine/impl/HwcBufferCache.h>
19 #include <compositionengine/impl/OutputLayer.h>
20 #include <compositionengine/impl/OutputLayerCompositionState.h>
21 #include <compositionengine/mock/CompositionEngine.h>
22 #include <compositionengine/mock/DisplayColorProfile.h>
23 #include <compositionengine/mock/LayerFE.h>
24 #include <compositionengine/mock/Output.h>
25 #include <gtest/gtest.h>
26 #include <log/log.h>
27 #include <renderengine/impl/ExternalTexture.h>
28 #include <renderengine/mock/RenderEngine.h>
29 #include <ui/FloatRect.h>
30 #include <ui/PixelFormat.h>
31
32 #include "RegionMatcher.h"
33 #include "mock/DisplayHardware/MockHWC2.h"
34 #include "mock/DisplayHardware/MockHWComposer.h"
35
36 #include <aidl/android/hardware/graphics/composer3/Composition.h>
37
38 using aidl::android::hardware::graphics::composer3::Composition;
39
40 namespace android::compositionengine {
41 namespace {
42
43 namespace hal = android::hardware::graphics::composer::hal;
44
45 using testing::_;
46 using testing::InSequence;
47 using testing::Mock;
48 using testing::NiceMock;
49 using testing::Return;
50 using testing::ReturnRef;
51 using testing::StrictMock;
52
53 constexpr auto TR_IDENT = 0u;
54 constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
55 constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
56 constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
57 constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
58 constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
59
60 const std::string kOutputName{"Test Output"};
61
62 MATCHER_P(ColorEq, expected, "") {
63 *result_listener << "Colors are not equal\n";
64 *result_listener << "expected " << expected.r << " " << expected.g << " " << expected.b << " "
65 << expected.a << "\n";
66 *result_listener << "actual " << arg.r << " " << arg.g << " " << arg.b << " " << arg.a << "\n";
67
68 return expected.r == arg.r && expected.g == arg.g && expected.b == arg.b && expected.a == arg.a;
69 }
70
toRotation(uint32_t rotationFlag)71 ui::Rotation toRotation(uint32_t rotationFlag) {
72 switch (rotationFlag) {
73 case ui::Transform::RotationFlags::ROT_0:
74 return ui::ROTATION_0;
75 case ui::Transform::RotationFlags::ROT_90:
76 return ui::ROTATION_90;
77 case ui::Transform::RotationFlags::ROT_180:
78 return ui::ROTATION_180;
79 case ui::Transform::RotationFlags::ROT_270:
80 return ui::ROTATION_270;
81 default:
82 LOG_FATAL("Unexpected rotation flag %d", rotationFlag);
83 return ui::Rotation(-1);
84 }
85 }
86
87 struct OutputLayerTest : public testing::Test {
88 struct OutputLayer final : public impl::OutputLayer {
OutputLayerandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer89 OutputLayer(const compositionengine::Output& output, compositionengine::LayerFE& layerFE)
90 : mOutput(output), mLayerFE(layerFE) {}
91 ~OutputLayer() override = default;
92
93 // compositionengine::OutputLayer overrides
getOutputandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer94 const compositionengine::Output& getOutput() const override { return mOutput; }
getLayerFEandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer95 compositionengine::LayerFE& getLayerFE() const override { return mLayerFE; }
getStateandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer96 const impl::OutputLayerCompositionState& getState() const override { return mState; }
editStateandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer97 impl::OutputLayerCompositionState& editState() override { return mState; }
98
99 // compositionengine::impl::OutputLayer overrides
dumpStateandroid::compositionengine::__anon045ea7a70111::OutputLayerTest::OutputLayer100 void dumpState(std::string& out) const override { mState.dump(out); }
101
102 const compositionengine::Output& mOutput;
103 compositionengine::LayerFE& mLayerFE;
104 impl::OutputLayerCompositionState mState;
105 };
106
OutputLayerTestandroid::compositionengine::__anon045ea7a70111::OutputLayerTest107 OutputLayerTest() {
108 ON_CALL(mLayerFE, getDebugName()).WillByDefault(Return("Test LayerFE"));
109 ON_CALL(mOutput, getName()).WillByDefault(ReturnRef(kOutputName));
110
111 ON_CALL(mLayerFE, getCompositionState()).WillByDefault(Return(&mLayerFEState));
112 ON_CALL(mOutput, getState()).WillByDefault(ReturnRef(mOutputState));
113 }
114
115 NiceMock<compositionengine::mock::Output> mOutput;
116 sp<NiceMock<compositionengine::mock::LayerFE>> mLayerFE_ =
117 sp<NiceMock<compositionengine::mock::LayerFE>>::make();
118 NiceMock<compositionengine::mock::LayerFE>& mLayerFE = *mLayerFE_;
119 OutputLayer mOutputLayer{mOutput, mLayerFE};
120
121 LayerFECompositionState mLayerFEState;
122 impl::OutputCompositionState mOutputState;
123 };
124
125 /*
126 * Basic construction
127 */
128
TEST_F(OutputLayerTest,canInstantiateOutputLayer)129 TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
130
131 /*
132 * OutputLayer::setHwcLayer()
133 */
134
TEST_F(OutputLayerTest,settingNullHwcLayerSetsEmptyHwcState)135 TEST_F(OutputLayerTest, settingNullHwcLayerSetsEmptyHwcState) {
136 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
137
138 mOutputLayer.setHwcLayer(nullptr);
139
140 EXPECT_FALSE(mOutputLayer.getState().hwc);
141 }
142
TEST_F(OutputLayerTest,settingHwcLayerSetsHwcState)143 TEST_F(OutputLayerTest, settingHwcLayerSetsHwcState) {
144 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
145
146 mOutputLayer.setHwcLayer(hwcLayer);
147
148 const auto& outputLayerState = mOutputLayer.getState();
149 ASSERT_TRUE(outputLayerState.hwc);
150
151 const auto& hwcState = *outputLayerState.hwc;
152 EXPECT_EQ(hwcLayer, hwcState.hwcLayer);
153 }
154
155 /*
156 * OutputLayer::calculateOutputSourceCrop()
157 */
158
159 struct OutputLayerSourceCropTest : public OutputLayerTest {
OutputLayerSourceCropTestandroid::compositionengine::__anon045ea7a70111::OutputLayerSourceCropTest160 OutputLayerSourceCropTest() {
161 // Set reasonable default values for a simple case. Each test will
162 // set one specific value to something different.
163 mLayerFEState.geomUsesSourceCrop = true;
164 mLayerFEState.geomContentCrop = Rect{0, 0, 1920, 1080};
165 mLayerFEState.transparentRegionHint = Region{};
166 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
167 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
168 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
169 mLayerFEState.geomBufferTransform = TR_IDENT;
170
171 mOutputState.layerStackSpace.setContent(Rect{0, 0, 1920, 1080});
172 }
173
calculateOutputSourceCropandroid::compositionengine::__anon045ea7a70111::OutputLayerSourceCropTest174 FloatRect calculateOutputSourceCrop() {
175 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
176
177 return mOutputLayer.calculateOutputSourceCrop(ui::Transform::RotationFlags::ROT_0);
178 }
179 };
180
TEST_F(OutputLayerSourceCropTest,computesEmptyIfSourceCropNotUsed)181 TEST_F(OutputLayerSourceCropTest, computesEmptyIfSourceCropNotUsed) {
182 mLayerFEState.geomUsesSourceCrop = false;
183
184 const FloatRect expected{};
185 EXPECT_THAT(calculateOutputSourceCrop(), expected);
186 }
187
TEST_F(OutputLayerSourceCropTest,correctForSimpleDefaultCase)188 TEST_F(OutputLayerSourceCropTest, correctForSimpleDefaultCase) {
189 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
190 EXPECT_THAT(calculateOutputSourceCrop(), expected);
191 }
192
TEST_F(OutputLayerSourceCropTest,handlesBoundsOutsideViewport)193 TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewport) {
194 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
195
196 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
197 EXPECT_THAT(calculateOutputSourceCrop(), expected);
198 }
199
TEST_F(OutputLayerSourceCropTest,handlesBoundsOutsideViewportRotated)200 TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewportRotated) {
201 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
202 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
203
204 const FloatRect expected{0.f, 0.f, 1080.f, 1080.f};
205 EXPECT_THAT(calculateOutputSourceCrop(), expected);
206 }
207
TEST_F(OutputLayerSourceCropTest,calculateOutputSourceCropWorksWithATransformedBuffer)208 TEST_F(OutputLayerSourceCropTest, calculateOutputSourceCropWorksWithATransformedBuffer) {
209 struct Entry {
210 uint32_t bufferInvDisplay;
211 uint32_t buffer;
212 uint32_t display;
213 FloatRect expected;
214 };
215 // Not an exhaustive list of cases, but hopefully enough.
216 const std::array<Entry, 12> testData = {
217 // clang-format off
218 // inv buffer display expected
219 /* 0 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
220 /* 1 */ Entry{false, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
221 /* 2 */ Entry{false, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
222 /* 3 */ Entry{false, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
223
224 /* 4 */ Entry{true, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
225 /* 5 */ Entry{true, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
226 /* 6 */ Entry{true, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
227 /* 7 */ Entry{true, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
228
229 /* 8 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
230 /* 9 */ Entry{false, TR_ROT_90, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
231 /* 10 */ Entry{false, TR_ROT_180, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
232 /* 11 */ Entry{false, TR_ROT_270, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
233
234 // clang-format on
235 };
236
237 for (size_t i = 0; i < testData.size(); i++) {
238 const auto& entry = testData[i];
239
240 mLayerFEState.geomBufferUsesDisplayInverseTransform = entry.bufferInvDisplay;
241 mLayerFEState.geomBufferTransform = entry.buffer;
242 mOutputState.displaySpace.setOrientation(toRotation(entry.display));
243
244 EXPECT_THAT(calculateOutputSourceCrop(), entry.expected) << "entry " << i;
245 }
246 }
247
TEST_F(OutputLayerSourceCropTest,geomContentCropAffectsCrop)248 TEST_F(OutputLayerSourceCropTest, geomContentCropAffectsCrop) {
249 mLayerFEState.geomContentCrop = Rect{0, 0, 960, 540};
250
251 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
252 EXPECT_THAT(calculateOutputSourceCrop(), expected);
253 }
254
TEST_F(OutputLayerSourceCropTest,viewportAffectsCrop)255 TEST_F(OutputLayerSourceCropTest, viewportAffectsCrop) {
256 mOutputState.layerStackSpace.setContent(Rect{0, 0, 960, 540});
257
258 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
259 EXPECT_THAT(calculateOutputSourceCrop(), expected);
260 }
261
262 /*
263 * OutputLayer::calculateOutputDisplayFrame()
264 */
265
266 struct OutputLayerDisplayFrameTest : public OutputLayerTest {
OutputLayerDisplayFrameTestandroid::compositionengine::__anon045ea7a70111::OutputLayerDisplayFrameTest267 OutputLayerDisplayFrameTest() {
268 // Set reasonable default values for a simple case. Each test will
269 // set one specific value to something different.
270
271 mLayerFEState.transparentRegionHint = Region{};
272 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
273 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
274 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
275 mLayerFEState.geomCrop = FloatRect{0, 0, 1920, 1080};
276 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
277
278 mOutputState.layerStackSpace.setContent(Rect{0, 0, 1920, 1080});
279 mOutputState.transform = ui::Transform{TR_IDENT};
280 }
281
calculateOutputDisplayFrameandroid::compositionengine::__anon045ea7a70111::OutputLayerDisplayFrameTest282 Rect calculateOutputDisplayFrame() {
283 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
284
285 return mOutputLayer.calculateOutputDisplayFrame();
286 }
287 };
288
TEST_F(OutputLayerDisplayFrameTest,correctForSimpleDefaultCase)289 TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
290 const Rect expected{0, 0, 1920, 1080};
291 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
292 }
293
TEST_F(OutputLayerDisplayFrameTest,fullActiveTransparentRegionReturnsEmptyFrame)294 TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
295 mLayerFEState.transparentRegionHint = Region{Rect{0, 0, 1920, 1080}};
296 const Rect expected{0, 0, 0, 0};
297 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
298 }
299
TEST_F(OutputLayerDisplayFrameTest,cropAffectsDisplayFrame)300 TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
301 mLayerFEState.geomCrop = FloatRect{100, 200, 300, 500};
302 const Rect expected{100, 200, 300, 500};
303 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
304 }
305
TEST_F(OutputLayerDisplayFrameTest,cropAffectsDisplayFrameRotated)306 TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
307 mLayerFEState.geomCrop = FloatRect{100, 200, 300, 500};
308 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
309 const Rect expected{1420, 100, 1720, 300};
310 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
311 }
312
TEST_F(OutputLayerDisplayFrameTest,emptyGeomCropIsNotUsedToComputeFrame)313 TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
314 mLayerFEState.geomCrop = FloatRect{};
315 const Rect expected{0, 0, 1920, 1080};
316 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
317 }
318
TEST_F(OutputLayerDisplayFrameTest,geomLayerBoundsAffectsFrame)319 TEST_F(OutputLayerDisplayFrameTest, geomLayerBoundsAffectsFrame) {
320 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
321 const Rect expected{0, 0, 960, 540};
322 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
323 }
324
TEST_F(OutputLayerDisplayFrameTest,viewportAffectsFrame)325 TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
326 mOutputState.layerStackSpace.setContent(Rect{0, 0, 960, 540});
327 const Rect expected{0, 0, 960, 540};
328 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
329 }
330
TEST_F(OutputLayerDisplayFrameTest,outputTransformAffectsDisplayFrame)331 TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
332 mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
333 const Rect expected{-1080, 0, 0, 1920};
334 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
335 }
336
TEST_F(OutputLayerDisplayFrameTest,shadowExpandsDisplayFrame)337 TEST_F(OutputLayerDisplayFrameTest, shadowExpandsDisplayFrame) {
338 const int kShadowRadius = 5;
339 mLayerFEState.shadowSettings.length = kShadowRadius;
340 mLayerFEState.forceClientComposition = true;
341
342 mLayerFEState.geomLayerBounds = FloatRect{100.f, 100.f, 200.f, 200.f};
343 Rect expected{mLayerFEState.geomLayerBounds};
344 expected.inset(-2 * kShadowRadius, -2 * kShadowRadius, -2 * kShadowRadius, -2 * kShadowRadius);
345 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
346 }
347
TEST_F(OutputLayerDisplayFrameTest,shadowExpandsDisplayFrame_onlyIfForcingClientComposition)348 TEST_F(OutputLayerDisplayFrameTest, shadowExpandsDisplayFrame_onlyIfForcingClientComposition) {
349 const int kShadowRadius = 5;
350 mLayerFEState.shadowSettings.length = kShadowRadius;
351 mLayerFEState.forceClientComposition = false;
352
353 mLayerFEState.geomLayerBounds = FloatRect{100.f, 100.f, 200.f, 200.f};
354 Rect expected{mLayerFEState.geomLayerBounds};
355 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
356 }
357
358 /*
359 * OutputLayer::calculateOutputRelativeBufferTransform()
360 */
361
TEST_F(OutputLayerTest,calculateOutputRelativeBufferTransformTestsNeeded)362 TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
363 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
364
365 struct Entry {
366 uint32_t layer;
367 uint32_t buffer;
368 uint32_t display;
369 uint32_t expected;
370 };
371 // Not an exhaustive list of cases, but hopefully enough.
372 const std::array<Entry, 24> testData = {
373 // clang-format off
374 // layer buffer display expected
375 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
376 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_90},
377 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
378 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270},
379
380 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_IDENT},
381 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_90},
382 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
383 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
384
385 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
386 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_180},
387 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
388 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_180},
389
390 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_90},
391 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_180},
392 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT ^ TR_ROT_270},
393 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_IDENT},
394
395 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_ROT_180},
396 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT ^ TR_ROT_270},
397 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_IDENT},
398 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_90},
399
400 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_270},
401 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_IDENT},
402 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
403 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_180},
404 // clang-format on
405 };
406
407 for (size_t i = 0; i < testData.size(); i++) {
408 const auto& entry = testData[i];
409
410 mLayerFEState.geomLayerTransform.set(entry.layer, 1920, 1080);
411 mLayerFEState.geomBufferTransform = entry.buffer;
412 mOutputState.displaySpace.setOrientation(toRotation(entry.display));
413 mOutputState.transform = ui::Transform{entry.display};
414
415 const auto actual = mOutputLayer.calculateOutputRelativeBufferTransform(entry.display);
416 EXPECT_EQ(entry.expected, actual) << "entry " << i;
417 }
418 }
419
TEST_F(OutputLayerTest,calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform)420 TEST_F(OutputLayerTest,
421 calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform) {
422 mLayerFEState.geomBufferUsesDisplayInverseTransform = true;
423
424 struct Entry {
425 uint32_t layer; /* shouldn't affect the result, so we just use arbitrary values */
426 uint32_t buffer;
427 uint32_t display;
428 uint32_t internal;
429 uint32_t expected;
430 };
431 const std::array<Entry, 64> testData = {
432 // clang-format off
433 // layer buffer display internal expected
434 Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
435 Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_270},
436 Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
437 Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_90},
438
439 Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_IDENT, TR_ROT_90},
440 Entry{TR_ROT_90, TR_IDENT, TR_ROT_90, TR_ROT_90, TR_IDENT},
441 Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_ROT_180, TR_ROT_270},
442 Entry{TR_ROT_90, TR_IDENT, TR_ROT_90, TR_ROT_270, TR_ROT_180},
443
444 Entry{TR_ROT_180, TR_IDENT, TR_ROT_180, TR_IDENT, TR_ROT_180},
445 Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_ROT_90, TR_ROT_90},
446 Entry{TR_ROT_180, TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
447 Entry{TR_ROT_270, TR_IDENT, TR_ROT_180, TR_ROT_270, TR_ROT_270},
448
449 Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT, TR_ROT_270},
450 Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_ROT_90, TR_ROT_180},
451 Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_ROT_180, TR_ROT_90},
452 Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270, TR_IDENT},
453
454 // layer buffer display internal expected
455 Entry{TR_IDENT, TR_ROT_90, TR_IDENT, TR_IDENT, TR_ROT_90},
456 Entry{TR_ROT_90, TR_ROT_90, TR_IDENT, TR_ROT_90, TR_IDENT},
457 Entry{TR_ROT_180, TR_ROT_90, TR_IDENT, TR_ROT_180, TR_ROT_270},
458 Entry{TR_ROT_270, TR_ROT_90, TR_IDENT, TR_ROT_270, TR_ROT_180},
459
460 Entry{TR_ROT_90, TR_ROT_90, TR_ROT_90, TR_IDENT, TR_ROT_180},
461 Entry{TR_ROT_90, TR_ROT_90, TR_ROT_90, TR_ROT_90, TR_ROT_90},
462 Entry{TR_ROT_90, TR_ROT_90, TR_ROT_90, TR_ROT_180, TR_IDENT},
463 Entry{TR_ROT_270, TR_ROT_90, TR_ROT_90, TR_ROT_270, TR_ROT_270},
464
465 Entry{TR_IDENT, TR_ROT_90, TR_ROT_180, TR_IDENT, TR_ROT_270},
466 Entry{TR_ROT_90, TR_ROT_90, TR_ROT_180, TR_ROT_90, TR_ROT_180},
467 Entry{TR_ROT_180, TR_ROT_90, TR_ROT_180, TR_ROT_180, TR_ROT_90},
468 Entry{TR_ROT_90, TR_ROT_90, TR_ROT_180, TR_ROT_270, TR_IDENT},
469
470 Entry{TR_IDENT, TR_ROT_90, TR_ROT_270, TR_IDENT, TR_IDENT},
471 Entry{TR_ROT_270, TR_ROT_90, TR_ROT_270, TR_ROT_90, TR_ROT_270},
472 Entry{TR_ROT_180, TR_ROT_90, TR_ROT_270, TR_ROT_180, TR_ROT_180},
473 Entry{TR_ROT_270, TR_ROT_90, TR_ROT_270, TR_ROT_270, TR_ROT_90},
474
475 // layer buffer display internal expected
476 Entry{TR_IDENT, TR_ROT_180, TR_IDENT, TR_IDENT, TR_ROT_180},
477 Entry{TR_IDENT, TR_ROT_180, TR_IDENT, TR_ROT_90, TR_ROT_90},
478 Entry{TR_ROT_180, TR_ROT_180, TR_IDENT, TR_ROT_180, TR_IDENT},
479 Entry{TR_ROT_270, TR_ROT_180, TR_IDENT, TR_ROT_270, TR_ROT_270},
480
481 Entry{TR_IDENT, TR_ROT_180, TR_ROT_90, TR_IDENT, TR_ROT_270},
482 Entry{TR_ROT_90, TR_ROT_180, TR_ROT_90, TR_ROT_90, TR_ROT_180},
483 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_90, TR_ROT_180, TR_ROT_90},
484 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_90, TR_ROT_270, TR_IDENT},
485
486 Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT, TR_IDENT},
487 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_180, TR_ROT_90, TR_ROT_270},
488 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_180, TR_ROT_180, TR_ROT_180},
489 Entry{TR_ROT_270, TR_ROT_180, TR_ROT_180, TR_ROT_270, TR_ROT_90},
490
491 Entry{TR_ROT_270, TR_ROT_180, TR_ROT_270, TR_IDENT, TR_ROT_90},
492 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_270, TR_ROT_90, TR_IDENT},
493 Entry{TR_ROT_180, TR_ROT_180, TR_ROT_270, TR_ROT_180, TR_ROT_270},
494 Entry{TR_ROT_270, TR_ROT_180, TR_ROT_270, TR_ROT_270, TR_ROT_180},
495
496 // layer buffer display internal expected
497 Entry{TR_IDENT, TR_ROT_270, TR_IDENT, TR_IDENT, TR_ROT_270},
498 Entry{TR_ROT_90, TR_ROT_270, TR_IDENT, TR_ROT_90, TR_ROT_180},
499 Entry{TR_ROT_270, TR_ROT_270, TR_IDENT, TR_ROT_180, TR_ROT_90},
500 Entry{TR_IDENT, TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT},
501
502 Entry{TR_ROT_270, TR_ROT_270, TR_ROT_90, TR_IDENT, TR_IDENT},
503 Entry{TR_ROT_90, TR_ROT_270, TR_ROT_90, TR_ROT_90, TR_ROT_270},
504 Entry{TR_ROT_180, TR_ROT_270, TR_ROT_90, TR_ROT_180, TR_ROT_180},
505 Entry{TR_ROT_90, TR_ROT_270, TR_ROT_90, TR_ROT_270, TR_ROT_90},
506
507 Entry{TR_IDENT, TR_ROT_270, TR_ROT_180, TR_IDENT, TR_ROT_90},
508 Entry{TR_ROT_270, TR_ROT_270, TR_ROT_180, TR_ROT_90, TR_IDENT},
509 Entry{TR_ROT_180, TR_ROT_270, TR_ROT_180, TR_ROT_180, TR_ROT_270},
510 Entry{TR_ROT_270, TR_ROT_270, TR_ROT_180, TR_ROT_270, TR_ROT_180},
511
512 Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_IDENT, TR_ROT_180},
513 Entry{TR_ROT_90, TR_ROT_270, TR_ROT_270, TR_ROT_90, TR_ROT_90},
514 Entry{TR_ROT_270, TR_ROT_270, TR_ROT_270, TR_ROT_180, TR_IDENT},
515 Entry{TR_ROT_270, TR_ROT_270, TR_ROT_270, TR_ROT_270, TR_ROT_270},
516 // clang-format on
517 };
518
519 for (size_t i = 0; i < testData.size(); i++) {
520 const auto& entry = testData[i];
521
522 mLayerFEState.geomLayerTransform.set(entry.layer, 1920, 1080);
523 mLayerFEState.geomBufferTransform = entry.buffer;
524 mOutputState.displaySpace.setOrientation(toRotation(entry.display));
525 mOutputState.transform = ui::Transform{entry.display};
526
527 const auto actual = mOutputLayer.calculateOutputRelativeBufferTransform(entry.internal);
528 EXPECT_EQ(entry.expected, actual) << "entry " << i;
529 }
530 }
531
532 /*
533 * OutputLayer::updateCompositionState()
534 */
535
536 struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
OutputLayerPartialMockForUpdateCompositionStateandroid::compositionengine::__anon045ea7a70111::OutputLayerPartialMockForUpdateCompositionState537 OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
538 compositionengine::LayerFE& layerFE)
539 : mOutput(output), mLayerFE(layerFE) {}
540 // Mock everything called by updateCompositionState to simplify testing it.
541 MOCK_CONST_METHOD1(calculateOutputSourceCrop, FloatRect(uint32_t));
542 MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
543 MOCK_CONST_METHOD1(calculateOutputRelativeBufferTransform, uint32_t(uint32_t));
544
545 // compositionengine::OutputLayer overrides
getOutputandroid::compositionengine::__anon045ea7a70111::OutputLayerPartialMockForUpdateCompositionState546 const compositionengine::Output& getOutput() const override { return mOutput; }
getLayerFEandroid::compositionengine::__anon045ea7a70111::OutputLayerPartialMockForUpdateCompositionState547 compositionengine::LayerFE& getLayerFE() const override { return mLayerFE; }
getStateandroid::compositionengine::__anon045ea7a70111::OutputLayerPartialMockForUpdateCompositionState548 const impl::OutputLayerCompositionState& getState() const override { return mState; }
editStateandroid::compositionengine::__anon045ea7a70111::OutputLayerPartialMockForUpdateCompositionState549 impl::OutputLayerCompositionState& editState() override { return mState; }
550
551 // These need implementations though are not expected to be called.
552 MOCK_CONST_METHOD1(dumpState, void(std::string&));
553
554 const compositionengine::Output& mOutput;
555 compositionengine::LayerFE& mLayerFE;
556 impl::OutputLayerCompositionState mState;
557 };
558
559 struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
560 public:
OutputLayerUpdateCompositionStateTestandroid::compositionengine::__anon045ea7a70111::OutputLayerUpdateCompositionStateTest561 OutputLayerUpdateCompositionStateTest() {
562 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
563 EXPECT_CALL(mOutput, getDisplayColorProfile())
564 .WillRepeatedly(Return(&mDisplayColorProfile));
565 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(true));
566 }
567
568 ~OutputLayerUpdateCompositionStateTest() = default;
569
setupGeometryChildCallValuesandroid::compositionengine::__anon045ea7a70111::OutputLayerUpdateCompositionStateTest570 void setupGeometryChildCallValues(ui::Transform::RotationFlags internalDisplayRotationFlags) {
571 EXPECT_CALL(mOutputLayer, calculateOutputSourceCrop(internalDisplayRotationFlags))
572 .WillOnce(Return(kSourceCrop));
573 EXPECT_CALL(mOutputLayer, calculateOutputDisplayFrame()).WillOnce(Return(kDisplayFrame));
574 EXPECT_CALL(mOutputLayer,
575 calculateOutputRelativeBufferTransform(internalDisplayRotationFlags))
576 .WillOnce(Return(mBufferTransform));
577 }
578
validateComputedGeometryStateandroid::compositionengine::__anon045ea7a70111::OutputLayerUpdateCompositionStateTest579 void validateComputedGeometryState() {
580 const auto& state = mOutputLayer.getState();
581 EXPECT_EQ(kSourceCrop, state.sourceCrop);
582 EXPECT_EQ(kDisplayFrame, state.displayFrame);
583 EXPECT_EQ(static_cast<Hwc2::Transform>(mBufferTransform), state.bufferTransform);
584 }
585
586 const FloatRect kSourceCrop{1.f, 2.f, 3.f, 4.f};
587 const Rect kDisplayFrame{11, 12, 13, 14};
588 uint32_t mBufferTransform{21};
589
590 using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
591 StrictMock<OutputLayer> mOutputLayer{mOutput, mLayerFE};
592 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
593 };
594
TEST_F(OutputLayerUpdateCompositionStateTest,doesNothingIfNoFECompositionState)595 TEST_F(OutputLayerUpdateCompositionStateTest, doesNothingIfNoFECompositionState) {
596 EXPECT_CALL(mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
597
598 mOutputLayer.updateCompositionState(true, false, ui::Transform::RotationFlags::ROT_90);
599 }
600
TEST_F(OutputLayerUpdateCompositionStateTest,setsStateNormally)601 TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
602 mLayerFEState.isSecure = true;
603 mOutputState.isSecure = true;
604 mOutputLayer.editState().forceClientComposition = true;
605
606 setupGeometryChildCallValues(ui::Transform::RotationFlags::ROT_90);
607
608 mOutputLayer.updateCompositionState(true, false, ui::Transform::RotationFlags::ROT_90);
609
610 validateComputedGeometryState();
611
612 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
613 }
614
TEST_F(OutputLayerUpdateCompositionStateTest,alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput)615 TEST_F(OutputLayerUpdateCompositionStateTest,
616 alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput) {
617 mLayerFEState.isSecure = true;
618 mOutputState.isSecure = false;
619
620 setupGeometryChildCallValues(ui::Transform::RotationFlags::ROT_0);
621
622 mOutputLayer.updateCompositionState(true, false, ui::Transform::RotationFlags::ROT_0);
623
624 validateComputedGeometryState();
625
626 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
627 }
628
TEST_F(OutputLayerUpdateCompositionStateTest,alsoSetsForceCompositionIfUnsupportedBufferTransform)629 TEST_F(OutputLayerUpdateCompositionStateTest,
630 alsoSetsForceCompositionIfUnsupportedBufferTransform) {
631 mLayerFEState.isSecure = true;
632 mOutputState.isSecure = true;
633
634 mBufferTransform = ui::Transform::ROT_INVALID;
635
636 setupGeometryChildCallValues(ui::Transform::RotationFlags::ROT_0);
637
638 mOutputLayer.updateCompositionState(true, false, ui::Transform::RotationFlags::ROT_0);
639
640 validateComputedGeometryState();
641
642 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
643 }
644
TEST_F(OutputLayerUpdateCompositionStateTest,setsOutputLayerColorspaceCorrectly)645 TEST_F(OutputLayerUpdateCompositionStateTest, setsOutputLayerColorspaceCorrectly) {
646 mLayerFEState.dataspace = ui::Dataspace::DISPLAY_P3;
647 mOutputState.dataspace = ui::Dataspace::V0_SCRGB;
648
649 // If the layer is not colorspace agnostic, the output layer dataspace
650 // should use the layers requested colorspace.
651 mLayerFEState.isColorspaceAgnostic = false;
652
653 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
654
655 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutputLayer.getState().dataspace);
656
657 // If the layer is colorspace agnostic, the output layer dataspace
658 // should use the colorspace chosen for the whole output.
659 mLayerFEState.isColorspaceAgnostic = true;
660
661 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
662
663 EXPECT_EQ(ui::Dataspace::V0_SCRGB, mOutputLayer.getState().dataspace);
664
665 // If the output is HDR, then don't blind the user with a colorspace agnostic dataspace
666 // drawing all white
667 mOutputState.dataspace = ui::Dataspace::BT2020_PQ;
668
669 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
670
671 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutputLayer.getState().dataspace);
672 }
673
TEST_F(OutputLayerUpdateCompositionStateTest,setsOutputLayerColorspaceWith170mReplacement)674 TEST_F(OutputLayerUpdateCompositionStateTest, setsOutputLayerColorspaceWith170mReplacement) {
675 mLayerFEState.dataspace = ui::Dataspace::TRANSFER_SMPTE_170M;
676 mOutputState.treat170mAsSrgb = false;
677 mLayerFEState.isColorspaceAgnostic = false;
678
679 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
680
681 EXPECT_EQ(ui::Dataspace::TRANSFER_SMPTE_170M, mOutputLayer.getState().dataspace);
682
683 // Rewrite SMPTE 170M as sRGB
684 mOutputState.treat170mAsSrgb = true;
685 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
686
687 EXPECT_EQ(ui::Dataspace::TRANSFER_SRGB, mOutputLayer.getState().dataspace);
688 }
689
TEST_F(OutputLayerUpdateCompositionStateTest,setsWhitePointNitsAndDimmingRatioCorrectly)690 TEST_F(OutputLayerUpdateCompositionStateTest, setsWhitePointNitsAndDimmingRatioCorrectly) {
691 mOutputState.sdrWhitePointNits = 200.f;
692 mOutputState.displayBrightnessNits = 800.f;
693
694 mLayerFEState.dataspace = ui::Dataspace::DISPLAY_P3;
695 mLayerFEState.isColorspaceAgnostic = false;
696 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
697 EXPECT_EQ(mOutputState.sdrWhitePointNits, mOutputLayer.getState().whitePointNits);
698 EXPECT_EQ(mOutputState.sdrWhitePointNits / mOutputState.displayBrightnessNits,
699 mOutputLayer.getState().dimmingRatio);
700
701 mLayerFEState.dimmingEnabled = false;
702 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
703 EXPECT_EQ(mOutputState.displayBrightnessNits, mOutputLayer.getState().whitePointNits);
704 EXPECT_EQ(1.f, mOutputLayer.getState().dimmingRatio);
705
706 // change dimmingEnabled back to true.
707 mLayerFEState.dimmingEnabled = true;
708 mLayerFEState.dataspace = ui::Dataspace::BT2020_ITU_PQ;
709 mLayerFEState.isColorspaceAgnostic = false;
710 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
711
712 EXPECT_EQ(mOutputState.displayBrightnessNits, mOutputLayer.getState().whitePointNits);
713 EXPECT_EQ(1.f, mOutputLayer.getState().dimmingRatio);
714 }
715
TEST_F(OutputLayerUpdateCompositionStateTest,doesNotRecomputeGeometryIfNotRequested)716 TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
717 mOutputLayer.editState().forceClientComposition = false;
718
719 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
720
721 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
722 }
723
TEST_F(OutputLayerUpdateCompositionStateTest,doesNotClearForceClientCompositionIfNotDoingGeometry)724 TEST_F(OutputLayerUpdateCompositionStateTest,
725 doesNotClearForceClientCompositionIfNotDoingGeometry) {
726 mOutputLayer.editState().forceClientComposition = true;
727
728 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
729
730 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
731 }
732
TEST_F(OutputLayerUpdateCompositionStateTest,clientCompositionForcedFromFrontEndFlagAtAnyTime)733 TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromFrontEndFlagAtAnyTime) {
734 mLayerFEState.forceClientComposition = true;
735 mOutputLayer.editState().forceClientComposition = false;
736
737 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
738
739 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
740 }
741
TEST_F(OutputLayerUpdateCompositionStateTest,clientCompositionForcedFromUnsupportedDataspaceAtAnyTime)742 TEST_F(OutputLayerUpdateCompositionStateTest,
743 clientCompositionForcedFromUnsupportedDataspaceAtAnyTime) {
744 mOutputLayer.editState().forceClientComposition = false;
745 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(false));
746
747 mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
748
749 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
750 }
751
TEST_F(OutputLayerUpdateCompositionStateTest,clientCompositionForcedFromArgumentFlag)752 TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromArgumentFlag) {
753 mLayerFEState.forceClientComposition = false;
754 mOutputLayer.editState().forceClientComposition = false;
755
756 mOutputLayer.updateCompositionState(false, true, ui::Transform::RotationFlags::ROT_0);
757
758 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
759
760 mOutputLayer.editState().forceClientComposition = false;
761
762 setupGeometryChildCallValues(ui::Transform::RotationFlags::ROT_0);
763
764 mOutputLayer.updateCompositionState(true, true, ui::Transform::RotationFlags::ROT_0);
765
766 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
767 }
768
769 /*
770 * OutputLayer::writeStateToHWC()
771 */
772
773 struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
774 static constexpr hal::Error kError = hal::Error::UNSUPPORTED;
775 static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
776 static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
777 static constexpr Hwc2::Transform kOverrideBufferTransform = static_cast<Hwc2::Transform>(0);
778 static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
779 static_cast<Hwc2::IComposerClient::BlendMode>(41);
780 static constexpr Hwc2::IComposerClient::BlendMode kOverrideBlendMode =
781 Hwc2::IComposerClient::BlendMode::PREMULTIPLIED;
782 static constexpr float kAlpha = 51.f;
783 static constexpr float kOverrideAlpha = 1.f;
784 static constexpr float kSkipAlpha = 0.f;
785 static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
786 static constexpr ui::Dataspace kOverrideDataspace = static_cast<ui::Dataspace>(72);
787 static constexpr int kSupportedPerFrameMetadata = 101;
788 static constexpr int kExpectedHwcSlot = 0;
789 static constexpr int kOverrideHwcSlot = impl::HwcBufferCache::kOverrideBufferSlot;
790 static constexpr bool kLayerGenericMetadata1Mandatory = true;
791 static constexpr bool kLayerGenericMetadata2Mandatory = true;
792 static constexpr float kWhitePointNits = 200.f;
793 static constexpr float kSdrWhitePointNits = 100.f;
794 static constexpr float kDisplayBrightnessNits = 400.f;
795 static constexpr float kLayerBrightness = kWhitePointNits / kDisplayBrightnessNits;
796 static constexpr float kOverrideLayerBrightness = kSdrWhitePointNits / kDisplayBrightnessNits;
797
798 static const half4 kColor;
799 static const Rect kDisplayFrame;
800 static const Rect kOverrideDisplayFrame;
801 static const FloatRect kOverrideSourceCrop;
802 static const Region kOutputSpaceVisibleRegion;
803 static const Region kOverrideVisibleRegion;
804 static const mat4 kColorTransform;
805 static const Region kSurfaceDamage;
806 static const Region kOverrideSurfaceDamage;
807 static const HdrMetadata kHdrMetadata;
808 static native_handle_t* kSidebandStreamHandle;
809 static const sp<GraphicBuffer> kBuffer;
810 static const sp<GraphicBuffer> kOverrideBuffer;
811 static const sp<Fence> kFence;
812 static const sp<Fence> kOverrideFence;
813 static const std::string kLayerGenericMetadata1Key;
814 static const std::vector<uint8_t> kLayerGenericMetadata1Value;
815 static const std::string kLayerGenericMetadata2Key;
816 static const std::vector<uint8_t> kLayerGenericMetadata2Value;
817
OutputLayerWriteStateToHWCTestandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest818 OutputLayerWriteStateToHWCTest() {
819 auto& outputLayerState = mOutputLayer.editState();
820 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
821
822 outputLayerState.displayFrame = kDisplayFrame;
823 outputLayerState.sourceCrop = kSourceCrop;
824 outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
825 outputLayerState.outputSpaceVisibleRegion = kOutputSpaceVisibleRegion;
826 outputLayerState.dataspace = kDataspace;
827 outputLayerState.whitePointNits = kWhitePointNits;
828 outputLayerState.dimmingRatio = kLayerBrightness;
829
830 mLayerFEState.blendMode = kBlendMode;
831 mLayerFEState.alpha = kAlpha;
832 mLayerFEState.colorTransform = kColorTransform;
833 mLayerFEState.color = kColor;
834 mLayerFEState.surfaceDamage = kSurfaceDamage;
835 mLayerFEState.hdrMetadata = kHdrMetadata;
836 mLayerFEState.sidebandStream = NativeHandle::create(kSidebandStreamHandle, false);
837 mLayerFEState.buffer = kBuffer;
838 mLayerFEState.acquireFence = kFence;
839
840 mOutputState.displayBrightnessNits = kDisplayBrightnessNits;
841 mOutputState.sdrWhitePointNits = kSdrWhitePointNits;
842
843 EXPECT_CALL(mOutput, getDisplayColorProfile())
844 .WillRepeatedly(Return(&mDisplayColorProfile));
845 EXPECT_CALL(mDisplayColorProfile, getSupportedPerFrameMetadata())
846 .WillRepeatedly(Return(kSupportedPerFrameMetadata));
847 }
848 // Some tests may need to simulate unsupported HWC calls
849 enum class SimulateUnsupported { None, ColorTransform };
850
includeGenericLayerMetadataInStateandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest851 void includeGenericLayerMetadataInState() {
852 mLayerFEState.metadata[kLayerGenericMetadata1Key] = {kLayerGenericMetadata1Mandatory,
853 kLayerGenericMetadata1Value};
854 mLayerFEState.metadata[kLayerGenericMetadata2Key] = {kLayerGenericMetadata2Mandatory,
855 kLayerGenericMetadata2Value};
856 }
857
includeOverrideInfoandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest858 void includeOverrideInfo() {
859 auto& overrideInfo = mOutputLayer.editState().overrideInfo;
860
861 overrideInfo.buffer = std::make_shared<
862 renderengine::impl::ExternalTexture>(kOverrideBuffer, mRenderEngine,
863 renderengine::impl::ExternalTexture::Usage::
864 READABLE |
865 renderengine::impl::ExternalTexture::
866 Usage::WRITEABLE);
867 overrideInfo.acquireFence = kOverrideFence;
868 overrideInfo.displayFrame = kOverrideDisplayFrame;
869 overrideInfo.dataspace = kOverrideDataspace;
870 overrideInfo.damageRegion = kOverrideSurfaceDamage;
871 overrideInfo.visibleRegion = kOverrideVisibleRegion;
872 }
873
expectGeometryCommonCallsandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest874 void expectGeometryCommonCalls(Rect displayFrame = kDisplayFrame,
875 FloatRect sourceCrop = kSourceCrop,
876 Hwc2::Transform bufferTransform = kBufferTransform,
877 Hwc2::IComposerClient::BlendMode blendMode = kBlendMode,
878 float alpha = kAlpha) {
879 EXPECT_CALL(*mHwcLayer, setDisplayFrame(displayFrame)).WillOnce(Return(kError));
880 EXPECT_CALL(*mHwcLayer, setSourceCrop(sourceCrop)).WillOnce(Return(kError));
881 EXPECT_CALL(*mHwcLayer, setZOrder(_)).WillOnce(Return(kError));
882 EXPECT_CALL(*mHwcLayer, setTransform(bufferTransform)).WillOnce(Return(kError));
883
884 EXPECT_CALL(*mHwcLayer, setBlendMode(blendMode)).WillOnce(Return(kError));
885 EXPECT_CALL(*mHwcLayer, setPlaneAlpha(alpha)).WillOnce(Return(kError));
886 }
887
expectPerFrameCommonCallsandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest888 void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None,
889 ui::Dataspace dataspace = kDataspace,
890 const Region& visibleRegion = kOutputSpaceVisibleRegion,
891 const Region& surfaceDamage = kSurfaceDamage,
892 float brightness = kLayerBrightness,
893 const Region& blockingRegion = Region()) {
894 EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(visibleRegion))).WillOnce(Return(kError));
895 EXPECT_CALL(*mHwcLayer, setDataspace(dataspace)).WillOnce(Return(kError));
896 EXPECT_CALL(*mHwcLayer, setBrightness(brightness)).WillOnce(Return(kError));
897 EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
898 .WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
899 ? hal::Error::UNSUPPORTED
900 : hal::Error::NONE));
901 EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(surfaceDamage))).WillOnce(Return(kError));
902 EXPECT_CALL(*mHwcLayer, setBlockingRegion(RegionEq(blockingRegion)))
903 .WillOnce(Return(kError));
904 }
905
expectSetCompositionTypeCallandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest906 void expectSetCompositionTypeCall(Composition compositionType) {
907 EXPECT_CALL(*mHwcLayer, setCompositionType(compositionType)).WillOnce(Return(kError));
908 }
909
expectNoSetCompositionTypeCallandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest910 void expectNoSetCompositionTypeCall() {
911 EXPECT_CALL(*mHwcLayer, setCompositionType(_)).Times(0);
912 }
913
expectSetColorCallandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest914 void expectSetColorCall() {
915 const aidl::android::hardware::graphics::composer3::Color color = {kColor.r, kColor.g,
916 kColor.b, 1.0f};
917
918 EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
919 }
920
expectSetSidebandHandleCallandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest921 void expectSetSidebandHandleCall() {
922 EXPECT_CALL(*mHwcLayer, setSidebandStream(kSidebandStreamHandle));
923 }
924
expectSetHdrMetadataAndBufferCallsandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest925 void expectSetHdrMetadataAndBufferCalls(uint32_t hwcSlot = kExpectedHwcSlot,
926 sp<GraphicBuffer> buffer = kBuffer,
927 sp<Fence> fence = kFence) {
928 EXPECT_CALL(*mHwcLayer, setPerFrameMetadata(kSupportedPerFrameMetadata, kHdrMetadata));
929 EXPECT_CALL(*mHwcLayer, setBuffer(hwcSlot, buffer, fence));
930 }
931
expectGenericLayerMetadataCallsandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteStateToHWCTest932 void expectGenericLayerMetadataCalls() {
933 // Note: Can be in any order.
934 EXPECT_CALL(*mHwcLayer,
935 setLayerGenericMetadata(kLayerGenericMetadata1Key,
936 kLayerGenericMetadata1Mandatory,
937 kLayerGenericMetadata1Value));
938 EXPECT_CALL(*mHwcLayer,
939 setLayerGenericMetadata(kLayerGenericMetadata2Key,
940 kLayerGenericMetadata2Mandatory,
941 kLayerGenericMetadata2Value));
942 }
943
944 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
945 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
946 renderengine::mock::RenderEngine mRenderEngine;
947 };
948
949 const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
950 84.f / 255.f};
951 const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
952 const Rect OutputLayerWriteStateToHWCTest::kOverrideDisplayFrame{1002, 1003, 1004, 20044};
953 const FloatRect OutputLayerWriteStateToHWCTest::kOverrideSourceCrop{0.f, 0.f, 4.f, 5.f};
954 const Region OutputLayerWriteStateToHWCTest::kOutputSpaceVisibleRegion{
955 Rect{1005, 1006, 1007, 1008}};
956 const Region OutputLayerWriteStateToHWCTest::kOverrideVisibleRegion{Rect{1006, 1007, 1008, 1009}};
957 const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{
958 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
959 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
960 };
961 const Region OutputLayerWriteStateToHWCTest::kSurfaceDamage{Rect{1025, 1026, 1027, 1028}};
962 const Region OutputLayerWriteStateToHWCTest::kOverrideSurfaceDamage{Rect{1026, 1027, 1028, 1029}};
963 const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattenable */}, 1029};
964 native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
965 reinterpret_cast<native_handle_t*>(1031);
966 const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer =
967 sp<GraphicBuffer>::make(1, 2, PIXEL_FORMAT_RGBA_8888,
968 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
969 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
970 const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kOverrideBuffer =
971 sp<GraphicBuffer>::make(4, 5, PIXEL_FORMAT_RGBA_8888,
972 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
973 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
974 const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
975 const sp<Fence> OutputLayerWriteStateToHWCTest::kOverrideFence = sp<Fence>::make();
976 const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
977 "com.example.metadata.1";
978 const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Value{{1, 2, 3}};
979 const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Key =
980 "com.example.metadata.2";
981 const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Value{
982 {4, 5, 6, 7}};
983
TEST_F(OutputLayerWriteStateToHWCTest,doesNothingIfNoFECompositionState)984 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoFECompositionState) {
985 EXPECT_CALL(mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
986
987 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
988 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
989 }
990
TEST_F(OutputLayerWriteStateToHWCTest,doesNothingIfNoHWCState)991 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
992 mOutputLayer.editState().hwc.reset();
993
994 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
995 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
996 }
997
TEST_F(OutputLayerWriteStateToHWCTest,doesNothingIfNoHWCLayer)998 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
999 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
1000
1001 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1002 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1003 }
1004
TEST_F(OutputLayerWriteStateToHWCTest,canSetAllState)1005 TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) {
1006 expectGeometryCommonCalls();
1007 expectPerFrameCommonCalls();
1008
1009 expectNoSetCompositionTypeCall();
1010 EXPECT_CALL(mLayerFE, hasRoundedCorners()).WillOnce(Return(false));
1011
1012 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1013 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1014 }
1015
TEST_F(OutputLayerTest,displayInstallOrientationBufferTransformSetTo90)1016 TEST_F(OutputLayerTest, displayInstallOrientationBufferTransformSetTo90) {
1017 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
1018 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
1019 // This test simulates a scenario where displayInstallOrientation is set to
1020 // ROT_90. This only has an effect on the transform; orientation stays 0 (see
1021 // DisplayDevice::setProjection).
1022 mOutputState.displaySpace.setOrientation(ui::ROTATION_0);
1023 mOutputState.transform = ui::Transform{TR_ROT_90};
1024 // Buffers are pre-rotated based on the transform hint (ROT_90); their
1025 // geomBufferTransform is set to the inverse transform.
1026 mLayerFEState.geomBufferTransform = TR_ROT_270;
1027
1028 EXPECT_EQ(TR_IDENT, mOutputLayer.calculateOutputRelativeBufferTransform(ui::Transform::ROT_90));
1029 }
1030
TEST_F(OutputLayerWriteStateToHWCTest,canSetPerFrameStateForSolidColor)1031 TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSolidColor) {
1032 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1033
1034 expectPerFrameCommonCalls();
1035
1036 // Setting the composition type should happen before setting the color. We
1037 // check this in this test only by setting up an testing::InSeqeuence
1038 // instance before setting up the two expectations.
1039 InSequence s;
1040 expectSetCompositionTypeCall(Composition::SOLID_COLOR);
1041 expectSetColorCall();
1042
1043 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1044 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1045 }
1046
TEST_F(OutputLayerWriteStateToHWCTest,canSetPerFrameStateForSideband)1047 TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) {
1048 mLayerFEState.compositionType = Composition::SIDEBAND;
1049
1050 expectPerFrameCommonCalls();
1051 expectSetSidebandHandleCall();
1052 expectSetCompositionTypeCall(Composition::SIDEBAND);
1053
1054 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1055 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1056 }
1057
TEST_F(OutputLayerWriteStateToHWCTest,canSetPerFrameStateForCursor)1058 TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) {
1059 mLayerFEState.compositionType = Composition::CURSOR;
1060
1061 expectPerFrameCommonCalls();
1062 expectSetHdrMetadataAndBufferCalls();
1063 expectSetCompositionTypeCall(Composition::CURSOR);
1064
1065 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1066 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1067 }
1068
TEST_F(OutputLayerWriteStateToHWCTest,canSetPerFrameStateForDevice)1069 TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) {
1070 mLayerFEState.compositionType = Composition::DEVICE;
1071
1072 expectPerFrameCommonCalls();
1073 expectSetHdrMetadataAndBufferCalls();
1074 expectSetCompositionTypeCall(Composition::DEVICE);
1075
1076 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1077 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1078 }
1079
TEST_F(OutputLayerWriteStateToHWCTest,compositionTypeIsNotSetIfUnchanged)1080 TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) {
1081 (*mOutputLayer.editState().hwc).hwcCompositionType = Composition::SOLID_COLOR;
1082
1083 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1084
1085 expectPerFrameCommonCalls();
1086 expectSetColorCall();
1087 expectNoSetCompositionTypeCall();
1088
1089 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1090 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1091 }
1092
TEST_F(OutputLayerWriteStateToHWCTest,compositionTypeIsSetToClientIfColorTransformNotSupported)1093 TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransformNotSupported) {
1094 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1095
1096 expectPerFrameCommonCalls(SimulateUnsupported::ColorTransform);
1097 expectSetColorCall();
1098 expectSetCompositionTypeCall(Composition::CLIENT);
1099
1100 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1101 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1102 }
1103
TEST_F(OutputLayerWriteStateToHWCTest,compositionTypeIsSetToClientIfClientCompositionForced)1104 TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompositionForced) {
1105 mOutputLayer.editState().forceClientComposition = true;
1106
1107 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1108
1109 expectPerFrameCommonCalls();
1110 expectSetColorCall();
1111 expectSetCompositionTypeCall(Composition::CLIENT);
1112
1113 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1114 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1115 }
1116
TEST_F(OutputLayerWriteStateToHWCTest,allStateIncludesMetadataIfPresent)1117 TEST_F(OutputLayerWriteStateToHWCTest, allStateIncludesMetadataIfPresent) {
1118 mLayerFEState.compositionType = Composition::DEVICE;
1119 includeGenericLayerMetadataInState();
1120
1121 expectGeometryCommonCalls();
1122 expectPerFrameCommonCalls();
1123 expectSetHdrMetadataAndBufferCalls();
1124 expectGenericLayerMetadataCalls();
1125 expectSetCompositionTypeCall(Composition::DEVICE);
1126
1127 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1128 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1129 }
1130
TEST_F(OutputLayerWriteStateToHWCTest,perFrameStateDoesNotIncludeMetadataIfPresent)1131 TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPresent) {
1132 mLayerFEState.compositionType = Composition::DEVICE;
1133 includeGenericLayerMetadataInState();
1134
1135 expectPerFrameCommonCalls();
1136 expectSetHdrMetadataAndBufferCalls();
1137 expectSetCompositionTypeCall(Composition::DEVICE);
1138
1139 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1140 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1141 }
1142
TEST_F(OutputLayerWriteStateToHWCTest,overriddenSkipLayerDoesNotSendBuffer)1143 TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerDoesNotSendBuffer) {
1144 mLayerFEState.compositionType = Composition::DEVICE;
1145 includeOverrideInfo();
1146
1147 expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
1148 kOverrideBlendMode, kSkipAlpha);
1149 expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
1150 kOverrideSurfaceDamage, kOverrideLayerBrightness);
1151 expectSetHdrMetadataAndBufferCalls();
1152 expectSetCompositionTypeCall(Composition::DEVICE);
1153
1154 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, 0,
1155 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1156 }
1157
TEST_F(OutputLayerWriteStateToHWCTest,overriddenSkipLayerForSolidColorDoesNotSendBuffer)1158 TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerForSolidColorDoesNotSendBuffer) {
1159 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1160 includeOverrideInfo();
1161
1162 expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
1163 kOverrideBlendMode, kSkipAlpha);
1164 expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
1165 kOverrideSurfaceDamage, kOverrideLayerBrightness);
1166 expectSetHdrMetadataAndBufferCalls();
1167 expectSetCompositionTypeCall(Composition::DEVICE);
1168
1169 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, 0,
1170 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1171 }
1172
TEST_F(OutputLayerWriteStateToHWCTest,includesOverrideInfoIfPresent)1173 TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
1174 mLayerFEState.compositionType = Composition::DEVICE;
1175 includeOverrideInfo();
1176
1177 expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
1178 kOverrideBlendMode, kOverrideAlpha);
1179 expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
1180 kOverrideSurfaceDamage, kOverrideLayerBrightness);
1181 expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence);
1182 expectSetCompositionTypeCall(Composition::DEVICE);
1183
1184 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1185 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1186 }
1187
TEST_F(OutputLayerWriteStateToHWCTest,includesOverrideInfoForSolidColorIfPresent)1188 TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoForSolidColorIfPresent) {
1189 mLayerFEState.compositionType = Composition::SOLID_COLOR;
1190 includeOverrideInfo();
1191
1192 expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
1193 kOverrideBlendMode, kOverrideAlpha);
1194 expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
1195 kOverrideSurfaceDamage, kOverrideLayerBrightness);
1196 expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence);
1197 expectSetCompositionTypeCall(Composition::DEVICE);
1198
1199 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1200 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1201 }
1202
TEST_F(OutputLayerWriteStateToHWCTest,previousOverriddenLayerSendsSurfaceDamage)1203 TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) {
1204 mLayerFEState.compositionType = Composition::DEVICE;
1205 mOutputLayer.editState().hwc->stateOverridden = true;
1206
1207 expectGeometryCommonCalls();
1208 expectPerFrameCommonCalls(SimulateUnsupported::None, kDataspace, kOutputSpaceVisibleRegion,
1209 Region::INVALID_REGION);
1210 expectSetHdrMetadataAndBufferCalls();
1211 expectSetCompositionTypeCall(Composition::DEVICE);
1212
1213 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1214 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1215 }
1216
TEST_F(OutputLayerWriteStateToHWCTest,previousSkipLayerSendsUpdatedDeviceCompositionInfo)1217 TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedDeviceCompositionInfo) {
1218 mLayerFEState.compositionType = Composition::DEVICE;
1219 mOutputLayer.editState().hwc->stateOverridden = true;
1220 mOutputLayer.editState().hwc->layerSkipped = true;
1221 mOutputLayer.editState().hwc->hwcCompositionType = Composition::DEVICE;
1222
1223 expectGeometryCommonCalls();
1224 expectPerFrameCommonCalls(SimulateUnsupported::None, kDataspace, kOutputSpaceVisibleRegion,
1225 Region::INVALID_REGION);
1226 expectSetHdrMetadataAndBufferCalls();
1227 expectSetCompositionTypeCall(Composition::DEVICE);
1228
1229 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1230 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1231 }
1232
TEST_F(OutputLayerWriteStateToHWCTest,previousSkipLayerSendsUpdatedClientCompositionInfo)1233 TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedClientCompositionInfo) {
1234 mLayerFEState.compositionType = Composition::DEVICE;
1235 mOutputLayer.editState().forceClientComposition = true;
1236 mOutputLayer.editState().hwc->stateOverridden = true;
1237 mOutputLayer.editState().hwc->layerSkipped = true;
1238 mOutputLayer.editState().hwc->hwcCompositionType = Composition::CLIENT;
1239
1240 expectGeometryCommonCalls();
1241 expectPerFrameCommonCalls(SimulateUnsupported::None, kDataspace, kOutputSpaceVisibleRegion,
1242 Region::INVALID_REGION);
1243 expectSetHdrMetadataAndBufferCalls();
1244 expectSetCompositionTypeCall(Composition::CLIENT);
1245
1246 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1247 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1248 }
1249
TEST_F(OutputLayerWriteStateToHWCTest,peekThroughChangesBlendMode)1250 TEST_F(OutputLayerWriteStateToHWCTest, peekThroughChangesBlendMode) {
1251 auto peekThroughLayerFE = sp<NiceMock<compositionengine::mock::LayerFE>>::make();
1252 OutputLayer peekThroughLayer{mOutput, *peekThroughLayerFE};
1253
1254 mOutputLayer.mState.overrideInfo.peekThroughLayer = &peekThroughLayer;
1255
1256 expectGeometryCommonCalls(kDisplayFrame, kSourceCrop, kBufferTransform,
1257 Hwc2::IComposerClient::BlendMode::PREMULTIPLIED);
1258 expectPerFrameCommonCalls();
1259
1260 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1261 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1262 }
1263
TEST_F(OutputLayerWriteStateToHWCTest,isPeekingThroughSetsOverride)1264 TEST_F(OutputLayerWriteStateToHWCTest, isPeekingThroughSetsOverride) {
1265 expectGeometryCommonCalls();
1266 expectPerFrameCommonCalls();
1267
1268 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1269 /*zIsOverridden*/ false, /*isPeekingThrough*/ true);
1270 EXPECT_TRUE(mOutputLayer.getState().hwc->stateOverridden);
1271 }
1272
TEST_F(OutputLayerWriteStateToHWCTest,zIsOverriddenSetsOverride)1273 TEST_F(OutputLayerWriteStateToHWCTest, zIsOverriddenSetsOverride) {
1274 expectGeometryCommonCalls();
1275 expectPerFrameCommonCalls();
1276
1277 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1278 /*zIsOverridden*/ true, /*isPeekingThrough*/
1279 false);
1280 EXPECT_TRUE(mOutputLayer.getState().hwc->stateOverridden);
1281 }
1282
TEST_F(OutputLayerWriteStateToHWCTest,roundedCornersForceClientComposition)1283 TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersForceClientComposition) {
1284 expectGeometryCommonCalls();
1285 expectPerFrameCommonCalls();
1286 EXPECT_CALL(mLayerFE, hasRoundedCorners()).WillOnce(Return(true));
1287 expectSetCompositionTypeCall(Composition::CLIENT);
1288
1289 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1290 /*zIsOverridden*/ false, /*isPeekingThrough*/
1291 false);
1292 }
1293
TEST_F(OutputLayerWriteStateToHWCTest,roundedCornersPeekingThroughAllowsDeviceComposition)1294 TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersPeekingThroughAllowsDeviceComposition) {
1295 expectGeometryCommonCalls();
1296 expectPerFrameCommonCalls();
1297 expectSetHdrMetadataAndBufferCalls();
1298 EXPECT_CALL(mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
1299 expectSetCompositionTypeCall(Composition::DEVICE);
1300
1301 mLayerFEState.compositionType = Composition::DEVICE;
1302 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1303 /*zIsOverridden*/ false, /*isPeekingThrough*/
1304 true);
1305 EXPECT_EQ(Composition::DEVICE, mOutputLayer.getState().hwc->hwcCompositionType);
1306 }
1307
TEST_F(OutputLayerWriteStateToHWCTest,setBlockingRegion)1308 TEST_F(OutputLayerWriteStateToHWCTest, setBlockingRegion) {
1309 mLayerFEState.compositionType = Composition::DISPLAY_DECORATION;
1310 const auto blockingRegion = Region(Rect(0, 0, 1000, 1000));
1311 mOutputLayer.editState().outputSpaceBlockingRegionHint = blockingRegion;
1312
1313 expectGeometryCommonCalls();
1314 expectPerFrameCommonCalls(SimulateUnsupported::None, kDataspace, kOutputSpaceVisibleRegion,
1315 kSurfaceDamage, kLayerBrightness, blockingRegion);
1316 expectSetHdrMetadataAndBufferCalls();
1317 expectSetCompositionTypeCall(Composition::DISPLAY_DECORATION);
1318
1319 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1320 /*zIsOverridden*/ false, /*isPeekingThrough*/
1321 false);
1322 }
1323
TEST_F(OutputLayerWriteStateToHWCTest,setCompositionTypeRefreshRateIndicator)1324 TEST_F(OutputLayerWriteStateToHWCTest, setCompositionTypeRefreshRateIndicator) {
1325 mLayerFEState.compositionType = Composition::REFRESH_RATE_INDICATOR;
1326
1327 expectGeometryCommonCalls();
1328 expectPerFrameCommonCalls();
1329 expectSetHdrMetadataAndBufferCalls();
1330 expectSetCompositionTypeCall(Composition::REFRESH_RATE_INDICATOR);
1331
1332 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1333 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1334 }
1335
TEST_F(OutputLayerWriteStateToHWCTest,setsPictureProfileWhenCommitted)1336 TEST_F(OutputLayerWriteStateToHWCTest, setsPictureProfileWhenCommitted) {
1337 if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
1338 GTEST_SKIP() << "Feature flag disabled, skipping";
1339 }
1340 mLayerFEState.compositionType = Composition::DEVICE;
1341 mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
1342
1343 expectGeometryCommonCalls();
1344 expectPerFrameCommonCalls();
1345 expectSetHdrMetadataAndBufferCalls();
1346 expectSetCompositionTypeCall(Composition::DEVICE);
1347
1348 EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1)));
1349
1350 mOutputLayer.commitPictureProfileToCompositionState();
1351 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1352 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1353 }
1354
TEST_F(OutputLayerWriteStateToHWCTest,doesNotSetPictureProfileWhenNotCommitted)1355 TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommitted) {
1356 if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
1357 GTEST_SKIP() << "Feature flag disabled, skipping";
1358 }
1359 mLayerFEState.compositionType = Composition::DEVICE;
1360 mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
1361
1362 expectGeometryCommonCalls();
1363 expectPerFrameCommonCalls();
1364 expectSetHdrMetadataAndBufferCalls();
1365 expectSetCompositionTypeCall(Composition::DEVICE);
1366
1367 EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(_)).Times(0);
1368
1369 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1370 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1371 }
1372
TEST_F(OutputLayerWriteStateToHWCTest,doesNotSetPictureProfileWhenNotCommittedLater)1373 TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommittedLater) {
1374 if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
1375 GTEST_SKIP() << "Feature flag disabled, skipping";
1376 }
1377 mLayerFEState.compositionType = Composition::DEVICE;
1378 mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
1379
1380 expectGeometryCommonCalls();
1381 expectPerFrameCommonCalls();
1382 expectSetHdrMetadataAndBufferCalls();
1383 expectSetCompositionTypeCall(Composition::DEVICE);
1384
1385 EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1)));
1386
1387 mOutputLayer.commitPictureProfileToCompositionState();
1388 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1389 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1390
1391 expectGeometryCommonCalls();
1392 expectPerFrameCommonCalls();
1393 expectSetHdrMetadataAndBufferCalls(kExpectedHwcSlot, nullptr, kFence);
1394
1395 EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1))).Times(0);
1396 // No committing of picture profile before writing the state
1397 mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
1398 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1399 }
1400
1401 /*
1402 * OutputLayer::uncacheBuffers
1403 */
1404 struct OutputLayerUncacheBufferTest : public OutputLayerTest {
1405 static const sp<GraphicBuffer> kBuffer1;
1406 static const sp<GraphicBuffer> kBuffer2;
1407 static const sp<GraphicBuffer> kBuffer3;
1408 static const sp<Fence> kFence;
1409
OutputLayerUncacheBufferTestandroid::compositionengine::__anon045ea7a70111::OutputLayerUncacheBufferTest1410 OutputLayerUncacheBufferTest() {
1411 auto& outputLayerState = mOutputLayer.editState();
1412 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer_);
1413
1414 mLayerFEState.compositionType = Composition::DEVICE;
1415 mLayerFEState.acquireFence = kFence;
1416
1417 ON_CALL(mOutput, getDisplayColorProfile()).WillByDefault(Return(&mDisplayColorProfile));
1418 }
1419
1420 std::shared_ptr<HWC2::mock::Layer> mHwcLayer_{std::make_shared<NiceMock<HWC2::mock::Layer>>()};
1421 HWC2::mock::Layer& mHwcLayer = *mHwcLayer_;
1422 NiceMock<mock::DisplayColorProfile> mDisplayColorProfile;
1423 };
1424
1425 const sp<GraphicBuffer> OutputLayerUncacheBufferTest::kBuffer1 =
1426 sp<GraphicBuffer>::make(1, 2, PIXEL_FORMAT_RGBA_8888,
1427 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
1428 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
1429 const sp<GraphicBuffer> OutputLayerUncacheBufferTest::kBuffer2 =
1430 sp<GraphicBuffer>::make(2, 3, PIXEL_FORMAT_RGBA_8888,
1431 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
1432 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
1433 const sp<GraphicBuffer> OutputLayerUncacheBufferTest::kBuffer3 =
1434 sp<GraphicBuffer>::make(4, 5, PIXEL_FORMAT_RGBA_8888,
1435 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
1436 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
1437 const sp<Fence> OutputLayerUncacheBufferTest::kFence = sp<Fence>::make();
1438
TEST_F(OutputLayerUncacheBufferTest,canUncacheAndReuseSlot)1439 TEST_F(OutputLayerUncacheBufferTest, canUncacheAndReuseSlot) {
1440 // Buffer1 is stored in slot 0
1441 mLayerFEState.buffer = kBuffer1;
1442 EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 0, kBuffer1, kFence));
1443 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1444 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1445 Mock::VerifyAndClearExpectations(&mHwcLayer);
1446
1447 // Buffer2 is stored in slot 1
1448 mLayerFEState.buffer = kBuffer2;
1449 EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, kBuffer2, kFence));
1450 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1451 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1452 Mock::VerifyAndClearExpectations(&mHwcLayer);
1453
1454 // Buffer3 is stored in slot 2
1455 mLayerFEState.buffer = kBuffer3;
1456 EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 2, kBuffer3, kFence));
1457 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1458 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1459 Mock::VerifyAndClearExpectations(&mHwcLayer);
1460
1461 // Buffer2 becomes the active buffer again (with a nullptr) and reuses slot 1
1462 mLayerFEState.buffer = kBuffer2;
1463 sp<GraphicBuffer> nullBuffer = nullptr;
1464 EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, nullBuffer, kFence));
1465 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1466 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1467 Mock::VerifyAndClearExpectations(&mHwcLayer);
1468
1469 // Buffer slots are cleared
1470 std::vector<uint32_t> slotsToClear = {0, 2, 1}; // order doesn't matter
1471 EXPECT_CALL(mHwcLayer, setBufferSlotsToClear(slotsToClear, /*activeBufferSlot*/ 1));
1472 // Uncache the active buffer in between other buffers to exercise correct algorithmic behavior.
1473 mOutputLayer.uncacheBuffers({kBuffer1->getId(), kBuffer2->getId(), kBuffer3->getId()});
1474 Mock::VerifyAndClearExpectations(&mHwcLayer);
1475
1476 // Buffer1 becomes active again, and rather than allocating a new slot, or re-using slot 0,
1477 // the active buffer slot (slot 1 for Buffer2) is reused first, which allows HWC to free the
1478 // memory for the active buffer. Note: slot 1 is different from the first and last buffer slot
1479 // requested to be cleared in slotsToClear (slot 1), above, indicating that the algorithm
1480 // correctly identifies the active buffer as the buffer in slot 1, despite ping-ponging.
1481 mLayerFEState.buffer = kBuffer1;
1482 EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, kBuffer1, kFence));
1483 mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
1484 /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
1485 Mock::VerifyAndClearExpectations(&mHwcLayer);
1486 }
1487
1488 /*
1489 * OutputLayer::writeCursorPositionToHWC()
1490 */
1491
1492 struct OutputLayerWriteCursorPositionToHWCTest : public OutputLayerTest {
1493 static constexpr int kDefaultTransform = TR_IDENT;
1494 static constexpr hal::Error kDefaultError = hal::Error::UNSUPPORTED;
1495
1496 static const Rect kDefaultDisplayViewport;
1497 static const Rect kDefaultCursorFrame;
1498
OutputLayerWriteCursorPositionToHWCTestandroid::compositionengine::__anon045ea7a70111::OutputLayerWriteCursorPositionToHWCTest1499 OutputLayerWriteCursorPositionToHWCTest() {
1500 auto& outputLayerState = mOutputLayer.editState();
1501 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
1502
1503 mLayerFEState.cursorFrame = kDefaultCursorFrame;
1504
1505 mOutputState.layerStackSpace.setContent(kDefaultDisplayViewport);
1506 mOutputState.transform = ui::Transform{kDefaultTransform};
1507 }
1508
1509 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
1510 };
1511
1512 const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultDisplayViewport{0, 0, 1920, 1080};
1513 const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultCursorFrame{1, 2, 3, 4};
1514
TEST_F(OutputLayerWriteCursorPositionToHWCTest,doesNothingIfNoFECompositionState)1515 TEST_F(OutputLayerWriteCursorPositionToHWCTest, doesNothingIfNoFECompositionState) {
1516 EXPECT_CALL(mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
1517
1518 mOutputLayer.writeCursorPositionToHWC();
1519 }
1520
TEST_F(OutputLayerWriteCursorPositionToHWCTest,writeCursorPositionToHWCHandlesNoHwcState)1521 TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCHandlesNoHwcState) {
1522 mOutputLayer.editState().hwc.reset();
1523
1524 mOutputLayer.writeCursorPositionToHWC();
1525 }
1526
TEST_F(OutputLayerWriteCursorPositionToHWCTest,writeCursorPositionToHWCWritesStateToHWC)1527 TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCWritesStateToHWC) {
1528 EXPECT_CALL(*mHwcLayer, setCursorPosition(1, 2)).WillOnce(Return(kDefaultError));
1529
1530 mOutputLayer.writeCursorPositionToHWC();
1531 }
1532
TEST_F(OutputLayerWriteCursorPositionToHWCTest,writeCursorPositionToHWCIntersectedWithViewport)1533 TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCIntersectedWithViewport) {
1534 mLayerFEState.cursorFrame = Rect{3000, 3000, 3016, 3016};
1535
1536 EXPECT_CALL(*mHwcLayer, setCursorPosition(1920, 1080)).WillOnce(Return(kDefaultError));
1537
1538 mOutputLayer.writeCursorPositionToHWC();
1539 }
1540
TEST_F(OutputLayerWriteCursorPositionToHWCTest,writeCursorPositionToHWCRotatedByTransform)1541 TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCRotatedByTransform) {
1542 mOutputState.transform = ui::Transform{TR_ROT_90};
1543
1544 EXPECT_CALL(*mHwcLayer, setCursorPosition(-4, 1)).WillOnce(Return(kDefaultError));
1545
1546 mOutputLayer.writeCursorPositionToHWC();
1547 }
1548
1549 /*
1550 * OutputLayer::getHwcLayer()
1551 */
1552
TEST_F(OutputLayerTest,getHwcLayerHandlesNoHwcState)1553 TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcState) {
1554 mOutputLayer.editState().hwc.reset();
1555
1556 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
1557 }
1558
TEST_F(OutputLayerTest,getHwcLayerHandlesNoHwcLayer)1559 TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcLayer) {
1560 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1561
1562 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
1563 }
1564
TEST_F(OutputLayerTest,getHwcLayerReturnsHwcLayer)1565 TEST_F(OutputLayerTest, getHwcLayerReturnsHwcLayer) {
1566 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
1567 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{hwcLayer};
1568
1569 EXPECT_EQ(hwcLayer.get(), mOutputLayer.getHwcLayer());
1570 }
1571
1572 /*
1573 * OutputLayer::requiresClientComposition()
1574 */
1575
TEST_F(OutputLayerTest,requiresClientCompositionReturnsTrueIfNoHWC2State)1576 TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfNoHWC2State) {
1577 mOutputLayer.editState().hwc.reset();
1578
1579 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
1580 }
1581
TEST_F(OutputLayerTest,requiresClientCompositionReturnsTrueIfSetToClientComposition)1582 TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfSetToClientComposition) {
1583 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1584 mOutputLayer.editState().hwc->hwcCompositionType = Composition::CLIENT;
1585
1586 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
1587 }
1588
TEST_F(OutputLayerTest,requiresClientCompositionReturnsFalseIfSetToDeviceComposition)1589 TEST_F(OutputLayerTest, requiresClientCompositionReturnsFalseIfSetToDeviceComposition) {
1590 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1591 mOutputLayer.editState().hwc->hwcCompositionType = Composition::DEVICE;
1592
1593 EXPECT_FALSE(mOutputLayer.requiresClientComposition());
1594 }
1595
1596 /*
1597 * OutputLayer::isHardwareCursor()
1598 */
1599
TEST_F(OutputLayerTest,isHardwareCursorReturnsFalseIfNoHWC2State)1600 TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfNoHWC2State) {
1601 mOutputLayer.editState().hwc.reset();
1602
1603 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
1604 }
1605
TEST_F(OutputLayerTest,isHardwareCursorReturnsTrueIfSetToCursorComposition)1606 TEST_F(OutputLayerTest, isHardwareCursorReturnsTrueIfSetToCursorComposition) {
1607 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1608 mOutputLayer.editState().hwc->hwcCompositionType = Composition::CURSOR;
1609
1610 EXPECT_TRUE(mOutputLayer.isHardwareCursor());
1611 }
1612
TEST_F(OutputLayerTest,isHardwareCursorReturnsFalseIfSetToDeviceComposition)1613 TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfSetToDeviceComposition) {
1614 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1615 mOutputLayer.editState().hwc->hwcCompositionType = Composition::DEVICE;
1616
1617 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
1618 }
1619
1620 /*
1621 * OutputLayer::applyDeviceCompositionTypeChange()
1622 */
1623
TEST_F(OutputLayerTest,applyDeviceCompositionTypeChangeSetsNewType)1624 TEST_F(OutputLayerTest, applyDeviceCompositionTypeChangeSetsNewType) {
1625 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1626 mOutputLayer.editState().hwc->hwcCompositionType = Composition::DEVICE;
1627
1628 mOutputLayer.applyDeviceCompositionTypeChange(Composition::CLIENT);
1629
1630 ASSERT_TRUE(mOutputLayer.getState().hwc);
1631 EXPECT_EQ(Composition::CLIENT, mOutputLayer.getState().hwc->hwcCompositionType);
1632 }
1633
1634 /*
1635 * OutputLayer::prepareForDeviceLayerRequests()
1636 */
1637
TEST_F(OutputLayerTest,prepareForDeviceLayerRequestsResetsRequestState)1638 TEST_F(OutputLayerTest, prepareForDeviceLayerRequestsResetsRequestState) {
1639 mOutputLayer.editState().clearClientTarget = true;
1640
1641 mOutputLayer.prepareForDeviceLayerRequests();
1642
1643 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1644 }
1645
1646 /*
1647 * OutputLayer::applyDeviceLayerRequest()
1648 */
1649
TEST_F(OutputLayerTest,applyDeviceLayerRequestHandlesClearClientTarget)1650 TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesClearClientTarget) {
1651 mOutputLayer.editState().clearClientTarget = false;
1652
1653 mOutputLayer.applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET);
1654
1655 EXPECT_TRUE(mOutputLayer.getState().clearClientTarget);
1656 }
1657
TEST_F(OutputLayerTest,applyDeviceLayerRequestHandlesUnknownRequest)1658 TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesUnknownRequest) {
1659 mOutputLayer.editState().clearClientTarget = false;
1660
1661 mOutputLayer.applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(0));
1662
1663 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1664 }
1665
1666 /*
1667 * OutputLayer::needsFiltering()
1668 */
1669
TEST_F(OutputLayerTest,needsFilteringReturnsFalseIfDisplaySizeSameAsSourceSize)1670 TEST_F(OutputLayerTest, needsFilteringReturnsFalseIfDisplaySizeSameAsSourceSize) {
1671 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1672 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f};
1673
1674 EXPECT_FALSE(mOutputLayer.needsFiltering());
1675 }
1676
TEST_F(OutputLayerTest,needsFilteringReturnsTrueIfDisplaySizeDifferentFromSourceSize)1677 TEST_F(OutputLayerTest, needsFilteringReturnsTrueIfDisplaySizeDifferentFromSourceSize) {
1678 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1679 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.1f, 100.1f};
1680
1681 EXPECT_TRUE(mOutputLayer.needsFiltering());
1682 }
1683
TEST_F(OutputLayerTest,needsFilteringReturnsFalseIfRotatedDisplaySizeSameAsSourceSize)1684 TEST_F(OutputLayerTest, needsFilteringReturnsFalseIfRotatedDisplaySizeSameAsSourceSize) {
1685 mOutputLayer.editState().displayFrame = Rect(100, 100, 300, 200);
1686 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 200.f};
1687 mOutputLayer.editState().bufferTransform = Hwc2::Transform::ROT_90;
1688
1689 EXPECT_FALSE(mOutputLayer.needsFiltering());
1690 }
1691
TEST_F(OutputLayerTest,needsFilteringReturnsTrueIfRotatedDisplaySizeDiffersFromSourceSize)1692 TEST_F(OutputLayerTest, needsFilteringReturnsTrueIfRotatedDisplaySizeDiffersFromSourceSize) {
1693 mOutputLayer.editState().displayFrame = Rect(100, 100, 300, 200);
1694 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 200.f};
1695
1696 EXPECT_TRUE(mOutputLayer.needsFiltering());
1697 }
1698
1699 } // namespace
1700 } // namespace android::compositionengine
1701