OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrLayerCache_DEFINED | 8 #ifndef GrLayerCache_DEFINED |
9 #define GrLayerCache_DEFINED | 9 #define GrLayerCache_DEFINED |
10 | 10 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 | 90 |
91 // GrCachedLayer proper | 91 // GrCachedLayer proper |
92 GrCachedLayer(uint32_t pictureID, int start, int stop, | 92 GrCachedLayer(uint32_t pictureID, int start, int stop, |
93 const SkMatrix& ctm, const SkPaint* paint) | 93 const SkMatrix& ctm, const SkPaint* paint) |
94 : fKey(pictureID, start, ctm) | 94 : fKey(pictureID, start, ctm) |
95 , fStop(stop) | 95 , fStop(stop) |
96 , fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL) | 96 , fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL) |
97 , fTexture(NULL) | 97 , fTexture(NULL) |
98 , fRect(GrIRect16::MakeEmpty()) | 98 , fRect(GrIRect16::MakeEmpty()) |
99 , fPlot(NULL) | 99 , fPlot(NULL) |
| 100 , fUses(0) |
100 , fLocked(false) { | 101 , fLocked(false) { |
101 SkASSERT(SK_InvalidGenID != pictureID && start >= 0 && stop >= 0); | 102 SkASSERT(SK_InvalidGenID != pictureID && start >= 0 && stop >= 0); |
102 } | 103 } |
103 | 104 |
104 ~GrCachedLayer() { | 105 ~GrCachedLayer() { |
105 SkSafeUnref(fTexture); | 106 SkSafeUnref(fTexture); |
106 SkDELETE(fPaint); | 107 SkDELETE(fPaint); |
107 } | 108 } |
108 | 109 |
109 uint32_t pictureID() const { return fKey.pictureID(); } | 110 uint32_t pictureID() const { return fKey.pictureID(); } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 149 |
149 // For both atlased and non-atlased layers 'fRect' contains the bound of | 150 // For both atlased and non-atlased layers 'fRect' contains the bound of |
150 // the layer in whichever texture it resides. It is empty when 'fTexture' | 151 // the layer in whichever texture it resides. It is empty when 'fTexture' |
151 // is NULL. | 152 // is NULL. |
152 GrIRect16 fRect; | 153 GrIRect16 fRect; |
153 | 154 |
154 // For atlased layers, fPlot stores the atlas plot in which the layer rests. | 155 // For atlased layers, fPlot stores the atlas plot in which the layer rests. |
155 // It is always NULL for non-atlased layers. | 156 // It is always NULL for non-atlased layers. |
156 GrPlot* fPlot; | 157 GrPlot* fPlot; |
157 | 158 |
| 159 // The number of actively hoisted layers using this cached image (e.g., |
| 160 // extant GrHoistedLayers pointing at this object). This object will |
| 161 // be unlocked when the use count reaches 0. |
| 162 int fUses; |
| 163 |
158 // For non-atlased layers 'fLocked' should always match "fTexture". | 164 // For non-atlased layers 'fLocked' should always match "fTexture". |
159 // (i.e., if there is a texture it is locked). | 165 // (i.e., if there is a texture it is locked). |
160 // For atlased layers, 'fLocked' is true if the layer is in a plot and | 166 // For atlased layers, 'fLocked' is true if the layer is in a plot and |
161 // actively required for rendering. If the layer is in a plot but not | 167 // actively required for rendering. If the layer is in a plot but not |
162 // actively required for rendering, then 'fLocked' is false. If the | 168 // actively required for rendering, then 'fLocked' is false. If the |
163 // layer isn't in a plot then is can never be locked. | 169 // layer isn't in a plot then is can never be locked. |
164 bool fLocked; | 170 bool fLocked; |
| 171 |
| 172 void addUse() { ++fUses; } |
| 173 void removeUse() { SkASSERT(fUses > 0); --fUses; } |
| 174 int uses() const { return fUses; } |
| 175 |
| 176 friend class GrLayerCache; // for access to usage methods |
| 177 friend class TestingAccess; // for testing |
165 }; | 178 }; |
166 | 179 |
167 // The GrLayerCache caches pre-computed saveLayers for later rendering. | 180 // The GrLayerCache caches pre-computed saveLayers for later rendering. |
168 // Non-atlased layers are stored in their own GrTexture while the atlased | 181 // Non-atlased layers are stored in their own GrTexture while the atlased |
169 // layers share a single GrTexture. | 182 // layers share a single GrTexture. |
170 // Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888) | 183 // Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888) |
171 // and one GrPlot (for the entire atlas). As such, the GrLayerCache | 184 // and one GrPlot (for the entire atlas). As such, the GrLayerCache |
172 // roughly combines the functionality of the GrFontCache and GrTextStrike | 185 // roughly combines the functionality of the GrFontCache and GrTextStrike |
173 // classes. | 186 // classes. |
174 class GrLayerCache { | 187 class GrLayerCache { |
175 public: | 188 public: |
176 GrLayerCache(GrContext*); | 189 GrLayerCache(GrContext*); |
177 ~GrLayerCache(); | 190 ~GrLayerCache(); |
178 | 191 |
179 // As a cache, the GrLayerCache can be ordered to free up all its cached | 192 // As a cache, the GrLayerCache can be ordered to free up all its cached |
180 // elements by the GrContext | 193 // elements by the GrContext |
181 void freeAll(); | 194 void freeAll(); |
182 | 195 |
183 GrCachedLayer* findLayer(uint32_t pictureID, int start, const SkMatrix& ctm)
; | 196 GrCachedLayer* findLayer(uint32_t pictureID, int start, const SkMatrix& ctm)
; |
184 GrCachedLayer* findLayerOrCreate(uint32_t pictureID, | 197 GrCachedLayer* findLayerOrCreate(uint32_t pictureID, |
185 int start, int stop, | 198 int start, int stop, |
186 const SkMatrix& ctm, | 199 const SkMatrix& ctm, |
187 const SkPaint* paint); | 200 const SkPaint* paint); |
188 | 201 |
189 // Inform the cache that layer's cached image is now required. | 202 // Inform the cache that layer's cached image is now required. |
190 // Return true if the layer must be re-rendered. Return false if the | 203 // Return true if the layer must be re-rendered. Return false if the |
191 // layer was found in the cache and can be reused. | 204 // layer was found in the cache and can be reused. |
192 bool lock(GrCachedLayer* layer, const GrTextureDesc& desc, bool dontAtlas); | 205 bool lock(GrCachedLayer* layer, const GrTextureDesc& desc, bool dontAtlas); |
193 | 206 |
194 // Inform the cache that layer's cached image is not currently required | 207 // addUse is just here to keep the API symmetric |
195 void unlock(GrCachedLayer* layer); | 208 void addUse(GrCachedLayer* layer) { layer->addUse(); } |
| 209 void removeUse(GrCachedLayer* layer) { |
| 210 layer->removeUse(); |
| 211 if (layer->uses() == 0) { |
| 212 // If no one cares about the layer allow it to be recycled. |
| 213 this->unlock(layer); |
| 214 } |
| 215 } |
196 | 216 |
197 // Setup to be notified when 'picture' is deleted | 217 // Setup to be notified when 'picture' is deleted |
198 void trackPicture(const SkPicture* picture); | 218 void trackPicture(const SkPicture* picture); |
199 | 219 |
200 // Cleanup after any SkPicture deletions | 220 // Cleanup after any SkPicture deletions |
201 void processDeletedPictures(); | 221 void processDeletedPictures(); |
202 | 222 |
203 SkDEBUGCODE(void validate() const;) | 223 SkDEBUGCODE(void validate() const;) |
204 | 224 |
205 private: | 225 private: |
(...skipping 23 matching lines...) Expand all Loading... |
229 SkAutoTUnref<SkPicture::DeletionListener> fDeletionListener; | 249 SkAutoTUnref<SkPicture::DeletionListener> fDeletionListener; |
230 | 250 |
231 // This implements a plot-centric locking mechanism (since the atlas | 251 // This implements a plot-centric locking mechanism (since the atlas |
232 // backing texture is always locked). Each layer that is locked (i.e., | 252 // backing texture is always locked). Each layer that is locked (i.e., |
233 // needed for the current rendering) in a plot increments the plot lock | 253 // needed for the current rendering) in a plot increments the plot lock |
234 // count for that plot. Similarly, once a rendering is complete all the | 254 // count for that plot. Similarly, once a rendering is complete all the |
235 // layers used in it decrement the lock count for the used plots. | 255 // layers used in it decrement the lock count for the used plots. |
236 // Plots with a 0 lock count are open for recycling/purging. | 256 // Plots with a 0 lock count are open for recycling/purging. |
237 int fPlotLocks[kNumPlotsX * kNumPlotsY]; | 257 int fPlotLocks[kNumPlotsX * kNumPlotsY]; |
238 | 258 |
| 259 // Inform the cache that layer's cached image is not currently required |
| 260 void unlock(GrCachedLayer* layer); |
| 261 |
239 void initAtlas(); | 262 void initAtlas(); |
240 GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, | 263 GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, |
241 const SkMatrix& ctm, const SkPaint* paint); | 264 const SkMatrix& ctm, const SkPaint* paint); |
242 | 265 |
243 void purgeAll(); | 266 void purgeAll(); |
244 | 267 |
245 // Remove all the layers (and unlock any resources) associated with 'picture
ID' | 268 // Remove all the layers (and unlock any resources) associated with 'picture
ID' |
246 void purge(uint32_t pictureID); | 269 void purge(uint32_t pictureID); |
247 | 270 |
248 static bool PlausiblyAtlasable(int width, int height) { | 271 static bool PlausiblyAtlasable(int width, int height) { |
249 return width <= kPlotWidth && height <= kPlotHeight; | 272 return width <= kPlotWidth && height <= kPlotHeight; |
250 } | 273 } |
251 | 274 |
252 void purgePlot(GrPlot* plot); | 275 void purgePlot(GrPlot* plot); |
253 | 276 |
254 // Try to find a purgeable plot and clear it out. Return true if a plot | 277 // Try to find a purgeable plot and clear it out. Return true if a plot |
255 // was purged; false otherwise. | 278 // was purged; false otherwise. |
256 bool purgePlot(); | 279 bool purgePlot(); |
257 | 280 |
| 281 void incPlotLock(int plotIdx) { ++fPlotLocks[plotIdx]; } |
| 282 void decPlotLock(int plotIdx) { |
| 283 SkASSERT(fPlotLocks[plotIdx] > 0); |
| 284 --fPlotLocks[plotIdx]; |
| 285 } |
| 286 |
258 // for testing | 287 // for testing |
259 friend class TestingAccess; | 288 friend class TestingAccess; |
260 int numLayers() const { return fLayerHash.count(); } | 289 int numLayers() const { return fLayerHash.count(); } |
261 }; | 290 }; |
262 | 291 |
263 #endif | 292 #endif |
OLD | NEW |