test-hwc2: set layer visible region

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: I0e620fa6763d258d7875da9bf85d41c182e015d2
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp
index 02a9df1..15a5f77 100644
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp
+++ b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp
@@ -21,13 +21,22 @@
 Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
         Hwc2TestCoverage coverage, const Area& displayArea)
 {
-    uint32_t nextZOrder = 0;
-
     for (auto layer : layers) {
         mTestLayers.emplace(std::piecewise_construct,
                 std::forward_as_tuple(layer),
-                std::forward_as_tuple(coverage, displayArea, nextZOrder++));
+                std::forward_as_tuple(coverage, displayArea));
     }
+
+    /* Iterate over the layers in order and assign z orders in the same order.
+     * This allows us to iterate over z orders in the same way when computing
+     * visible regions */
+    uint32_t nextZOrder = layers.size();
+
+    for (auto& testLayer : mTestLayers) {
+        testLayer.second.setZOrder(nextZOrder--);
+    }
+
+    setVisibleRegions();
 }
 
 std::string Hwc2TestLayers::dump() const
@@ -44,6 +53,28 @@
     for (auto& testLayer : mTestLayers) {
         testLayer.second.reset();
     }
+
+    setVisibleRegions();
+}
+
+bool Hwc2TestLayers::advanceVisibleRegions()
+{
+    for (auto& testLayer : mTestLayers) {
+        if (testLayer.second.advanceVisibleRegion()) {
+            setVisibleRegions();
+            return true;
+        }
+        testLayer.second.reset();
+    }
+    return false;
+}
+
+hwc_region_t Hwc2TestLayers::getVisibleRegion(hwc2_layer_t layer) const
+{
+    if (mTestLayers.count(layer) == 0) {
+        []() { GTEST_FAIL(); }();
+    }
+    return mTestLayers.at(layer).getVisibleRegion();
 }
 
 uint32_t Hwc2TestLayers::getZOrder(hwc2_layer_t layer) const
@@ -53,3 +84,31 @@
     }
     return mTestLayers.at(layer).getZOrder();
 }
+
+void Hwc2TestLayers::setVisibleRegions()
+{
+    /* The region of the display that is covered by layers above the current
+     * layer */
+    android::Region aboveOpaqueLayers;
+
+    /* Iterate over test layers from max z order to min z order. */
+    for (auto& testLayer : mTestLayers) {
+        android::Region visibleRegion;
+
+        /* Set the visible region of this layer */
+        const hwc_rect_t displayFrame = testLayer.second.getDisplayFrame();
+
+        visibleRegion.set(android::Rect(displayFrame.left, displayFrame.top,
+                displayFrame.right, displayFrame.bottom));
+
+        /* Remove the area covered by opaque layers above this layer
+         * from this layer's visible region */
+        visibleRegion.subtractSelf(aboveOpaqueLayers);
+
+        testLayer.second.setVisibleRegion(visibleRegion);
+
+        /* If this layer is opaque, store the region it covers */
+        if (testLayer.second.getPlaneAlpha() == 1.0f)
+            aboveOpaqueLayers.orSelf(visibleRegion);
+    }
+}