• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #define LOG_TAG "OpenGLRenderer"
18 
19 #include <utils/threads.h>
20 
21 #include "PathCache.h"
22 #include "Properties.h"
23 
24 namespace android {
25 namespace uirenderer {
26 
27 // Defined in ShapeCache.h
28 
computePathBounds(const SkPath * path,const SkPaint * paint,float & left,float & top,float & offset,uint32_t & width,uint32_t & height)29 void computePathBounds(const SkPath* path, const SkPaint* paint,
30         float& left, float& top, float& offset, uint32_t& width, uint32_t& height) {
31     const SkRect& bounds = path->getBounds();
32     computeBounds(bounds, paint, left, top, offset, width, height);
33 }
34 
computeBounds(const SkRect & bounds,const SkPaint * paint,float & left,float & top,float & offset,uint32_t & width,uint32_t & height)35 void computeBounds(const SkRect& bounds, const SkPaint* paint,
36         float& left, float& top, float& offset, uint32_t& width, uint32_t& height) {
37     const float pathWidth = fmax(bounds.width(), 1.0f);
38     const float pathHeight = fmax(bounds.height(), 1.0f);
39 
40     left = bounds.fLeft;
41     top = bounds.fTop;
42 
43     offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f);
44 
45     width = uint32_t(pathWidth + offset * 2.0 + 0.5);
46     height = uint32_t(pathHeight + offset * 2.0 + 0.5);
47 }
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 // Path cache
51 ///////////////////////////////////////////////////////////////////////////////
52 
PathCache()53 PathCache::PathCache(): ShapeCache<PathCacheEntry>("path",
54         PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE) {
55 }
56 
remove(SkPath * path)57 void PathCache::remove(SkPath* path) {
58     // TODO: Linear search...
59     Vector<size_t> pathsToRemove;
60     for (size_t i = 0; i < mCache.size(); i++) {
61         if (mCache.getKeyAt(i).path == path) {
62             pathsToRemove.push(i);
63             removeTexture(mCache.getValueAt(i));
64         }
65     }
66 
67     mCache.setOnEntryRemovedListener(NULL);
68     for (size_t i = 0; i < pathsToRemove.size(); i++) {
69         // This will work because pathsToRemove is sorted
70         // and because the cache is a sorted keyed vector
71         mCache.removeAt(pathsToRemove.itemAt(i) - i);
72     }
73     mCache.setOnEntryRemovedListener(this);
74 }
75 
removeDeferred(SkPath * path)76 void PathCache::removeDeferred(SkPath* path) {
77     Mutex::Autolock _l(mLock);
78     mGarbage.push(path);
79 }
80 
clearGarbage()81 void PathCache::clearGarbage() {
82     Mutex::Autolock _l(mLock);
83     size_t count = mGarbage.size();
84     for (size_t i = 0; i < count; i++) {
85         remove(mGarbage.itemAt(i));
86     }
87     mGarbage.clear();
88 }
89 
get(SkPath * path,SkPaint * paint)90 PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
91     const SkPath* sourcePath = path->getSourcePath();
92     if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) {
93         path = const_cast<SkPath*>(sourcePath);
94     }
95 
96     PathCacheEntry entry(path, paint);
97     PathTexture* texture = mCache.get(entry);
98 
99     float left, top, offset;
100     uint32_t width, height;
101 
102     if (!texture) {
103         texture = addTexture(entry, path, paint);
104     } else if (path->getGenerationID() != texture->generation) {
105         mCache.remove(entry);
106         texture = addTexture(entry, path, paint);
107     }
108 
109     return texture;
110 }
111 
112 }; // namespace uirenderer
113 }; // namespace android
114