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