Fix Skia render node projection to match HWUI

Fix Skia render node projection to match HWUI. Port
FrameBuilderTests_projectionReorder test for Skia pipeline.
Add new tests in both HWUI and Skia to cover more projection
use cases.

Test: built and run on angler-eng
Change-Id: Ibf27af211452ae95d595aca7723ea63f48b0b282
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index a2ffc6c..3eed647 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -29,6 +29,8 @@
 
 namespace skiapipeline {
 
+class SkiaDisplayList;
+
 /**
  * This drawable wraps a RenderNode and enables it to be recorded into a list
  * of Skia drawing commands.
@@ -36,18 +38,6 @@
 class RenderNodeDrawable : public SkDrawable {
 public:
     /**
-     * This struct contains a pointer to a node that is to be
-     * projected into the drawing order of its closest ancestor
-     * (excluding its parent) that is marked as a projection
-     * receiver. The matrix is used to ensure that the node is
-     * drawn with same matrix as it would have prior to projection.
-     */
-    struct ProjectedChild {
-        const RenderNodeDrawable* node;
-        const SkMatrix matrix;
-    };
-
-    /**
      * Creates a new RenderNodeDrawable backed by a render node.
      *
      * @param node that has to be drawn
@@ -86,6 +76,14 @@
      */
     const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
 
+    /**
+     * Sets a pointer to a display list of the parent render node. The display list is used when
+     * drawing backward projected nodes, when this node is a projection receiver.
+     */
+    void setProjectedDisplayList(SkiaDisplayList* projectedDisplayList) {
+        mProjectedDisplayList = projectedDisplayList;
+    }
+
 protected:
     /*
      * Return the (conservative) bounds of what the drawable will draw.
@@ -108,6 +106,16 @@
     sp<RenderNode> mRenderNode;
 
     /**
+     * Walks recursively the display list and draws the content of backward projected nodes.
+     *
+     * @param canvas used to draw the backward projected nodes
+     * @param displayList is a display list that contains a projection receiver
+     * @param nestLevel should be always 0. Used to track how far we are from the receiver.
+     */
+    void drawBackwardsProjectedNodes(SkCanvas* canvas, const SkiaDisplayList& displayList,
+            int nestLevel = 0);
+
+    /**
      * Applies the rendering properties of a view onto a SkCanvas.
      */
     static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
@@ -126,19 +134,6 @@
      */
     const bool mComposeLayer;
 
-    /**
-     * List to which we will add any projected children we encounter while walking our descendents.
-     * This pointer is valid only while the node (including its children) is actively being drawn.
-     */
-    std::vector<ProjectedChild>* mProjectedChildrenTarget = nullptr;
-
-    /**
-     * The value to which we should set our children's mProjectedChildrenTarget. We use two pointers
-     * (mProjectedChildrenTarget and mNextProjectedChildrenTarget) because we need to skip over our
-     * parent when looking for a projection receiver.
-     */
-    std::vector<ProjectedChild>* mNextProjectedChildrenTarget = nullptr;
-
     /*
      * True if the render node is in a reordering section
      */
@@ -148,6 +143,11 @@
      *  Draw the content into a canvas, depending on the render node layer type and mComposeLayer.
      */
     void drawContent(SkCanvas* canvas) const;
+
+    /*
+     * display list that is searched for any render nodes with getProjectBackwards==true
+     */
+    SkiaDisplayList* mProjectedDisplayList = nullptr;
 };
 
 }; // namespace skiapipeline