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 <SkCanvas.h> 20 #include <SkDrawable.h> 21 #include <SkMatrix.h> 22 #include <utils/RefBase.h> 23 24 namespace android { 25 namespace uirenderer { 26 27 class RenderNode; 28 class RenderProperties; 29 30 namespace skiapipeline { 31 32 class SkiaDisplayList; 33 34 /** 35 * This drawable wraps a RenderNode and enables it to be recorded into a list 36 * of Skia drawing commands. 37 */ 38 class RenderNodeDrawable : public SkDrawable { 39 public: 40 /** 41 * Creates a new RenderNodeDrawable backed by a render node. 42 * 43 * @param node that has to be drawn 44 * @param canvas is a recording canvas used to extract its matrix 45 * @param composeLayer if the node's layer type is RenderLayer this flag determines whether 46 * we should draw into the contents of the layer or compose the existing contents of the 47 * layer into the canvas. 48 */ 49 explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true, 50 bool inReorderingSection = false) 51 : mRenderNode(node) 52 , mRecordedTransform(canvas->getTotalMatrix()) 53 , mComposeLayer(composeLayer) 54 , mInReorderingSection(inReorderingSection) {} 55 56 /** 57 * Draws into the canvas this render node and its children. If the node is marked as a 58 * projection receiver then all projected children (excluding direct children) will be drawn 59 * last. Any projected node not matching those requirements will not be drawn by this function. 60 */ 61 void forceDraw(SkCanvas* canvas); 62 63 /** 64 * Returns readonly render properties for this render node. 65 */ 66 const RenderProperties& getNodeProperties() const; 67 68 /** 69 * The renderNode (and its properties) that is to be drawn 70 */ 71 RenderNode* getRenderNode() const { return mRenderNode.get(); } 72 73 /** 74 * Returns the transform on the canvas at time of recording and is used for 75 * computing total transform without rerunning DL contents. 76 */ 77 const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; } 78 79 /** 80 * Sets a pointer to a display list of the parent render node. The display list is used when 81 * drawing backward projected nodes, when this node is a projection receiver. 82 */ 83 void setProjectedDisplayList(SkiaDisplayList* projectedDisplayList) { 84 mProjectedDisplayList = projectedDisplayList; 85 } 86 87 protected: 88 /* 89 * Return the (conservative) bounds of what the drawable will draw. 90 */ 91 virtual SkRect onGetBounds() override { 92 // We don't want to enable a record time quick reject because the properties 93 // of the RenderNode may be updated on subsequent frames. 94 return SkRect::MakeLargest(); 95 } 96 /** 97 * This function draws into a canvas as forceDraw, but does nothing if the render node has a 98 * non-zero elevation. 99 */ 100 virtual void onDraw(SkCanvas* canvas) override; 101 102 private: 103 /* 104 * Render node that is wrapped by this class. 105 */ 106 sp<RenderNode> mRenderNode; 107 108 /** 109 * Walks recursively the display list and draws the content of backward projected nodes. 110 * 111 * @param canvas used to draw the backward projected nodes 112 * @param displayList is a display list that contains a projection receiver 113 * @param nestLevel should be always 0. Used to track how far we are from the receiver. 114 */ 115 void drawBackwardsProjectedNodes(SkCanvas* canvas, const SkiaDisplayList& displayList, 116 int nestLevel = 0); 117 118 /** 119 * Applies the rendering properties of a view onto a SkCanvas. 120 */ 121 static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas, 122 float* alphaMultiplier); 123 124 /** 125 * Stores transform on the canvas at time of recording and is used for 126 * computing total transform without rerunning DL contents. 127 */ 128 const SkMatrix mRecordedTransform; 129 130 /** 131 * If mRenderNode's layer type is RenderLayer this flag determines whether we 132 * should draw into the contents of the layer or compose the existing contents 133 * of the layer into the canvas. 134 */ 135 const bool mComposeLayer; 136 137 /* 138 * True if the render node is in a reordering section 139 */ 140 bool mInReorderingSection; 141 142 /* 143 * Draw the content into a canvas, depending on the render node layer type and mComposeLayer. 144 */ 145 void drawContent(SkCanvas* canvas) const; 146 147 /* 148 * display list that is searched for any render nodes with getProjectBackwards==true 149 */ 150 SkiaDisplayList* mProjectedDisplayList = nullptr; 151 }; 152 153 }; // namespace skiapipeline 154 }; // namespace uirenderer 155 }; // namespace android 156