• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <compositionengine/impl/OutputLayer.h>
18 #include <compositionengine/mock/CompositionEngine.h>
19 #include <compositionengine/mock/Layer.h>
20 #include <compositionengine/mock/LayerFE.h>
21 #include <compositionengine/mock/Output.h>
22 #include <gtest/gtest.h>
23 
24 #include "MockHWC2.h"
25 #include "MockHWComposer.h"
26 #include "RectMatcher.h"
27 
28 namespace android::compositionengine {
29 namespace {
30 
31 using testing::_;
32 using testing::Return;
33 using testing::ReturnRef;
34 using testing::StrictMock;
35 
36 constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
37 
38 constexpr auto TR_IDENT = 0u;
39 constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
40 constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
41 constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
42 constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
43 constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
44 
45 const std::string kOutputName{"Test Output"};
46 
47 class OutputLayerTest : public testing::Test {
48 public:
OutputLayerTest()49     OutputLayerTest() {
50         EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
51         EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
52 
53         EXPECT_CALL(*mLayer, getState()).WillRepeatedly(ReturnRef(mLayerState));
54         EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
55     }
56 
57     ~OutputLayerTest() override = default;
58 
59     compositionengine::mock::Output mOutput;
60     std::shared_ptr<compositionengine::mock::Layer> mLayer{
61             new StrictMock<compositionengine::mock::Layer>()};
62     sp<compositionengine::mock::LayerFE> mLayerFE{
63             new StrictMock<compositionengine::mock::LayerFE>()};
64     impl::OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
65 
66     impl::LayerCompositionState mLayerState;
67     impl::OutputCompositionState mOutputState;
68 };
69 
70 /*
71  * Basic construction
72  */
73 
TEST_F(OutputLayerTest,canInstantiateOutputLayer)74 TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
75 
76 /*
77  * OutputLayer::initialize()
78  */
79 
TEST_F(OutputLayerTest,initializingOutputLayerWithoutHwcDoesNothingInteresting)80 TEST_F(OutputLayerTest, initializingOutputLayerWithoutHwcDoesNothingInteresting) {
81     StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
82 
83     mOutputLayer.initialize(compositionEngine, std::nullopt);
84 
85     EXPECT_FALSE(mOutputLayer.getState().hwc);
86 }
87 
TEST_F(OutputLayerTest,initializingOutputLayerWithHwcDisplayCreatesHwcLayer)88 TEST_F(OutputLayerTest, initializingOutputLayerWithHwcDisplayCreatesHwcLayer) {
89     StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
90     StrictMock<android::mock::HWComposer> hwc;
91     StrictMock<HWC2::mock::Layer> hwcLayer;
92 
93     EXPECT_CALL(compositionEngine, getHwComposer()).WillOnce(ReturnRef(hwc));
94     EXPECT_CALL(hwc, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
95 
96     mOutputLayer.initialize(compositionEngine, DEFAULT_DISPLAY_ID);
97 
98     const auto& outputLayerState = mOutputLayer.getState();
99     ASSERT_TRUE(outputLayerState.hwc);
100 
101     const auto& hwcState = *outputLayerState.hwc;
102     EXPECT_EQ(&hwcLayer, hwcState.hwcLayer.get());
103 
104     EXPECT_CALL(hwc, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
105     mOutputLayer.editState().hwc.reset();
106 }
107 
108 /*
109  * OutputLayer::calculateOutputDisplayFrame()
110  */
111 
112 struct OutputLayerDisplayFrameTest : public OutputLayerTest {
OutputLayerDisplayFrameTestandroid::compositionengine::__anon5036059a0111::OutputLayerDisplayFrameTest113     OutputLayerDisplayFrameTest() {
114         // Set reasonable default values for a simple case. Each test will
115         // set one specific value to something different.
116 
117         mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
118         mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
119         mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
120         mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
121         mLayerState.frontEnd.geomCrop = Rect{0, 0, 1920, 1080};
122         mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
123 
124         mOutputState.viewport = Rect{0, 0, 1920, 1080};
125         mOutputState.transform = ui::Transform{TR_IDENT};
126     }
127 
calculateOutputDisplayFrameandroid::compositionengine::__anon5036059a0111::OutputLayerDisplayFrameTest128     Rect calculateOutputDisplayFrame() {
129         mLayerState.frontEnd.geomInverseLayerTransform =
130                 mLayerState.frontEnd.geomLayerTransform.inverse();
131 
132         return mOutputLayer.calculateOutputDisplayFrame();
133     }
134 };
135 
TEST_F(OutputLayerDisplayFrameTest,correctForSimpleDefaultCase)136 TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
137     const Rect expected{0, 0, 1920, 1080};
138     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
139 }
140 
TEST_F(OutputLayerDisplayFrameTest,fullActiveTransparentRegionReturnsEmptyFrame)141 TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
142     mLayerState.frontEnd.geomActiveTransparentRegion = Region{Rect{0, 0, 1920, 1080}};
143     const Rect expected{0, 0, 0, 0};
144     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
145 }
146 
TEST_F(OutputLayerDisplayFrameTest,cropAffectsDisplayFrame)147 TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
148     mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
149     const Rect expected{100, 200, 300, 500};
150     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
151 }
152 
TEST_F(OutputLayerDisplayFrameTest,cropAffectsDisplayFrameRotated)153 TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
154     mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
155     mLayerState.frontEnd.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
156     const Rect expected{1420, 100, 1720, 300};
157     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
158 }
159 
TEST_F(OutputLayerDisplayFrameTest,emptyGeomCropIsNotUsedToComputeFrame)160 TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
161     mLayerState.frontEnd.geomCrop = Rect{};
162     const Rect expected{0, 0, 1920, 1080};
163     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
164 }
165 
TEST_F(OutputLayerDisplayFrameTest,geomLayerSnapToBoundsAffectsFrame)166 TEST_F(OutputLayerDisplayFrameTest, geomLayerSnapToBoundsAffectsFrame) {
167     mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
168     const Rect expected{0, 0, 960, 540};
169     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
170 }
171 
TEST_F(OutputLayerDisplayFrameTest,viewportAffectsFrame)172 TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
173     mOutputState.viewport = Rect{0, 0, 960, 540};
174     const Rect expected{0, 0, 960, 540};
175     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
176 }
177 
TEST_F(OutputLayerDisplayFrameTest,outputTransformAffectsDisplayFrame)178 TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
179     mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
180     const Rect expected{-1080, 0, 0, 1920};
181     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
182 }
183 
184 /*
185  * OutputLayer::calculateOutputRelativeBufferTransform()
186  */
187 
TEST_F(OutputLayerTest,calculateOutputRelativeBufferTransformTestsNeeded)188 TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
189     mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
190 
191     struct Entry {
192         uint32_t layer;
193         uint32_t buffer;
194         uint32_t display;
195         uint32_t expected;
196     };
197     // Not an exhaustive list of cases, but hopefully enough.
198     const std::array<Entry, 24> testData = {
199             // clang-format off
200             //             layer       buffer      display     expected
201             /*  0 */ Entry{TR_IDENT,   TR_IDENT,   TR_IDENT,   TR_IDENT},
202             /*  1 */ Entry{TR_IDENT,   TR_IDENT,   TR_ROT_90,  TR_ROT_90},
203             /*  2 */ Entry{TR_IDENT,   TR_IDENT,   TR_ROT_180, TR_ROT_180},
204             /*  3 */ Entry{TR_IDENT,   TR_IDENT,   TR_ROT_270, TR_ROT_270},
205 
206             /*  4 */ Entry{TR_IDENT,   TR_FLP_H,   TR_IDENT,   TR_FLP_H ^ TR_IDENT},
207             /*  5 */ Entry{TR_IDENT,   TR_FLP_H,   TR_ROT_90,  TR_FLP_H ^ TR_ROT_90},
208             /*  6 */ Entry{TR_IDENT,   TR_FLP_H,   TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
209             /*  7 */ Entry{TR_IDENT,   TR_FLP_H,   TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
210 
211             /*  8 */ Entry{TR_IDENT,   TR_FLP_V,   TR_IDENT,   TR_FLP_V},
212             /*  9 */ Entry{TR_IDENT,   TR_ROT_90,  TR_ROT_90,  TR_ROT_180},
213             /* 10 */ Entry{TR_IDENT,   TR_ROT_180, TR_ROT_180, TR_IDENT},
214             /* 11 */ Entry{TR_IDENT,   TR_ROT_270, TR_ROT_270, TR_ROT_180},
215 
216             /* 12 */ Entry{TR_ROT_90,  TR_IDENT,   TR_IDENT,   TR_IDENT ^ TR_ROT_90},
217             /* 13 */ Entry{TR_ROT_90,  TR_FLP_H,   TR_ROT_90,  TR_FLP_H ^ TR_ROT_180},
218             /* 14 */ Entry{TR_ROT_90,  TR_IDENT,   TR_ROT_180, TR_IDENT ^ TR_ROT_270},
219             /* 15 */ Entry{TR_ROT_90,  TR_FLP_H,   TR_ROT_270, TR_FLP_H ^ TR_IDENT},
220 
221             /* 16 */ Entry{TR_ROT_180, TR_FLP_H,   TR_IDENT,   TR_FLP_H ^ TR_ROT_180},
222             /* 17 */ Entry{TR_ROT_180, TR_IDENT,   TR_ROT_90,  TR_IDENT ^ TR_ROT_270},
223             /* 18 */ Entry{TR_ROT_180, TR_FLP_H,   TR_ROT_180, TR_FLP_H ^ TR_IDENT},
224             /* 19 */ Entry{TR_ROT_180, TR_IDENT,   TR_ROT_270, TR_IDENT ^ TR_ROT_90},
225 
226             /* 20 */ Entry{TR_ROT_270, TR_IDENT,   TR_IDENT,   TR_IDENT ^ TR_ROT_270},
227             /* 21 */ Entry{TR_ROT_270, TR_FLP_H,   TR_ROT_90,  TR_FLP_H ^ TR_IDENT},
228             /* 22 */ Entry{TR_ROT_270, TR_FLP_H,   TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
229             /* 23 */ Entry{TR_ROT_270, TR_IDENT,   TR_ROT_270, TR_IDENT ^ TR_ROT_180},
230             // clang-format on
231     };
232 
233     for (size_t i = 0; i < testData.size(); i++) {
234         const auto& entry = testData[i];
235 
236         mLayerState.frontEnd.geomLayerTransform.set(entry.layer, 1920, 1080);
237         mLayerState.frontEnd.geomBufferTransform = entry.buffer;
238         mOutputState.orientation = entry.display;
239 
240         auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
241         EXPECT_EQ(entry.expected, actual) << "entry " << i;
242     }
243 }
244 
245 /*
246  * OutputLayer::writeStateToHWC()
247  */
248 
249 struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
250     static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
251     static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
252     static constexpr uint32_t kZOrder = 21u;
253     static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
254     static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
255             static_cast<Hwc2::IComposerClient::BlendMode>(41);
256     static constexpr float kAlpha = 51.f;
257     static constexpr uint32_t kType = 61u;
258     static constexpr uint32_t kAppId = 62u;
259 
260     static const Rect kDisplayFrame;
261 
OutputLayerWriteStateToHWCTestandroid::compositionengine::__anon5036059a0111::OutputLayerWriteStateToHWCTest262     OutputLayerWriteStateToHWCTest() {
263         auto& outputLayerState = mOutputLayer.editState();
264         outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
265 
266         outputLayerState.displayFrame = kDisplayFrame;
267         outputLayerState.sourceCrop = kSourceCrop;
268         outputLayerState.z = kZOrder;
269         outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
270 
271         mLayerState.frontEnd.blendMode = kBlendMode;
272         mLayerState.frontEnd.alpha = kAlpha;
273         mLayerState.frontEnd.type = kType;
274         mLayerState.frontEnd.appId = kAppId;
275     }
276 
expectGeometryCommonCallsandroid::compositionengine::__anon5036059a0111::OutputLayerWriteStateToHWCTest277     void expectGeometryCommonCalls() {
278         EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
279         EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
280         EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
281         EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
282                 .WillOnce(Return(kError));
283 
284         EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
285                 .WillOnce(Return(kError));
286         EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
287         EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
288     }
289 
290     std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
291 };
292 
293 const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
294 
TEST_F(OutputLayerWriteStateToHWCTest,doesNothingIfNoHWCState)295 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
296     mOutputLayer.editState().hwc.reset();
297 
298     mOutputLayer.writeStateToHWC(true);
299 }
300 
TEST_F(OutputLayerWriteStateToHWCTest,doesNothingIfNoHWCLayer)301 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
302     mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
303 
304     mOutputLayer.writeStateToHWC(true);
305 }
306 
TEST_F(OutputLayerWriteStateToHWCTest,canSetsAllState)307 TEST_F(OutputLayerWriteStateToHWCTest, canSetsAllState) {
308     expectGeometryCommonCalls();
309 
310     mOutputLayer.writeStateToHWC(true);
311 }
312 
313 } // namespace
314 } // namespace android::compositionengine
315