OSDN Git Service

test-hwc2: virtual displays
authorMarissa Wall <marissaw@google.com>
Tue, 21 Feb 2017 22:33:46 +0000 (14:33 -0800)
committerMarissa Wall <marissaw@google.com>
Wed, 8 Mar 2017 22:57:33 +0000 (14:57 -0800)
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: Ia10ec761712ee03f56782e3df2d6eabf7fb77760

services/surfaceflinger/tests/hwc2/Android.mk
services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp
services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h
services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp [new file with mode: 0644]
services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h [new file with mode: 0644]

index f7403cf..b8c2133 100644 (file)
@@ -47,6 +47,7 @@ LOCAL_SRC_FILES := \
     Hwc2TestLayer.cpp \
     Hwc2TestLayers.cpp \
     Hwc2TestBuffer.cpp \
-    Hwc2TestClientTarget.cpp
+    Hwc2TestClientTarget.cpp \
+    Hwc2TestVirtualDisplay.cpp
 
 include $(BUILD_NATIVE_TEST)
index 840f67d..751a9cc 100644 (file)
@@ -32,6 +32,7 @@
 #include "Hwc2TestLayer.h"
 #include "Hwc2TestLayers.h"
 #include "Hwc2TestClientTarget.h"
+#include "Hwc2TestVirtualDisplay.h"
 
 void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
         hwc2_display_t display, int32_t connected);
@@ -77,6 +78,13 @@ public:
             setPowerMode(display, HWC2_POWER_MODE_OFF);
         }
 
+        for (auto itr = mVirtualDisplays.begin(); itr != mVirtualDisplays.end();) {
+            hwc2_display_t display = *itr;
+            itr++;
+            /* Destroys virtual displays */
+            destroyVirtualDisplay(display);
+        }
+
         if (mHwc2Device)
             hwc2_close(mHwc2Device);
     }
@@ -949,6 +957,71 @@ public:
         }
     }
 
+    void createVirtualDisplay(uint32_t width, uint32_t height,
+            android_pixel_format_t* outFormat, hwc2_display_t* outDisplay,
+            hwc2_error_t* outErr = nullptr)
+    {
+        auto pfn = reinterpret_cast<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
+                getFunction(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY));
+        ASSERT_TRUE(pfn) << "failed to get function";
+
+        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, width, height,
+                reinterpret_cast<int32_t*>(outFormat), outDisplay));
+
+        if (err == HWC2_ERROR_NONE)
+            mVirtualDisplays.insert(*outDisplay);
+
+        if (outErr) {
+            *outErr = err;
+        } else {
+            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create virtual display";
+        }
+    }
+
+    void destroyVirtualDisplay(hwc2_display_t display,
+            hwc2_error_t* outErr = nullptr)
+    {
+        auto pfn = reinterpret_cast<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
+                getFunction(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY));
+        ASSERT_TRUE(pfn) << "failed to get function";
+
+        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display));
+
+        if (err == HWC2_ERROR_NONE)
+            mVirtualDisplays.erase(display);
+
+        if (outErr) {
+            *outErr = err;
+        } else {
+            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to destroy virtual display";
+        }
+    }
+
+    void getMaxVirtualDisplayCount(uint32_t* outMaxCnt)
+    {
+        auto pfn = reinterpret_cast<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
+                getFunction(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT));
+        ASSERT_TRUE(pfn) << "failed to get function";
+
+        *outMaxCnt = pfn(mHwc2Device);
+    }
+
+    void setOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
+            int32_t releaseFence, hwc2_error_t* outErr = nullptr)
+    {
+        auto pfn = reinterpret_cast<HWC2_PFN_SET_OUTPUT_BUFFER>(
+                getFunction(HWC2_FUNCTION_SET_OUTPUT_BUFFER));
+        ASSERT_TRUE(pfn) << "failed to get function";
+
+        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, buffer,
+                releaseFence));
+        if (outErr) {
+            *outErr = err;
+        } else {
+            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set output buffer";
+        }
+    }
+
     void getBadDisplay(hwc2_display_t* outDisplay)
     {
         for (hwc2_display_t display = 0; display < UINT64_MAX; display++) {
@@ -1129,6 +1202,10 @@ protected:
     using TestActiveDisplayConfigFunction = void (*)(Hwc2Test* test,
             hwc2_display_t display);
 
+    /* Tests a newly created virtual display */
+    using TestCreateVirtualDisplayFunction = void (*)(Hwc2Test* test,
+            hwc2_display_t display, Hwc2TestVirtualDisplay* testVirtualDisplay);
+
     /* Advances a property of Hwc2TestLayer */
     using AdvanceProperty = bool (*)(Hwc2TestLayer* testLayer);
 
@@ -1441,6 +1518,40 @@ protected:
         }
     }
 
