Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cd789cd authored by Marissa Wall's avatar Marissa Wall
Browse files

test-hwc2: validate display

Test: Add "#define HAVE_NO_SURFACE_FLINGER" to
          frameworks/native/libs/gui/BufferQueueCore.cpp.
      Recompile and flash.
      Run "mm" in frameworks/native/services/surfaceflinger/tests/hwc2.
      Push test-hwc2 to device.
      Run "adb root && adb shell stop".
      Run test case. Ex: "./test-hwc2"

Change-Id: I9a9df2902213d99d4f043e3bdea1e5e2fc77b01d
parent f7618ed1
Loading
Loading
Loading
Loading
+196 −0
Original line number Diff line number Diff line
@@ -559,6 +559,33 @@ public:
        }
    }

    void validateDisplay(hwc2_display_t display, uint32_t* outNumTypes,
            uint32_t* outNumRequests, hwc2_error_t* outErr)
    {
        auto pfn = reinterpret_cast<HWC2_PFN_VALIDATE_DISPLAY>(
                getFunction(HWC2_FUNCTION_VALIDATE_DISPLAY));
        ASSERT_TRUE(pfn) << "failed to get function";

        *outErr = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
                outNumTypes, outNumRequests));
    }

    void validateDisplay(hwc2_display_t display, uint32_t* outNumTypes,
            uint32_t* outNumRequests, bool* outHasChanges)
    {
        hwc2_error_t err = HWC2_ERROR_NONE;

        EXPECT_NO_FATAL_FAILURE(validateDisplay(display, outNumTypes,
                outNumRequests, &err));

        if (err != HWC2_ERROR_HAS_CHANGES) {
            *outHasChanges = false;
            EXPECT_EQ(err, HWC2_ERROR_NONE) << "failed to validate display";
        } else {
            *outHasChanges = true;
        }
    }

