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 28 class SkBitmap; 29 class SkCanvas; 30 class SkPaint; 31 class SkPath; 32 struct SkRect; 33 34 namespace android { 35 namespace uirenderer { 36 37 class Caches; 38 class VertexBuffer; 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) override; 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) override { 182 bufferPairTask->decStrong(nullptr); 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