+    /* Creates a virtual display for testing */
+    void createVirtualDisplay(Hwc2TestCoverage coverage,
+            TestCreateVirtualDisplayFunction function)
+    {
+        Hwc2TestVirtualDisplay testVirtualDisplay(coverage);
+
+        do {
+            hwc2_display_t display;
+            hwc2_error_t err = HWC2_ERROR_NONE;
+
+            const UnsignedArea& dimension =
+                    testVirtualDisplay.getDisplayDimension();
+            android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+
+            ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(dimension.width,
+                    dimension.height, &desiredFormat, &display, &err));
+
+            EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_NO_RESOURCES
+                    || err == HWC2_ERROR_UNSUPPORTED)
+                    << "returned wrong error code";
+            EXPECT_GE(desiredFormat, 0) << "invalid format";
+
+            if (err != HWC2_ERROR_NONE)
+                continue;
+
+            EXPECT_NO_FATAL_FAILURE(function(this, display,
+                    &testVirtualDisplay));
+
+            ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
+
+        } while (testVirtualDisplay.advance());
+    }
+
+
     void getActiveConfigAttribute(hwc2_display_t display,
             hwc2_attribute_t attribute, int32_t* outValue)
     {
@@ -1664,6 +1775,10 @@ protected:
      * tearing down the test cases, change it to HWC2_POWER_MODE_OFF */
     std::set<hwc2_display_t> mActiveDisplays;
 
+    /* Store all created virtual displays that have not been destroyed. If an
+     * ASSERT_* fails, then destroy the virtual displays on exit */
+    std::set<hwc2_display_t> mVirtualDisplays;
+
     std::mutex mVsyncMutex;
     std::condition_variable mVsyncCv;
     hwc2_display_t mVsyncDisplay;
@@ -4219,3 +4334,198 @@ TEST_F(Hwc2Test, SET_COLOR_TRANSFORM_arbitrary_matrix)
             }
     ));
 }