protected:
    hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
    {
@@ -719,6 +746,12 @@ protected:
    using TestLayerPropertyBadParameterFunction = void (*)(Hwc2Test* test,
            hwc2_display_t display, hwc2_layer_t layer, hwc2_error_t* outErr);

    /* Is called after a display is powered on and all layer properties have
     * been set. It should be used to test functions such as validate, accepting
     * changes, present, etc. */
    using TestDisplayLayersFunction = void (*)(Hwc2Test* test,
            hwc2_display_t display, const std::vector<hwc2_layer_t>& layers);

    /* Advances a property of Hwc2TestLayer */
    using AdvanceProperty = bool (*)(Hwc2TestLayer* testLayer);

@@ -895,6 +928,48 @@ protected:
        }
    }

    /* For each active display it powers on the display, cycles through each
     * config and creates a set of layers with a certain amount of coverage.
     * For each active display, for each config and for each set of layers,
     * it calls the TestDisplayLayersFunction */
    void displayLayers(Hwc2TestCoverage coverage, size_t layerCnt,
            TestDisplayLayersFunction function)
    {
        for (auto display : mDisplays) {
            std::vector<hwc2_config_t> configs;

            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));

            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));

            for (auto config : configs) {
                Area displayArea;
                std::vector<hwc2_layer_t> layers;

                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display, &displayArea));

                ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
                Hwc2TestLayers testLayers(layers, coverage, displayArea);

                do {
                    bool skip;

                    ASSERT_NO_FATAL_FAILURE(setLayerProperties(display, layers,
                            &testLayers, &skip));
                    if (!skip)
                        EXPECT_NO_FATAL_FAILURE(function(this, display, layers));

                } while (testLayers.advance());

                ASSERT_NO_FATAL_FAILURE(destroyLayers(display,
                        std::move(layers)));
            }

            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
        }
    }

    void getActiveConfigAttribute(hwc2_display_t display,
            hwc2_attribute_t attribute, int32_t* outValue)
    {
@@ -914,6 +989,74 @@ protected:
                HWC2_ATTRIBUTE_HEIGHT, &displayArea->height));
    }

    void setLayerProperties(hwc2_display_t display, hwc2_layer_t layer,
            Hwc2TestLayers* testLayers, bool* outSkip)
    {
        hwc2_composition_t composition;
        buffer_handle_t handle = nullptr;
        int32_t acquireFence;
        hwc2_error_t err = HWC2_ERROR_NONE;
        *outSkip = true;

        if (!testLayers->contains(layer))
            return;

        composition = testLayers->getComposition(layer);

        /* If the device cannot support a buffer format, then do not continue */
        if ((composition == HWC2_COMPOSITION_DEVICE
                || composition == HWC2_COMPOSITION_CURSOR)
                && testLayers->getBuffer(layer, &handle, &acquireFence) < 0)
            return;

        EXPECT_NO_FATAL_FAILURE(setLayerCompositionType(display, layer,
                composition, &err));
        if (err == HWC2_ERROR_UNSUPPORTED)
            EXPECT_TRUE(composition != HWC2_COMPOSITION_CLIENT
                    && composition != HWC2_COMPOSITION_DEVICE);

        const hwc_rect_t cursor = testLayers->getCursorPosition(layer);

        EXPECT_NO_FATAL_FAILURE(setLayerBuffer(display, layer, handle,
                acquireFence));
        EXPECT_NO_FATAL_FAILURE(setLayerBlendMode(display, layer,
                testLayers->getBlendMode(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerColor(display, layer,
                testLayers->getColor(layer)));
        EXPECT_NO_FATAL_FAILURE(setCursorPosition(display, layer, cursor.left,
                cursor.top));
        EXPECT_NO_FATAL_FAILURE(setLayerDataspace(display, layer,
                testLayers->getDataspace(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerDisplayFrame(display, layer,
                testLayers->getDisplayFrame(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerPlaneAlpha(display, layer,
                testLayers->getPlaneAlpha(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerSourceCrop(display, layer,
                testLayers->getSourceCrop(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerSurfaceDamage(display, layer,
                testLayers->getSurfaceDamage(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerTransform(display, layer,
                testLayers->getTransform(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerVisibleRegion(display, layer,
                testLayers->getVisibleRegion(layer)));
        EXPECT_NO_FATAL_FAILURE(setLayerZOrder(display, layer,
                testLayers->getZOrder(layer)));

        *outSkip = false;
    }

    void setLayerProperties(hwc2_display_t display,
            const std::vector<hwc2_layer_t>& layers,
            Hwc2TestLayers* testLayers, bool* outSkip)
    {
        for (auto layer : layers) {
            EXPECT_NO_FATAL_FAILURE(setLayerProperties(display, layer,
                    testLayers, outSkip));
            if (*outSkip)
                return;
        }
    }

    hwc2_device_t* mHwc2Device = nullptr;

    enum class Hwc2TestHotplugStatus {
@@ -2405,3 +2548,56 @@ TEST_F(Hwc2Test, SET_LAYER_Z_ORDER_bad_layer)
    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
            setZOrder));
}

/* TESTCASE: Tests that the HWC2 can display a layer with basic property
 * coverage */
TEST_F(Hwc2Test, VALIDATE_DISPLAY_basic)
{
    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Basic, 1,
            [] (Hwc2Test* test, hwc2_display_t display,
                    const std::vector<hwc2_layer_t>& layers) {

                uint32_t numTypes, numRequests;
                bool hasChanges = false;

                EXPECT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
                        &numRequests, &hasChanges));
                if (hasChanges)
                    EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
                            << "wrong number of requests";
            }
    ));
}

/* TESTCASE: Tests that the HWC2 can display 5 layers with default coverage. */
TEST_F(Hwc2Test, VALIDATE_DISPLAY_default_5)
{
    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Default, 5,
            [] (Hwc2Test* test, hwc2_display_t display,
                    const std::vector<hwc2_layer_t>& layers) {

                uint32_t numTypes, numRequests;
                bool hasChanges = false;

                EXPECT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
                        &numRequests, &hasChanges));
                if (hasChanges)
                    EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
                            << "wrong number of requests";
            }
    ));
}

/* TESTCASE: Tests that the HWC2 cannot validate a bad display */
TEST_F(Hwc2Test, VALIDATE_DISPLAY_bad_display)
{
    hwc2_display_t display;
    uint32_t numTypes, numRequests;
    hwc2_error_t err = HWC2_ERROR_NONE;

    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));

    ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes, &numRequests,
            &err));
    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
}
+16 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ int Hwc2TestLayer::getBuffer(buffer_handle_t* outHandle,
    return ret;
}

int Hwc2TestLayer::getBuffer(buffer_handle_t* outHandle,
        int32_t* outAcquireFence)
{
    return mBuffer.get(outHandle, outAcquireFence);
}

void Hwc2TestLayer::setZOrder(uint32_t zOrder)
{
    mZOrder = zOrder;
@@ -80,6 +86,16 @@ void Hwc2TestLayer::reset()
    }
}

bool Hwc2TestLayer::advance()
{
    for (auto property : mProperties) {
        if (property->isSupported(mComposition.get()))
            if (property->advance())
                return true;
    }
    return false;
}

