/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "SkiaUtils.h" #include <SkCanvas.h> #include <SkDrawable.h> #include <SkMatrix.h> #include <utils/RefBase.h> namespace android { namespace uirenderer { class RenderNode; class RenderProperties; namespace skiapipeline { class SkiaDisplayList; /** * This drawable wraps a RenderNode and enables it to be recorded into a list * of Skia drawing commands. */ class RenderNodeDrawable : public SkDrawable { public: /** * Creates a new RenderNodeDrawable backed by a render node. * * @param node that has to be drawn * @param canvas is a recording canvas used to extract its matrix * @param composeLayer if the node's layer type is RenderLayer this flag determines whether * we should draw into the contents of the layer or compose the existing contents of the * layer into the canvas. */ explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true, bool inReorderingSection = false); ~RenderNodeDrawable(); /** * Draws into the canvas this render node and its children. If the node is marked as a * projection receiver then all projected children (excluding direct children) will be drawn * last. Any projected node not matching those requirements will not be drawn by this function. */ void forceDraw(SkCanvas* canvas); /** * Returns readonly render properties for this render node. */ const RenderProperties& getNodeProperties() const; /** * The renderNode (and its properties) that is to be drawn */ RenderNode* getRenderNode() const { return mRenderNode.get(); } /** * Returns the transform on the canvas at time of recording and is used for * computing total transform without rerunning DL contents. */ 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. */ virtual SkRect onGetBounds() override { // We don't want to enable a record time quick reject because the properties // of the RenderNode may be updated on subsequent frames. return SkRectMakeLargest(); } /** * This function draws into a canvas as forceDraw, but does nothing if the render node has a * non-zero elevation. */ virtual void onDraw(SkCanvas* canvas) override; private: /* * Render node that is wrapped by this class. */ 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, float* alphaMultiplier); /** * Stores transform on the canvas at time of recording and is used for * computing total transform without rerunning DL contents. */ const SkMatrix mRecordedTransform; /** * If mRenderNode's layer type is RenderLayer this flag determines whether we * should draw into the contents of the layer or compose the existing contents * of the layer into the canvas. */ const bool mComposeLayer; /* * True if the render node is in a reordering section */ bool mInReorderingSection; /* * 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 } // namespace uirenderer } // namespace android