+
+/* TESTCASE: Tests that the HWC2 create an destory virtual displays. */
+TEST_F(Hwc2Test, CREATE_DESTROY_VIRTUAL_DISPLAY)
+{
+    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Complete,
+            [] (Hwc2Test* /*test*/, hwc2_display_t /*display*/,
+                    Hwc2TestVirtualDisplay* /*testVirtualDisplay*/) { }));
+}
+
+/* TESTCASE: Tests that the HWC2 can create and destroy multiple virtual
+ * displays. */
+TEST_F(Hwc2Test, CREATE_DESTROY_VIRTUAL_DISPLAY_multiple)
+{
+    Hwc2TestVirtualDisplay testVirtualDisplay(Hwc2TestCoverage::Complete);
+    std::vector<hwc2_display_t> displays;
+
+    do {
+        const UnsignedArea& dimension =
+                testVirtualDisplay.getDisplayDimension();
+        android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+        hwc2_display_t display;
+        hwc2_error_t err = HWC2_ERROR_NONE;
+
+        ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(dimension.width,
+                dimension.height, &desiredFormat, &display, &err));
+
+        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_NO_RESOURCES
+                || err == HWC2_ERROR_UNSUPPORTED) << "returned wrong error code";
+        EXPECT_GE(desiredFormat, 0) << "invalid format";
+
+        if (err == HWC2_ERROR_NONE)
+            displays.push_back(display);
+
+    } while (testVirtualDisplay.advance());
+
+    for (hwc2_display_t display : displays) {
+        EXPECT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
+    }
+}
+
+/* TESTCASE: Tests that the HWC2 cannot destroy a bad virtual displays.  */
+TEST_F(Hwc2Test, DESTROY_VIRTUAL_DISPLAY_bad_display)
+{
+    hwc2_display_t display;
+    hwc2_error_t err = HWC2_ERROR_NONE;
+
+    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
+
+    ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display, &err));
+    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
+}
+
+/* TESTCASE: Tests that the HWC2 cannot destroy a physical display. */
+TEST_F(Hwc2Test, DESTROY_VIRTUAL_DISPLAY_bad_parameter)
+{
+    hwc2_display_t display = HWC_DISPLAY_PRIMARY;
+    hwc2_error_t err = HWC2_ERROR_NONE;
+
+    ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display, &err));
+    EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
+}
+
+/* TESTCASE: Tests that the HWC2 can get the max virtual display count. */
+TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT)
+{
+    uint32_t maxCnt;
+
+    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt));
+}
+
+/* TESTCASE: Tests that the HWC2 returns the same max virtual display count for
+ * each call. */
+TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT_duplicate)
+{
+    uint32_t maxCnt1, maxCnt2;
+
+    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt1));
+    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt2));
+
+    EXPECT_EQ(maxCnt1, maxCnt2) << "returned two different max virtual display"
+            " counts";
+}
+
+/* TESTCASE: Tests that the HWC2 can create the max number of virtual displays
+ * that it reports. */
+TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT_create_max)
+{
+    std::vector<hwc2_display_t> displays;
+    uint32_t maxCnt;
+
+    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt));
+
+    while (displays.size() < maxCnt) {
+        uint32_t width = 1920, height = 1080;
+        android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+        hwc2_display_t display;
+        hwc2_error_t err = HWC2_ERROR_NONE;
+
+        ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(width, height,
+                    &desiredFormat, &display, &err));
+
+        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_UNSUPPORTED)
+                << "returned wrong error code";
+        if (err != HWC2_ERROR_NONE)
+            break;
+
+        displays.push_back(display);
+    }
+
+    for (hwc2_display_t display : displays) {
+        EXPECT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
+    }
+}
+
+/* TESTCASE: Tests that the HWC2 can set an output buffer for a virtual
+ * display. */
+TEST_F(Hwc2Test, SET_OUTPUT_BUFFER)
+{
+    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Complete,
+            [] (Hwc2Test* test, hwc2_display_t display,
+                    Hwc2TestVirtualDisplay* testVirtualDisplay) {
+
+                buffer_handle_t handle;
+                android::base::unique_fd acquireFence;
+
+                if (testVirtualDisplay->getBuffer(&handle, &acquireFence) >= 0)
+                    EXPECT_NO_FATAL_FAILURE(test->setOutputBuffer(display,
+                            handle, acquireFence));
+            }));
+}
+
+/* TESTCASE: Tests that the HWC2 cannot set an output buffer for a bad display */
+TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_bad_display)
+{
+    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Default,
+            [] (Hwc2Test* test, hwc2_display_t /*display*/,
+                    Hwc2TestVirtualDisplay* testVirtualDisplay) {
+
+                hwc2_display_t badDisplay;
+                buffer_handle_t handle;
+                android::base::unique_fd acquireFence;
+                hwc2_error_t err = HWC2_ERROR_NONE;
+
+                ASSERT_NO_FATAL_FAILURE(test->getBadDisplay(&badDisplay));
+
+                if (testVirtualDisplay->getBuffer(&handle, &acquireFence) < 0)
+                    return;
+
+                ASSERT_NO_FATAL_FAILURE(test->setOutputBuffer(badDisplay,
+                        handle, acquireFence, &err));
+                EXPECT_TRUE(err == HWC2_ERROR_BAD_DISPLAY)
+                        << "returned wrong error code";
+            }));
+}
+
+/* TESTCASE: Tests that the HWC2 cannot set an invalid output buffer. */
+TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_bad_parameter)
+{
+    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Default,
+            [] (Hwc2Test* test, hwc2_display_t display,
+                    Hwc2TestVirtualDisplay* /*testVirtualDisplay*/) {
+
+                const buffer_handle_t handle = nullptr;
+                uint32_t releaseFence = -1;
+                hwc2_error_t err = HWC2_ERROR_NONE;
+
+                ASSERT_NO_FATAL_FAILURE(test->setOutputBuffer(display, handle,
+                        releaseFence, &err));
+                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER)
+                        << "returned wrong error code";
+            }));
+}
+
+/* TESTCASE: Tests that the HWC2 cannot set an output buffer for non virtual
+ * display */
+TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_unsupported)
+{
+    for (auto display : mDisplays) {
+        Hwc2TestVirtualDisplay testVirtualDisplay(Hwc2TestCoverage::Complete);
+
+        do {
+            buffer_handle_t handle;
+            android::base::unique_fd acquireFence;
+            hwc2_error_t err = HWC2_ERROR_NONE;
+
+            if (testVirtualDisplay.getBuffer(&handle, &acquireFence) < 0)
+                continue;
+
+            ASSERT_NO_FATAL_FAILURE(setOutputBuffer(display, handle,
+                    acquireFence, &err));
+            EXPECT_EQ(err, HWC2_ERROR_UNSUPPORTED) << "returned wrong error code";
+
+        } while (testVirtualDisplay.advance());
+    }
+}
index e00c560..b5522de 100644 (file)
@@ -321,6 +321,63 @@ const std::vector<android_dataspace_t> Hwc2TestDataspace::completeDataspaces = {
 };
 
 
