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