Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2013 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 #ifndef ANDROID_HWUI_TESSELLATION_CACHE_H
     18 #define ANDROID_HWUI_TESSELLATION_CACHE_H
     19 
     20 #include <utils/LruCache.h>
     21 #include <utils/Mutex.h>
     22 #include <utils/Vector.h>
     23 
     24 #include "Debug.h"
     25 #include "utils/Macros.h"
     26 #include "utils/Pair.h"
     27 #include "VertexBuffer.h"
     28 
     29 class SkBitmap;
     30 class SkCanvas;
     31 class SkPaint;
     32 class SkPath;
     33 struct SkRect;
     34 
     35 namespace android {
     36 namespace uirenderer {
     37 
     38 class Caches;
     39 
     40 ///////////////////////////////////////////////////////////////////////////////
     41 // Classes
     42 ///////////////////////////////////////////////////////////////////////////////
     43 
     44 class TessellationCache {
     45 public:
     46     typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
     47 
     48     struct Description {
     49         DESCRIPTION_TYPE(Description);
     50         enum Type {
     51             kNone,
     52             kRoundRect,
     53         };
     54 
     55         Type type;
     56         float scaleX;
     57         float scaleY;
     58         bool aa;
     59         SkPaint::Cap cap;
     60         SkPaint::Style style;
     61         float strokeWidth;
     62         union Shape {
     63             struct RoundRect {
     64                 float width;
     65                 float height;
     66                 float rx;
     67                 float ry;
     68             } roundRect;
     69         } shape;
     70 
     71         Description();
     72         Description(Type type, const Matrix4& transform, const SkPaint& paint);
     73         hash_t hash() const;
     74         void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
     75     };
     76 
     77     struct ShadowDescription {
     78         DESCRIPTION_TYPE(ShadowDescription);
     79         const void* nodeKey;
     80         float matrixData[16];
     81 
     82         ShadowDescription();
     83         ShadowDescription(const void* nodeKey, const Matrix4* drawTransform);
     84         hash_t hash() const;
     85     };
     86 
     87     TessellationCache();
     88     ~TessellationCache();
     89 
     90     /**
     91      * Clears the cache. This causes all TessellationBuffers to be deleted.
     92      */
     93     void clear();
     94 
     95     /**
     96      * Sets the maximum size of the cache in bytes.
     97      */
     98     void setMaxSize(uint32_t maxSize);
     99     /**
    100      * Returns the maximum size of the cache in bytes.
    101      */
    102     uint32_t getMaxSize();
    103     /**
    104      * Returns the current size of the cache in bytes.
    105      */
    106     uint32_t getSize();
    107 
    108     /**
    109      * Trims the contents of the cache, removing items until it's under its
    110      * specified limit.
    111      *
    112      * Trimming is used for caches that support pre-caching from a worker
    113      * thread. During pre-caching the maximum limit of the cache can be
    114      * exceeded for the duration of the frame. It is therefore required to
    115      * trim the cache at the end of the frame to keep the total amount of
    116      * memory used under control.
    117      *
    118      * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
    119      */
    120     void trim();
    121 
    122     // TODO: precache/get for Oval, Lines, Points, etc.
    123 
    124     void precacheRoundRect(const Matrix4& transform, const SkPaint& paint,
    125             float width, float height, float rx, float ry) {
    126         getRoundRectBuffer(transform, paint, width, height, rx, ry);
    127     }
    128     const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint,
    129             float width, float height, float rx, float ry);
    130 
    131     void precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
    132             bool opaque, const SkPath* casterPerimeter,
    133             const Matrix4* transformXY, const Matrix4* transformZ,
    134             const Vector3& lightCenter, float lightRadius);
    135 
    136     void getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
    137             bool opaque, const SkPath* casterPerimeter,
    138             const Matrix4* transformXY, const Matrix4* transformZ,
    139             const Vector3& lightCenter, float lightRadius,
    140             vertexBuffer_pair_t& outBuffers);
    141 
    142 private:
    143     class Buffer;
    144     class TessellationTask;
    145     class TessellationProcessor;
    146 
    147     typedef VertexBuffer* (*Tessellator)(const Description&);
    148 
    149     Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint,
    150             float width, float height);
    151     Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint,
    152             float width, float height, float rx, float ry);
    153 
    154     Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);
    155 
    156     uint32_t mSize;
    157     uint32_t mMaxSize;
    158 
    159     bool mDebugEnabled;
    160 
    161     mutable Mutex mLock;
    162 
    163     ///////////////////////////////////////////////////////////////////////////////
    164     // General tessellation caching
    165     ///////////////////////////////////////////////////////////////////////////////
    166     sp<TaskProcessor<VertexBuffer*> > mProcessor;
    167     LruCache<Description, Buffer*> mCache;
    168     class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
    169         void operator()(Description& description, Buffer*& buffer);
    170     };
    171     BufferRemovedListener mBufferRemovedListener;
    172 
    173     ///////////////////////////////////////////////////////////////////////////////
    174     // Shadow tessellation caching
    175     ///////////////////////////////////////////////////////////////////////////////
    176     sp<TaskProcessor<vertexBuffer_pair_t*> > mShadowProcessor;
    177 
    178     // holds a pointer, and implicit strong ref to each shadow task of the frame
    179     LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*> mShadowCache;
    180     class BufferPairRemovedListener : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t*>*> {
    181         void operator()(ShadowDescription& description, Task<vertexBuffer_pair_t*>*& bufferPairTask) {
    182             bufferPairTask->decStrong(NULL);
    183         }
    184     };
    185     BufferPairRemovedListener mBufferPairRemovedListener;
    186 
    187 }; // class TessellationCache
    188 
    189 }; // namespace uirenderer
    190 }; // namespace android
    191 
    192 #endif // ANDROID_HWUI_PATH_CACHE_H
    193