+Hwc2TestDisplayDimension::Hwc2TestDisplayDimension(Hwc2TestCoverage coverage)
+    : Hwc2TestProperty(
+            (coverage == Hwc2TestCoverage::Complete)? mCompleteDisplayDimensions:
+            (coverage == Hwc2TestCoverage::Basic)? mBasicDisplayDimensions:
+            mDefaultDisplayDimensions, mCompositionSupport) { }
+
+std::string Hwc2TestDisplayDimension::dump() const
+{
+    std::stringstream dmp;
+    const UnsignedArea& curr = get();
+    dmp << "\tdisplay dimension: " << curr.width<< " x " << curr.height<< "\n";
+    return dmp.str();
+}
+
+void Hwc2TestDisplayDimension::setDependent(Hwc2TestBuffer* buffer)
+{
+    mBuffer = buffer;
+    updateDependents();
+}
+
+void Hwc2TestDisplayDimension::updateDependents()
+{
+    const UnsignedArea& curr = get();
+
+    if (mBuffer)
+        mBuffer->updateBufferArea({static_cast<int32_t>(curr.width),
+                static_cast<int32_t>(curr.height)});
+}
+
+const std::vector<UnsignedArea>
+        Hwc2TestDisplayDimension::mDefaultDisplayDimensions = {
+    {1920, 1080},
+};
+
+const std::vector<UnsignedArea>
+        Hwc2TestDisplayDimension::mBasicDisplayDimensions = {
+    {640, 480},
+    {1280, 720},
+    {1920, 1080},
+    {1920, 1200},
+};
+
+const std::vector<UnsignedArea>
+        Hwc2TestDisplayDimension::mCompleteDisplayDimensions = {
+    {320, 240},
+    {480, 320},
+    {640, 480},
+    {1280, 720},
+    {1920, 1080},
+    {1920, 1200},
+    {2560, 1440},
+    {2560, 1600},
+    {3840, 2160},
+    {4096, 2160},
+};
+
+
 Hwc2TestDisplayFrame::Hwc2TestDisplayFrame(Hwc2TestCoverage coverage,
         const Area& displayArea)
     : Hwc2TestProperty(mDisplayFrames, mCompositionSupport),
