| /* | 
 |  * Copyright (C) 2013 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. | 
 |  */ | 
 |  | 
 | #ifndef ANDROID_HWUI_TESSELLATION_CACHE_H | 
 | #define ANDROID_HWUI_TESSELLATION_CACHE_H | 
 |  | 
 | #include <utils/LruCache.h> | 
 | #include <utils/Mutex.h> | 
 | #include <utils/Vector.h> | 
 |  | 
 | #include "Debug.h" | 
 | #include "utils/Macros.h" | 
 | #include "utils/Pair.h" | 
 | #include "VertexBuffer.h" | 
 |  | 
 | class SkBitmap; | 
 | class SkCanvas; | 
 | class SkPaint; | 
 | class SkPath; | 
 | struct SkRect; | 
 |  | 
 | namespace android { | 
 | namespace uirenderer { | 
 |  | 
 | class Caches; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 | // Classes | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | class TessellationCache { | 
 | public: | 
 |     typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t; | 
 |  | 
 |     struct Description { | 
 |         DESCRIPTION_TYPE(Description); | 
 |         enum Type { | 
 |             kNone, | 
 |             kRoundRect, | 
 |         }; | 
 |  | 
 |         Type type; | 
 |         float scaleX; | 
 |         float scaleY; | 
 |         bool aa; | 
 |         SkPaint::Cap cap; | 
 |         SkPaint::Style style; | 
 |         float strokeWidth; | 
 |         union Shape { | 
 |             struct RoundRect { | 
 |                 float width; | 
 |                 float height; | 
 |                 float rx; | 
 |                 float ry; | 
 |             } roundRect; | 
 |         } shape; | 
 |  | 
 |         Description(); | 
 |         Description(Type type, const Matrix4& transform, const SkPaint& paint); | 
 |         hash_t hash() const; | 
 |         void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const; | 
 |     }; | 
 |  | 
 |     struct ShadowDescription { | 
 |         DESCRIPTION_TYPE(ShadowDescription); | 
 |         const void* nodeKey; | 
 |         float matrixData[16]; | 
 |  | 
 |         ShadowDescription(); | 
 |         ShadowDescription(const void* nodeKey, const Matrix4* drawTransform); | 
 |         hash_t hash() const; | 
 |     }; | 
 |  | 
 |     TessellationCache(); | 
 |     ~TessellationCache(); | 
 |  | 
 |     /** | 
 |      * Clears the cache. This causes all TessellationBuffers to be deleted. | 
 |      */ | 
 |     void clear(); | 
 |  | 
 |     /** | 
 |      * Sets the maximum size of the cache in bytes. | 
 |      */ | 
 |     void setMaxSize(uint32_t maxSize); | 
 |     /** | 
 |      * Returns the maximum size of the cache in bytes. | 
 |      */ | 
 |     uint32_t getMaxSize(); | 
 |     /** | 
 |      * Returns the current size of the cache in bytes. | 
 |      */ | 
 |     uint32_t getSize(); | 
 |  | 
 |     /** | 
 |      * Trims the contents of the cache, removing items until it's under its | 
 |      * specified limit. | 
 |      * | 
 |      * Trimming is used for caches that support pre-caching from a worker | 
 |      * thread. During pre-caching the maximum limit of the cache can be | 
 |      * exceeded for the duration of the frame. It is therefore required to | 
 |      * trim the cache at the end of the frame to keep the total amount of | 
 |      * memory used under control. | 
 |      * | 
 |      * Also removes transient Shadow VertexBuffers, which aren't cached between frames. | 
 |      */ | 
 |     void trim(); | 
 |  | 
 |     // TODO: precache/get for Oval, Lines, Points, etc. | 
 |  | 
 |     void precacheRoundRect(const Matrix4& transform, const SkPaint& paint, | 
 |             float width, float height, float rx, float ry) { | 
 |         getRoundRectBuffer(transform, paint, width, height, rx, ry); | 
 |     } | 
 |     const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint, | 
 |             float width, float height, float rx, float ry); | 
 |  | 
 |     void precacheShadows(const Matrix4* drawTransform, const Rect& localClip, | 
 |             bool opaque, const SkPath* casterPerimeter, | 
 |             const Matrix4* transformXY, const Matrix4* transformZ, | 
 |             const Vector3& lightCenter, float lightRadius); | 
 |  | 
 |     void getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip, | 
 |             bool opaque, const SkPath* casterPerimeter, | 
 |             const Matrix4* transformXY, const Matrix4* transformZ, | 
 |             const Vector3& lightCenter, float lightRadius, | 
 |             vertexBuffer_pair_t& outBuffers); | 
 |  | 
 | private: | 
 |     class Buffer; | 
 |     class TessellationTask; | 
 |     class TessellationProcessor; | 
 |  | 
 |     typedef VertexBuffer* (*Tessellator)(const Description&); | 
 |  | 
 |     Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint, | 
 |             float width, float height); | 
 |     Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint, | 
 |             float width, float height, float rx, float ry); | 
 |  | 
 |     Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator); | 
 |  | 
 |     uint32_t mSize; | 
 |     uint32_t mMaxSize; | 
 |  | 
 |     bool mDebugEnabled; | 
 |  | 
 |     mutable Mutex mLock; | 
 |  | 
 |     /////////////////////////////////////////////////////////////////////////////// | 
 |     // General tessellation caching | 
 |     /////////////////////////////////////////////////////////////////////////////// | 
 |     sp<TaskProcessor<VertexBuffer*> > mProcessor; | 
 |     LruCache<Description, Buffer*> mCache; | 
 |     class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> { | 
 |         void operator()(Description& description, Buffer*& buffer); | 
 |     }; | 
 |     BufferRemovedListener mBufferRemovedListener; | 
 |  | 
 |     /////////////////////////////////////////////////////////////////////////////// | 
 |     // Shadow tessellation caching | 
 |     /////////////////////////////////////////////////////////////////////////////// | 
 |     sp<TaskProcessor<vertexBuffer_pair_t*> > mShadowProcessor; | 
 |  | 
 |     // holds a pointer, and implicit strong ref to each shadow task of the frame | 
 |     LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*> mShadowCache; | 
 |     class BufferPairRemovedListener : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t*>*> { | 
 |         void operator()(ShadowDescription& description, Task<vertexBuffer_pair_t*>*& bufferPairTask) { | 
 |             bufferPairTask->decStrong(NULL); | 
 |         } | 
 |     }; | 
 |     BufferPairRemovedListener mBufferPairRemovedListener; | 
 |  | 
 | }; // class TessellationCache | 
 |  | 
 | }; // namespace uirenderer | 
 | }; // namespace android | 
 |  | 
 | #endif // ANDROID_HWUI_PATH_CACHE_H |