Home | History | Annotate | Download | only in skia
      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 "DisplayList.h"
     20 #include "hwui/AnimatedImageDrawable.h"
     21 #include "GLFunctorDrawable.h"
     22 #include "RenderNodeDrawable.h"
     23 
     24 #include <SkLiteDL.h>
     25 #include <SkLiteRecorder.h>
     26 #include <deque>
     27 
     28 namespace android {
     29 namespace uirenderer {
     30 
     31 class Outline;
     32 
     33 namespace skiapipeline {
     34 
     35 /**
     36  * This class is intended to be self contained, but still subclasses from
     37  * DisplayList to make it easier to support switching between the two at
     38  * runtime.  The downside of this inheritance is that we pay for the overhead
     39  * of the parent class construction/destruction without any real benefit.
     40  */
     41 class SkiaDisplayList : public DisplayList {
     42 public:
     43     SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
     44     virtual ~SkiaDisplayList() {
     45         /* Given that we are using a LinearStdAllocator to store some of the
     46          * SkDrawable contents we must ensure that any other object that is
     47          * holding a reference to those drawables is destroyed prior to their
     48          * deletion.
     49          */
     50         mDisplayList.reset();
     51     }
     52 
     53     /**
     54      * This resets the DisplayList so that it behaves as if the object were newly
     55      * constructed.  The reuse avoids any overhead associated with destroying
     56      * the SkLiteDL as well as the deques and vectors.
     57      */
     58     void reset();
     59 
     60     /**
     61      * Use the linear allocator to create any SkDrawables needed by the display
     62      * list. This could be dangerous as these objects are ref-counted, so we
     63      * need to monitor that they don't extend beyond the lifetime of the class
     64      * that creates them. Allocator dtor invokes all SkDrawable dtors.
     65      */
     66     template <class T, typename... Params>
     67     SkDrawable* allocateDrawable(Params&&... params) {
     68         return allocator.create<T>(std::forward<Params>(params)...);
     69     }
     70 
     71     bool isSkiaDL() const override { return true; }
     72 
     73     /**
     74      * Returns true if the DisplayList does not have any recorded content
     75      */
     76     bool isEmpty() const override { return mDisplayList.empty(); }
     77 
     78     /**
     79      * Returns true if this list directly contains a GLFunctor drawing command.
     80      */
     81     bool hasFunctor() const override { return !mChildFunctors.empty(); }
     82 
     83     /**
     84      * Returns true if this list directly contains a VectorDrawable drawing command.
     85      */
     86     bool hasVectorDrawables() const override { return !mVectorDrawables.empty(); }
     87 
     88     /**
     89      * Attempts to reset and reuse this DisplayList.
     90      *
     91      * @return true if the displayList will be reused and therefore should not be deleted
     92      */
     93     bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) override;
     94 
     95     /**
     96      * ONLY to be called by RenderNode::syncDisplayList so that we can notify any
     97      * contained VectorDrawables or GLFunctors to sync their state.
     98      *
     99      * NOTE: This function can be folded into RenderNode when we no longer need
    100      *       to subclass from DisplayList
    101      */
    102     void syncContents() override;
    103 
    104     /**
    105      * ONLY to be called by RenderNode::prepareTree in order to prepare this
    106      * list while the UI thread is blocked.  Here we can upload mutable bitmaps
    107      * and notify our parent if any of our content has been invalidated and in
    108      * need of a redraw.  If the renderNode has any children then they are also
    109      * call in order to prepare them.
    110      *
    111      * @return true if any content change requires the node to be invalidated
    112      *
    113      * NOTE: This function can be folded into RenderNode when we no longer need
    114      *       to subclass from DisplayList
    115      */
    116 
    117     bool prepareListAndChildren(
    118             TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
    119             std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) override;
    120 
    121     /**
    122      *  Calls the provided function once for each child of this DisplayList
    123      */
    124     void updateChildren(std::function<void(RenderNode*)> updateFn) override;
    125 
    126     /**
    127      *  Returns true if there is a child render node that is a projection receiver.
    128      */
    129     inline bool containsProjectionReceiver() const { return mProjectionReceiver; }
    130 
    131     void attachRecorder(SkLiteRecorder* recorder, const SkIRect& bounds) {
    132         recorder->reset(&mDisplayList, bounds);
    133     }
    134 
    135     void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }
    136 
    137     void output(std::ostream& output, uint32_t level) override;
    138 
    139     /**
    140      * We use std::deque here because (1) we need to iterate through these
    141      * elements and (2) mDisplayList holds pointers to the elements, so they
    142      * cannot relocate.
    143      */
    144     std::deque<RenderNodeDrawable> mChildNodes;
    145     std::deque<GLFunctorDrawable> mChildFunctors;
    146     std::vector<SkImage*> mMutableImages;
    147     std::vector<VectorDrawableRoot*> mVectorDrawables;
    148     std::vector<AnimatedImageDrawable*> mAnimatedImages;
    149     SkLiteDL mDisplayList;
    150 
    151     // mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection
    152     // receiver. It is set at record time and used at both prepare and draw tree traversals to
    153     // make sure backward projected nodes are found and drawn immediately after mProjectionReceiver.
    154     RenderNodeDrawable* mProjectionReceiver = nullptr;
    155 
    156     // mProjectedOutline is valid only when render node tree is traversed during the draw pass.
    157     // Render nodes that have a child receiver node, will store a pointer to their outline in
    158     // mProjectedOutline. Child receiver node will apply the clip before any backward projected
    159     // node is drawn.
    160     const Outline* mProjectedOutline = nullptr;
    161 
    162     // mProjectedReceiverParentMatrix is valid when render node tree is traversed during the draw
    163     // pass. Render nodes that have a child receiver node, will store their matrix in
    164     // mProjectedReceiverParentMatrix. Child receiver node will set the matrix and then clip with
    165     // the
    166     // outline of their parent.
    167     SkMatrix mProjectedReceiverParentMatrix;
    168 };
    169 
    170 };  // namespace skiapipeline
    171 };  // namespace uirenderer
    172 };  // namespace android
    173