hwc2_blend_mode_t Hwc2TestLayer::getBlendMode() const
{
    return mBlendMode.get();
+5 −2
Original line number Diff line number Diff line
@@ -36,11 +36,13 @@ public:

    int getBuffer(buffer_handle_t* outHandle,
            android::base::unique_fd* outAcquireFence);
    int getBuffer(buffer_handle_t* outHandle, int32_t* outAcquireFence);

    void setZOrder(uint32_t zOrder);
    void setVisibleRegion(const android::Region& region);

    void reset();
    bool advance();

    hwc2_blend_mode_t      getBlendMode() const;
    Area                   getBufferArea() const;
@@ -71,8 +73,9 @@ public:

private:
    std::array<Hwc2TestContainer*, 10> mProperties = {{
        &mBlendMode, &mBufferArea, &mColor, &mComposition, &mDataspace,
        &mDisplayFrame, &mPlaneAlpha, &mSourceCrop, &mSurfaceDamage, &mTransform
        &mTransform, &mColor, &mDataspace, &mPlaneAlpha, &mSourceCrop,
        &mSurfaceDamage, &mBlendMode, &mBufferArea, &mDisplayFrame,
        &mComposition
    }};

    Hwc2TestBuffer mBuffer;
+107 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
        Hwc2TestCoverage coverage, const Area& displayArea)
    : mDisplayArea(displayArea)
{
    for (auto layer : layers) {
        mTestLayers.emplace(std::piecewise_construct,
@@ -57,6 +58,18 @@ void Hwc2TestLayers::reset()
    setVisibleRegions();
}

bool Hwc2TestLayers::advance()
{
    for (auto& testLayer : mTestLayers) {
        if (testLayer.second.advance()) {
            setVisibleRegions();
            return true;
        }
        testLayer.second.reset();
    }
    return false;
}

bool Hwc2TestLayers::advanceVisibleRegions()
{
    for (auto& testLayer : mTestLayers) {
@@ -69,6 +82,100 @@ bool Hwc2TestLayers::advanceVisibleRegions()
    return false;
}

bool Hwc2TestLayers::contains(hwc2_layer_t layer) const
{
    return mTestLayers.count(layer) != 0;
}

int Hwc2TestLayers::getBuffer(hwc2_layer_t layer, buffer_handle_t* outHandle,
        int32_t* outAcquireFence)
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getBuffer(outHandle, outAcquireFence);
}

hwc2_blend_mode_t Hwc2TestLayers::getBlendMode(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getBlendMode();
}

hwc_color_t Hwc2TestLayers::getColor(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getColor();
}

hwc2_composition_t Hwc2TestLayers::getComposition(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getComposition();
}

hwc_rect_t Hwc2TestLayers::getCursorPosition(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getCursorPosition();
}

android_dataspace_t Hwc2TestLayers::getDataspace(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getDataspace();
}

hwc_rect_t Hwc2TestLayers::getDisplayFrame(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getDisplayFrame();
}

float Hwc2TestLayers::getPlaneAlpha(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getPlaneAlpha();
}

hwc_frect_t Hwc2TestLayers::getSourceCrop(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getSourceCrop();
}

hwc_region_t Hwc2TestLayers::getSurfaceDamage(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getSurfaceDamage();
}

hwc_transform_t Hwc2TestLayers::getTransform(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
        []() { GTEST_FAIL(); }();
    }
    return mTestLayers.at(layer).getTransform();
}

hwc_region_t Hwc2TestLayers::getVisibleRegion(hwc2_layer_t layer) const
{
    if (mTestLayers.count(layer) == 0) {
+21 −2
Original line number Diff line number Diff line
@@ -37,8 +37,25 @@ public:

    void reset();

    bool advance();
    bool advanceVisibleRegions();

    bool contains(hwc2_layer_t layer) const;

    int  getBuffer(hwc2_layer_t layer, buffer_handle_t* outHandle,
            int32_t* outAcquireFence);

    hwc2_blend_mode_t      getBlendMode(hwc2_layer_t layer) const;
    hwc_color_t            getColor(hwc2_layer_t layer) const;
    hwc2_composition_t     getComposition(hwc2_layer_t layer) const;
    hwc_rect_t             getCursorPosition(hwc2_layer_t layer) const;
    android_dataspace_t    getDataspace(hwc2_layer_t layer) const;
    hwc_rect_t             getDisplayFrame(hwc2_layer_t layer) const;
    android_pixel_format_t getFormat(hwc2_layer_t layer) const;
    float                  getPlaneAlpha(hwc2_layer_t layer) const;
    hwc_frect_t            getSourceCrop(hwc2_layer_t layer) const;
    hwc_region_t           getSurfaceDamage(hwc2_layer_t layer) const;
    hwc_transform_t        getTransform(hwc2_layer_t layer) const;
    hwc_region_t           getVisibleRegion(hwc2_layer_t layer) const;
    uint32_t               getZOrder(hwc2_layer_t layer) const;

@@ -46,6 +63,8 @@ private:
    void setVisibleRegions();

    std::map<hwc2_layer_t, Hwc2TestLayer> mTestLayers;

    Area mDisplayArea;
};

#endif /* ifndef _HWC2_TEST_LAYERS_H */
Loading