Home | History | Annotate | Download | only in tests
      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:
     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 
     74 TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
     75 
     76 /*
     77  * OutputLayer::initialize()
     78  */
     79 
     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 
     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 {
    113     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 
    128     Rect calculateOutputDisplayFrame() {
    129         mLayerState.frontEnd.geomInverseLayerTransform =
    130                 mLayerState.frontEnd.geomLayerTransform.inverse();
    131 
    132         return mOutputLayer.calculateOutputDisplayFrame();
    133     }
    134 };
    135 
    136 TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
    137     const Rect expected{0, 0, 1920, 1080};
    138     EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
    139 }
    140 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    262     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 
    277     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 
    295 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
    296     mOutputLayer.editState().hwc.reset();
    297 
    298     mOutputLayer.writeStateToHWC(true);
    299 }
    300 
    301 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
    302     mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
    303 
    304     mOutputLayer.writeStateToHWC(true);
    305 }
    306 
    307 TEST_F(OutputLayerWriteStateToHWCTest, canSetsAllState) {
    308     expectGeometryCommonCalls();
    309 
    310     mOutputLayer.writeStateToHWC(true);
    311 }
    312 
    313 } // namespace
    314 } // namespace android::compositionengine
    315