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

Commit 6bd8bfde authored by Marissa Wall's avatar Marissa Wall
Browse files

test-hwc2: set layer composition type

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: I9e71d0c01daa70f28031dd8310f2a40d7162a68e
parent dd4087f4
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ LOCAL_CFLAGS += \
    -fno-builtin
LOCAL_SHARED_LIBRARIES := libcutils libutils libhardware
LOCAL_STATIC_LIBRARIES := libbase libadf libadfhwc
LOCAL_SRC_FILES := Hwc2Test.cpp
LOCAL_SRC_FILES := \
    Hwc2Test.cpp \
    Hwc2TestProperties.cpp \
    Hwc2TestLayer.cpp

include $(BUILD_NATIVE_TEST)
+226 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11

#include "Hwc2TestLayer.h"

void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
        hwc2_display_t display, int32_t connected);
void hwc2TestVsyncCallback(hwc2_callback_data_t callbackData,
@@ -338,6 +340,23 @@ public:
        }
    }

    void setLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer,
            hwc2_composition_t composition, hwc2_error_t* outErr = nullptr)
    {
        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
                getFunction(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE));
        ASSERT_TRUE(pfn) << "failed to get function";

        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
                composition));
        if (outErr) {
            *outErr = err;
        } else {
            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer composition"
                    " type " << getCompositionName(composition);
        }
    }

protected:
    hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
    {
@@ -475,6 +494,152 @@ protected:
            *outTimestamp = mVsyncTimestamp;
    }

    /* Calls a set property function from Hwc2Test to set a property value from
     * Hwc2TestLayer to hwc2_layer_t on hwc2_display_t */
    using TestLayerPropertyFunction = void (*)(Hwc2Test* test,
            hwc2_display_t display, hwc2_layer_t layer,
            const Hwc2TestLayer& testLayer, hwc2_error_t* outErr);

    /* Calls a set property function from Hwc2Test to set a bad property value
     * on hwc2_layer_t on hwc2_display_t */
    using TestLayerPropertyBadLayerFunction = void (*)(Hwc2Test* test,
            hwc2_display_t display, hwc2_layer_t layer,
            const Hwc2TestLayer& testLayer, hwc2_error_t* outErr);

    /* Calls a set property function from Hwc2Test to set a bad property value
     * on hwc2_layer_t on hwc2_display_t */
    using TestLayerPropertyBadParameterFunction = void (*)(Hwc2Test* test,
            hwc2_display_t display, hwc2_layer_t layer, hwc2_error_t* outErr);

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

    /* For each active display it cycles through each display config and tests
     * each property value. It creates a layer, sets the property and then
     * destroys the layer */
    void setLayerProperty(Hwc2TestCoverage coverage,
            TestLayerPropertyFunction function, AdvanceProperty advance)
    {
        for (auto display : mDisplays) {
            std::vector<hwc2_config_t> configs;

            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));

            for (auto config : configs) {
                hwc2_layer_t layer;

                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
                Hwc2TestLayer testLayer(coverage);

                do {
                    ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));

                    ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
                            testLayer, nullptr));

                    ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
                } while (advance(&testLayer));
            }
        }
    }

    /* For each active display it cycles through each display config and tests
     * each property value. It creates a layer, cycles through each property
     * value and updates the layer property value and then destroys the layer */
    void setLayerPropertyUpdate(Hwc2TestCoverage coverage,
            TestLayerPropertyFunction function, AdvanceProperty advance)
    {
        for (auto display : mDisplays) {
            std::vector<hwc2_config_t> configs;

            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));

            for (auto config : configs) {
                hwc2_layer_t layer;

                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
                Hwc2TestLayer testLayer(coverage);

                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));

                do {
                    ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
                            testLayer, nullptr));
                } while (advance(&testLayer));

                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
            }
        }
    }

    /* For each active display it cycles through each display config.
     * 1) It attempts to set a valid property value to bad layer handle.
     * 2) It creates a layer x and attempts to set a valid property value to
     *    layer x + 1
     * 3) It destroys the layer x and attempts to set a valid property value to
     *    the destroyed layer x.
     */
    void setLayerPropertyBadLayer(Hwc2TestCoverage coverage,
            TestLayerPropertyBadLayerFunction function)
    {
        for (auto display : mDisplays) {
            std::vector<hwc2_config_t> configs;

            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));

            for (auto config : configs) {
                hwc2_layer_t layer = 0;
                hwc2_error_t err = HWC2_ERROR_NONE;

                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
                Hwc2TestLayer testLayer(coverage);

                ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
                        testLayer, &err));
                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";

                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));

                ASSERT_NO_FATAL_FAILURE(function(this, display, layer + 1,
                        testLayer, &err));
                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";

                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));

                ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
                        testLayer, &err));
                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
            }
        }
    }

    /* For each active display it cycles through each display config and tests
     * each property value. It creates a layer, sets a bad property value and
     * then destroys the layer */
    void setLayerPropertyBadParameter(TestLayerPropertyBadParameterFunction function)
    {
        for (auto display : mDisplays) {
            std::vector<hwc2_config_t> configs;

            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));

            for (auto config : configs) {
                hwc2_layer_t layer;
                hwc2_error_t err = HWC2_ERROR_NONE;

                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));

                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));

                ASSERT_NO_FATAL_FAILURE(function(this, display, layer, &err));
                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong"
                        " error code";

                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
            }
        }
    }

    hwc2_device_t* mHwc2Device = nullptr;

    enum class Hwc2TestHotplugStatus {
@@ -518,6 +683,32 @@ void hwc2TestVsyncCallback(hwc2_callback_data_t callbackData,
                timestamp);
}

