Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2014 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 #ifndef RENDERNODE_H
     17 #define RENDERNODE_H
     18 
     19 #ifndef LOG_TAG
     20     #define LOG_TAG "OpenGLRenderer"
     21 #endif
     22 
     23 #include <SkCamera.h>
     24 #include <SkMatrix.h>
     25 
     26 #include <utils/LinearAllocator.h>
     27 #include <utils/RefBase.h>
     28 #include <utils/String8.h>
     29 #include <utils/Vector.h>
     30 
     31 #include <cutils/compiler.h>
     32 
     33 #include <androidfw/ResourceTypes.h>
     34 
     35 #include "AnimatorManager.h"
     36 #include "Debug.h"
     37 #include "Matrix.h"
     38 #include "DisplayList.h"
     39 #include "RenderProperties.h"
     40 
     41 class SkBitmap;
     42 class SkPaint;
     43 class SkPath;
     44 class SkRegion;
     45 
     46 namespace android {
     47 namespace uirenderer {
     48 
     49 class DisplayListOp;
     50 class DisplayListCanvas;
     51 class OpenGLRenderer;
     52 class Rect;
     53 class Layer;
     54 class SkiaShader;
     55 
     56 class ClipRectOp;
     57 class SaveLayerOp;
     58 class SaveOp;
     59 class RestoreToCountOp;
     60 class DrawRenderNodeOp;
     61 class TreeInfo;
     62 
     63 /**
     64  * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
     65  *
     66  * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording
     67  * functionality is split between DisplayListCanvas (which manages the recording), DisplayListData
     68  * (which holds the actual data), and DisplayList (which holds properties and performs playback onto
     69  * a renderer).
     70  *
     71  * Note that DisplayListData is swapped out from beneath an individual DisplayList when a view's
     72  * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
     73  * attached.
     74  */
     75 class RenderNode : public VirtualLightRefBase {
     76 public:
     77     enum DirtyPropertyMask {
     78         GENERIC         = 1 << 1,
     79         TRANSLATION_X   = 1 << 2,
     80         TRANSLATION_Y   = 1 << 3,
     81         TRANSLATION_Z   = 1 << 4,
     82         SCALE_X         = 1 << 5,
     83         SCALE_Y         = 1 << 6,
     84         ROTATION        = 1 << 7,
     85         ROTATION_X      = 1 << 8,
     86         ROTATION_Y      = 1 << 9,
     87         X               = 1 << 10,
     88         Y               = 1 << 11,
     89         Z               = 1 << 12,
     90         ALPHA           = 1 << 13,
     91         DISPLAY_LIST    = 1 << 14,
     92     };
     93 
     94     ANDROID_API RenderNode();
     95     ANDROID_API virtual ~RenderNode();
     96 
     97     // See flags defined in DisplayList.java
     98     enum ReplayFlag {
     99         kReplayFlag_ClipChildren = 0x1
    100     };
    101 
    102     static void outputLogBuffer(int fd);
    103     void debugDumpLayers(const char* prefix);
    104 
    105     ANDROID_API void setStagingDisplayList(DisplayListData* newData);
    106 
    107     void computeOrdering();
    108 
    109     void defer(DeferStateStruct& deferStruct, const int level);
    110     void replay(ReplayStateStruct& replayStruct, const int level);
    111 
    112     ANDROID_API void output(uint32_t level = 1);
    113     ANDROID_API int getDebugSize();
    114 
    115     bool isRenderable() const {
    116         return mDisplayListData && !mDisplayListData->isEmpty();
    117     }
    118 
    119     bool hasProjectionReceiver() const {
    120         return mDisplayListData && mDisplayListData->projectionReceiveIndex >= 0;
    121     }
    122 
    123     const char* getName() const {
    124         return mName.string();
    125     }
    126 
    127     void setName(const char* name) {
    128         if (name) {
    129             char* lastPeriod = strrchr(name, '.');
    130             if (lastPeriod) {
    131                 mName.setTo(lastPeriod + 1);
    132             } else {
    133                 mName.setTo(name);
    134             }
    135         }
    136     }
    137 
    138     bool isPropertyFieldDirty(DirtyPropertyMask field) const {
    139         return mDirtyPropertyFields & field;
    140     }
    141 
    142     void setPropertyFieldsDirty(uint32_t fields) {
    143         mDirtyPropertyFields |= fields;
    144     }
    145 
    146     const RenderProperties& properties() const {
    147         return mProperties;
    148     }
    149 
    150     RenderProperties& animatorProperties() {
    151         return mProperties;
    152     }
    153 
    154     const RenderProperties& stagingProperties() {
    155         return mStagingProperties;
    156     }
    157 
    158     RenderProperties& mutateStagingProperties() {
    159         return mStagingProperties;
    160     }
    161 
    162     int getWidth() {
    163         return properties().getWidth();
    164     }
    165 
    166     int getHeight() {
    167         return properties().getHeight();
    168     }
    169 
    170     ANDROID_API virtual void prepareTree(TreeInfo& info);
    171     void destroyHardwareResources();
    172 
    173     // UI thread only!
    174     ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
    175 
    176     AnimatorManager& animators() { return mAnimatorManager; }
    177 
    178     void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const;
    179 
    180 private:
    181     typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair;
    182 
    183     static size_t findNonNegativeIndex(const Vector<ZDrawRenderNodeOpPair>& nodes) {
    184         for (size_t i = 0; i < nodes.size(); i++) {
    185             if (nodes[i].key >= 0.0f) return i;
    186         }
    187         return nodes.size();
    188     }
    189 
    190     enum ChildrenSelectMode {
    191         kNegativeZChildren,
    192         kPositiveZChildren
    193     };
    194 
    195     void computeOrderingImpl(DrawRenderNodeOp* opState,
    196             const SkPath* outlineOfProjectionSurface,
    197             Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface,
    198             const mat4* transformFromProjectionSurface);
    199 
    200     template <class T>
    201     inline void setViewProperties(OpenGLRenderer& renderer, T& handler);
    202 
    203     void buildZSortedChildList(const DisplayListData::Chunk& chunk,
    204             Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes);
    205 
    206     template<class T>
    207     inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler);
    208 
    209     template <class T>
    210     inline void issueOperationsOf3dChildren(ChildrenSelectMode mode,
    211             const Matrix4& initialTransform, const Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
    212             OpenGLRenderer& renderer, T& handler);
    213 
    214     template <class T>
    215     inline void issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler);
    216 
    217     /**
    218      * Issue the RenderNode's operations into a handler, recursing for subtrees through
    219      * DrawRenderNodeOp's defer() or replay() methods
    220      */
    221     template <class T>
    222     inline void issueOperations(OpenGLRenderer& renderer, T& handler);
    223 
    224     class TextContainer {
    225     public:
    226         size_t length() const {
    227             return mByteLength;
    228         }
    229 
    230         const char* text() const {
    231             return (const char*) mText;
    232         }
    233 
    234         size_t mByteLength;
    235         const char* mText;
    236     };
    237 
    238     void prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer);
    239     void pushStagingPropertiesChanges(TreeInfo& info);
    240     void pushStagingDisplayListChanges(TreeInfo& info);
    241     void prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayListData* subtree);
    242     void applyLayerPropertiesToLayer(TreeInfo& info);
    243     void prepareLayer(TreeInfo& info, uint32_t dirtyMask);
    244     void pushLayerUpdate(TreeInfo& info);
    245     void deleteDisplayListData();
    246     void damageSelf(TreeInfo& info);
    247 
    248     void incParentRefCount() { mParentCount++; }
    249     void decParentRefCount();
    250 
    251     String8 mName;
    252 
    253     uint32_t mDirtyPropertyFields;
    254     RenderProperties mProperties;
    255     RenderProperties mStagingProperties;
    256 
    257     bool mNeedsDisplayListDataSync;
    258     // WARNING: Do not delete this directly, you must go through deleteDisplayListData()!
    259     DisplayListData* mDisplayListData;
    260     DisplayListData* mStagingDisplayListData;
    261 
    262     friend class AnimatorManager;
    263     AnimatorManager mAnimatorManager;
    264 
    265     // Owned by RT. Lifecycle is managed by prepareTree(), with the exception
    266     // being in ~RenderNode() which may happen on any thread.
    267     Layer* mLayer;
    268 
    269     /**
    270      * Draw time state - these properties are only set and used during rendering
    271      */
    272 
    273     // for projection surfaces, contains a list of all children items
    274     Vector<DrawRenderNodeOp*> mProjectedNodes;
    275 
    276     // How many references our parent(s) have to us. Typically this should alternate
    277     // between 2 and 1 (when a staging push happens we inc first then dec)
    278     // When this hits 0 we are no longer in the tree, so any hardware resources
    279     // (specifically Layers) should be released.
    280     // This is *NOT* thread-safe, and should therefore only be tracking
    281     // mDisplayListData, not mStagingDisplayListData.
    282     uint32_t mParentCount;
    283 }; // class RenderNode
    284 
    285 } /* namespace uirenderer */
    286 } /* namespace android */
    287 
    288 #endif /* RENDERNODE_H */
    289