| 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 |