Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: src/gpu/GrLayerCache.h

Issue 640323002: Fix bug in GrCachedLayer reuse (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Improve comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/gpu/GrLayerCache.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/gpu/GrLayerCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698