• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "SkiaUtils.h"
20 
21 #include <SkBlendMode.h>
22 #include <SkCanvas.h>
23 #include <SkDrawable.h>
24 #include <SkMatrix.h>
25 #include <utils/RefBase.h>
26 
27 namespace android {
28 namespace uirenderer {
29 
30 class RenderNode;
31 class RenderProperties;
32 
33 namespace skiapipeline {
34 
35 class SkiaDisplayList;
36 
37 /**
38  * This drawable wraps a RenderNode and enables it to be recorded into a list
39  * of Skia drawing commands.
40  */
41 class RenderNodeDrawable : public SkDrawable {
42 public:
43     /**
44      * Creates a new RenderNodeDrawable backed by a render node.
45      *
46      * @param node that has to be drawn
47      * @param canvas is a recording canvas used to extract its matrix
48      * @param composeLayer if the node's layer type is RenderLayer this flag determines whether
49      *      we should draw into the contents of the layer or compose the existing contents of the
50      *      layer into the canvas.
51      */
52     explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true,
53                                 bool inReorderingSection = false);
54 
55     ~RenderNodeDrawable();
56 
57     /**
58      * Draws into the canvas this render node and its children. If the node is marked as a
59      * projection receiver then all projected children (excluding direct children) will be drawn
60      * last. Any projected node not matching those requirements will not be drawn by this function.
61      */
62     void forceDraw(SkCanvas* canvas) const;
63 
64     /**
65      * Returns readonly render properties for this render node.
66      */
67     const RenderProperties& getNodeProperties() const;
68 
69     /**
70      * The renderNode (and its properties) that is to be drawn
71      */
getRenderNode()72     RenderNode* getRenderNode() const { return mRenderNode.get(); }
73 
74     /**
75      * Returns the transform on the canvas at time of recording and is used for
76      * computing total transform without rerunning DL contents.
77      */
getRecordedMatrix()78     const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
79 
80     /**
81      * Sets a pointer to a display list of the parent render node. The display list is used when
82      * drawing backward projected nodes, when this node is a projection receiver.
83      */
setProjectedDisplayList(SkiaDisplayList * projectedDisplayList)84     void setProjectedDisplayList(SkiaDisplayList* projectedDisplayList) {
85         mProjectedDisplayList = projectedDisplayList;
86     }
87 
88 protected:
89     /*
90      * Return the (conservative) bounds of what the drawable will draw.
91      */
onGetBounds()92     virtual SkRect onGetBounds() override {
93         // We don't want to enable a record time quick reject because the properties
94         // of the RenderNode may be updated on subsequent frames.
95         return SkRectMakeLargest();
96     }
97     /**
98      * This function draws into a canvas as forceDraw, but does nothing if the render node has a
99      * non-zero elevation.
100      */
101     virtual void onDraw(SkCanvas* canvas) override;
102 
103 private:
104     /*
105      * Render node that is wrapped by this class.
106      */
107     sp<RenderNode> mRenderNode;
108 
109     /**
110      * Walks recursively the display list and draws the content of backward projected nodes.
111      *
112      * @param canvas used to draw the backward projected nodes
113      * @param displayList is a display list that contains a projection receiver
114      * @param nestLevel should be always 0. Used to track how far we are from the receiver.
115      */
116     void drawBackwardsProjectedNodes(SkCanvas* canvas, const SkiaDisplayList& displayList,
117                                      int nestLevel = 0) const;
118 
119     /**
120      * Applies the rendering properties of a view onto a SkCanvas.
121      */
122     static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
123                                   float* alphaMultiplier, bool ignoreLayer = false);
124 
125     /**
126      * Stores transform on the canvas at time of recording and is used for
127      * computing total transform without rerunning DL contents.
128      */
129     const SkMatrix mRecordedTransform;
130 
131     /**
132      * If mRenderNode's layer type is RenderLayer this flag determines whether we
133      * should draw into the contents of the layer or compose the existing contents
134      * of the layer into the canvas.
135      */
136     const bool mComposeLayer;
137 
138     /*
139      * True if the render node is in a reordering section
140      */
141     bool mInReorderingSection;
142 
143     /*
144      *  Draw the content into a canvas, depending on the render node layer type and mComposeLayer.
145      */
146     void drawContent(SkCanvas* canvas) const;
147 
148     /*
149      * display list that is searched for any render nodes with getProjectBackwards==true
150      */
151     SkiaDisplayList* mProjectedDisplayList = nullptr;
152 
153     /**
154      * Allow BackdropFilterDrawable to apply same render properties onto SkCanvas.
155      */
156     friend class BackdropFilterDrawable;
157 };
158 
159 }  // namespace skiapipeline
160 }  // namespace uirenderer
161 }  // namespace android
162