void setComposition(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
        const Hwc2TestLayer& testLayer, hwc2_error_t* outErr)
{
    hwc2_composition_t composition = testLayer.getComposition();
    hwc2_error_t err = HWC2_ERROR_NONE;

    ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display, layer,
            composition, &err));
    if (outErr) {
        *outErr = err;
        return;
    }

    if (composition != HWC2_COMPOSITION_SIDEBAND) {
        EXPECT_EQ(err, HWC2_ERROR_NONE) << "returned wrong error code";
    } else {
        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_UNSUPPORTED)
                 << "returned wrong error code";
    }
}

bool advanceComposition(Hwc2TestLayer* testLayer)
{
    return testLayer->advanceComposition();
}


static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
    HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
@@ -1330,3 +1521,38 @@ TEST_F(Hwc2Test, GET_DISPLAY_NAME_bad_display)
    ASSERT_NO_FATAL_FAILURE(getDisplayName(display, &name, &err));
    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
}

/* TESTCASE: Tests that the HWC2 can set basic composition types. */
TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE)
{
    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
            setComposition, advanceComposition));
}

/* TESTCASE: Tests that the HWC2 can update a basic composition type on a
 * layer. */
TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_update)
{
    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
            setComposition, advanceComposition));
}

/* TESTCASE: Tests that the HWC2 cannot set a composition type for a bad layer */
TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_bad_layer)
{
    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
            setComposition));
}

/* TESTCASE: Tests that the HWC2 cannot set a bad composition type */
TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_bad_parameter)
{
    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadParameter(
            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
                    hwc2_error_t* outErr) {

                ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display,
                        layer, HWC2_COMPOSITION_INVALID, outErr));
            }
    ));
}
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>

#include "Hwc2TestLayer.h"

Hwc2TestLayer::Hwc2TestLayer(Hwc2TestCoverage coverage)
    : mComposition(coverage) { }

std::string Hwc2TestLayer::dump() const
{
    std::stringstream dmp;

    dmp << "layer: \n";
    dmp << mComposition.dump();

    return dmp.str();
}

void Hwc2TestLayer::reset()
{
    mComposition.reset();
}

hwc2_composition_t Hwc2TestLayer::getComposition() const
{
    return mComposition.get();
}

bool Hwc2TestLayer::advanceComposition()
{
    return mComposition.advance();
}
+44 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _HWC2_TEST_LAYER_H
#define _HWC2_TEST_LAYER_H

#include "Hwc2TestProperties.h"

#define HWC2_INCLUDE_STRINGIFICATION
#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11

class Hwc2TestLayer {
public:
    Hwc2TestLayer(Hwc2TestCoverage coverage);

    std::string dump() const;

    void reset();

    hwc2_composition_t getComposition() const;

    bool advanceComposition();

private:
    Hwc2TestComposition mComposition;
};

#endif /* ifndef _HWC2_TEST_LAYER_H */
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>

#include "Hwc2TestProperties.h"

Hwc2TestComposition::Hwc2TestComposition(Hwc2TestCoverage coverage)
    : Hwc2TestProperty(
            (coverage == Hwc2TestCoverage::Complete)? mCompleteCompositions:
            (coverage == Hwc2TestCoverage::Basic)? mBasicCompositions:
            mDefaultCompositions) { }

std::string Hwc2TestComposition::dump() const
{
    std::stringstream dmp;
    dmp << "\tcomposition: " << getCompositionName(get()) << "\n";
    return dmp.str();
}

const std::vector<hwc2_composition_t> Hwc2TestComposition::mDefaultCompositions = {
    HWC2_COMPOSITION_DEVICE,
};

const std::vector<hwc2_composition_t> Hwc2TestComposition::mBasicCompositions = {
    HWC2_COMPOSITION_CLIENT,
    HWC2_COMPOSITION_DEVICE,
};

const std::vector<hwc2_composition_t> Hwc2TestComposition::mCompleteCompositions = {
    HWC2_COMPOSITION_CLIENT,
    HWC2_COMPOSITION_DEVICE,
    HWC2_COMPOSITION_SOLID_COLOR,
    HWC2_COMPOSITION_CURSOR,
    HWC2_COMPOSITION_SIDEBAND,
};
Loading