@@ -695,6 +752,11 @@ const std::array<bool, 6> Hwc2TestDataspace::mCompositionSupport = {{
 }};
 
 /*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
+const std::array<bool, 6> Hwc2TestDisplayDimension::mCompositionSupport = {{
+    false,   true,    true,    true,    true,    true,
+}};
+
+/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
 const std::array<bool, 6> Hwc2TestDisplayFrame::mCompositionSupport = {{
     false,   true,    true,    true,    false,   true,
 }};
index d978237..c2029ab 100644 (file)
@@ -54,6 +54,12 @@ typedef struct {
 } Area;
 
 
+typedef struct {
+    uint32_t width;
+    uint32_t height;
+} UnsignedArea;
+
+
 class Hwc2TestContainer {
 public:
     virtual ~Hwc2TestContainer() = default;
@@ -238,6 +244,27 @@ protected:
 };
 
 
+class Hwc2TestDisplayDimension : public Hwc2TestProperty<UnsignedArea> {
+public:
+    Hwc2TestDisplayDimension(Hwc2TestCoverage coverage);
+
+    std::string dump() const;
+
+    void setDependent(Hwc2TestBuffer* buffer);
+
+private:
+    void updateDependents();
+
+    Hwc2TestBuffer* mBuffer;
+
+    static const std::vector<UnsignedArea> mDefaultDisplayDimensions;
+    static const std::vector<UnsignedArea> mBasicDisplayDimensions;
+    static const std::vector<UnsignedArea> mCompleteDisplayDimensions;
+
+    static const std::array<bool, 6> mCompositionSupport;
+};
+
+
 class Hwc2TestDisplayFrame : public Hwc2TestProperty<hwc_rect_t> {
 public:
     Hwc2TestDisplayFrame(Hwc2TestCoverage coverage, const Area& displayArea);
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp
new file mode 100644 (file)
index 0000000..d0fbc0b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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 "Hwc2TestVirtualDisplay.h"
+
+Hwc2TestVirtualDisplay::Hwc2TestVirtualDisplay(
+        Hwc2TestCoverage coverage)
+    : mDisplayDimension(coverage)
+{
+    mDisplayDimension.setDependent(&mBuffer);
+}
+
+std::string Hwc2TestVirtualDisplay::dump() const
+{
+    std::stringstream dmp;
+
+    dmp << "virtual display: \n";
+
+    mDisplayDimension.dump();
+
+    return dmp.str();
+}
+
+int Hwc2TestVirtualDisplay::getBuffer(buffer_handle_t* outHandle,
+        android::base::unique_fd* outAcquireFence)
+{
+    int32_t acquireFence;
+    int ret = mBuffer.get(outHandle, &acquireFence);
+    outAcquireFence->reset(acquireFence);
+    return ret;
+}
+
+void Hwc2TestVirtualDisplay::reset()
+{
+    return mDisplayDimension.reset();
+}
+
+bool Hwc2TestVirtualDisplay::advance()
+{
+    return mDisplayDimension.advance();
+}
+
+UnsignedArea Hwc2TestVirtualDisplay::getDisplayDimension() const
+{
+    return mDisplayDimension.get();
+}
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h
new file mode 100644 (file)
index 0000000..09420ef
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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_VIRTUAL_DISPLAY_H
+#define _HWC2_TEST_VIRTUAL_DISPLAY_H
+
+#include "Hwc2TestBuffer.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 Hwc2TestVirtualDisplay {
+public:
+    Hwc2TestVirtualDisplay(Hwc2TestCoverage coverage);
+
+    std::string dump() const;
+
+    int getBuffer(buffer_handle_t* outHandle,
+            android::base::unique_fd* outAcquireFence);
+
+    void reset();
+    bool advance();
+
+    UnsignedArea getDisplayDimension() const;
+
+private:
+    Hwc2TestBuffer mBuffer;
+
+    Hwc2TestDisplayDimension mDisplayDimension;
+};
+
+#endif /* ifndef _HWC2_TEST_VIRTUAL_DISPLAY_H */