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 #include "GrAtlas.h" | 8 #include "GrAtlas.h" |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
11 #include "GrGpu.h" | 11 #include "GrGpu.h" |
12 #include "GrLayerCache.h" | 12 #include "GrLayerCache.h" |
13 #include "GrSurfacePriv.h" | 13 #include "GrSurfacePriv.h" |
14 | 14 |
15 #ifdef SK_DEBUG | 15 #ifdef SK_DEBUG |
16 void GrCachedLayer::validate(const GrTexture* backingTexture) const { | 16 void GrCachedLayer::validate(const GrTexture* backingTexture) const { |
17 SkASSERT(SK_InvalidGenID != fKey.pictureID()); | 17 SkASSERT(SK_InvalidGenID != fKey.pictureID()); |
18 | 18 |
19 if (fTexture) { | 19 if (fTexture) { |
20 // If the layer is in some texture then it must occupy some rectangle | 20 // If the layer is in some texture then it must occupy some rectangle |
21 SkASSERT(!fRect.isEmpty()); | 21 SkASSERT(!fRect.isEmpty()); |
22 if (!this->isAtlased()) { | 22 if (!this->isAtlased()) { |
23 // If it isn't atlased then the rectangle should start at the origin | 23 // If it isn't atlased then the rectangle should start at the origin |
24 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop); | 24 SkASSERT(0.0f == fRect.fLeft && 0.0f == fRect.fTop); |
25 } | 25 } |
26 } else { | 26 } else { |
27 SkASSERT(fRect.isEmpty()); | 27 SkASSERT(fRect.isEmpty()); |
28 SkASSERT(NULL == fPlot); | 28 SkASSERT(nullptr == fPlot); |
29 SkASSERT(!fLocked); // layers without a texture cannot be locked | 29 SkASSERT(!fLocked); // layers without a texture cannot be locked |
30 } | 30 } |
31 | 31 |
32 if (fPlot) { | 32 if (fPlot) { |
33 // If a layer has a plot (i.e., is atlased) then it must point to | 33 // If a layer has a plot (i.e., is atlased) then it must point to |
34 // the backing texture. Additionally, its rect should be non-empty. | 34 // the backing texture. Additionally, its rect should be non-empty. |
35 SkASSERT(fTexture && backingTexture == fTexture); | 35 SkASSERT(fTexture && backingTexture == fTexture); |
36 SkASSERT(!fRect.isEmpty()); | 36 SkASSERT(!fRect.isEmpty()); |
37 } | 37 } |
38 | 38 |
(...skipping 22 matching lines...) Expand all Loading... |
61 if (fLayer) { | 61 if (fLayer) { |
62 fLayer->validate(backingTexture); | 62 fLayer->validate(backingTexture); |
63 } | 63 } |
64 } | 64 } |
65 ~GrAutoValidateLayer() { | 65 ~GrAutoValidateLayer() { |
66 if (fLayer) { | 66 if (fLayer) { |
67 fLayer->validate(fBackingTexture); | 67 fLayer->validate(fBackingTexture); |
68 } | 68 } |
69 } | 69 } |
70 void setBackingTexture(GrTexture* backingTexture) { | 70 void setBackingTexture(GrTexture* backingTexture) { |
71 SkASSERT(NULL == fBackingTexture || fBackingTexture == backingTexture); | 71 SkASSERT(nullptr == fBackingTexture || fBackingTexture == backingTexture
); |
72 fBackingTexture = backingTexture; | 72 fBackingTexture = backingTexture; |
73 } | 73 } |
74 | 74 |
75 private: | 75 private: |
76 const GrTexture* fBackingTexture; | 76 const GrTexture* fBackingTexture; |
77 const GrCachedLayer* fLayer; | 77 const GrCachedLayer* fLayer; |
78 }; | 78 }; |
79 #endif | 79 #endif |
80 | 80 |
81 GrLayerCache::GrLayerCache(GrContext* context) | 81 GrLayerCache::GrLayerCache(GrContext* context) |
(...skipping 11 matching lines...) Expand all Loading... |
93 delete layer; | 93 delete layer; |
94 } | 94 } |
95 | 95 |
96 SkASSERT(0 == fPictureHash.count()); | 96 SkASSERT(0 == fPictureHash.count()); |
97 | 97 |
98 // The atlas only lets go of its texture when the atlas is deleted. | 98 // The atlas only lets go of its texture when the atlas is deleted. |
99 fAtlas.free(); | 99 fAtlas.free(); |
100 } | 100 } |
101 | 101 |
102 void GrLayerCache::initAtlas() { | 102 void GrLayerCache::initAtlas() { |
103 SkASSERT(NULL == fAtlas.get()); | 103 SkASSERT(nullptr == fAtlas.get()); |
104 GR_STATIC_ASSERT(kNumPlotsX*kNumPlotsX == GrPictureInfo::kNumPlots); | 104 GR_STATIC_ASSERT(kNumPlotsX*kNumPlotsX == GrPictureInfo::kNumPlots); |
105 | 105 |
106 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight)
; | 106 SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight)
; |
107 fAtlas.reset(new GrAtlas(fContext->getGpu(), kSkia8888_GrPixelConfig, | 107 fAtlas.reset(new GrAtlas(fContext->getGpu(), kSkia8888_GrPixelConfig, |
108 kRenderTarget_GrSurfaceFlag, textureSize, kNumPlots
X, kNumPlotsY, | 108 kRenderTarget_GrSurfaceFlag, textureSize, kNumPlots
X, kNumPlotsY, |
109 false)); | 109 false)); |
110 } | 110 } |
111 | 111 |
112 void GrLayerCache::freeAll() { | 112 void GrLayerCache::freeAll() { |
113 | 113 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID, | 148 GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID, |
149 int start, int stop, | 149 int start, int stop, |
150 const SkIRect& srcIR, | 150 const SkIRect& srcIR, |
151 const SkIRect& dstIR, | 151 const SkIRect& dstIR, |
152 const SkMatrix& initialMat, | 152 const SkMatrix& initialMat, |
153 const int* key, | 153 const int* key, |
154 int keySize, | 154 int keySize, |
155 const SkPaint* paint) { | 155 const SkPaint* paint) { |
156 SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0); | 156 SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0); |
157 GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, initial
Mat, key, keySize)); | 157 GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, initial
Mat, key, keySize)); |
158 if (NULL == layer) { | 158 if (nullptr == layer) { |
159 layer = this->createLayer(pictureID, start, stop, | 159 layer = this->createLayer(pictureID, start, stop, |
160 srcIR, dstIR, initialMat, | 160 srcIR, dstIR, initialMat, |
161 key, keySize, paint); | 161 key, keySize, paint); |
162 } | 162 } |
163 | 163 |
164 return layer; | 164 return layer; |
165 } | 165 } |
166 | 166 |
167 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, | 167 bool GrLayerCache::tryToAtlas(GrCachedLayer* layer, |
168 const GrSurfaceDesc& desc, | 168 const GrSurfaceDesc& desc, |
169 bool* needsRendering) { | 169 bool* needsRendering) { |
170 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : NULL, la
yer);) | 170 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr,
layer);) |
171 | 171 |
172 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight)); | 172 SkASSERT(PlausiblyAtlasable(desc.fWidth, desc.fHeight)); |
173 SkASSERT(0 == desc.fSampleCnt); | 173 SkASSERT(0 == desc.fSampleCnt); |
174 | 174 |
175 if (layer->locked()) { | 175 if (layer->locked()) { |
176 // This layer is already locked | 176 // This layer is already locked |
177 SkASSERT(fAtlas); | 177 SkASSERT(fAtlas); |
178 SkASSERT(layer->isAtlased()); | 178 SkASSERT(layer->isAtlased()); |
179 SkASSERT(layer->rect().width() == desc.fWidth); | 179 SkASSERT(layer->rect().width() == desc.fWidth); |
180 SkASSERT(layer->rect().height() == desc.fHeight); | 180 SkASSERT(layer->rect().height() == desc.fHeight); |
(...skipping 10 matching lines...) Expand all Loading... |
191 return true; | 191 return true; |
192 } else { | 192 } else { |
193 if (!fAtlas) { | 193 if (!fAtlas) { |
194 this->initAtlas(); | 194 this->initAtlas(); |
195 if (!fAtlas) { | 195 if (!fAtlas) { |
196 return false; | 196 return false; |
197 } | 197 } |
198 } | 198 } |
199 // Not in the atlas - will it fit? | 199 // Not in the atlas - will it fit? |
200 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); | 200 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); |
201 if (NULL == pictInfo) { | 201 if (nullptr == pictInfo) { |
202 pictInfo = new GrPictureInfo(layer->pictureID()); | 202 pictInfo = new GrPictureInfo(layer->pictureID()); |
203 fPictureHash.add(pictInfo); | 203 fPictureHash.add(pictInfo); |
204 } | 204 } |
205 | 205 |
206 SkIPoint16 loc; | 206 SkIPoint16 loc; |
207 for (int i = 0; i < 2; ++i) { // extra pass in case we fail to add but a
re able to purge | 207 for (int i = 0; i < 2; ++i) { // extra pass in case we fail to add but a
re able to purge |
208 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage, | 208 GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage, |
209 desc.fWidth, desc.fHeight, | 209 desc.fWidth, desc.fHeight, |
210 NULL, &loc); | 210 nullptr, &loc); |
211 // addToAtlas can allocate the backing texture | 211 // addToAtlas can allocate the backing texture |
212 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture())); | 212 SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture())); |
213 if (plot) { | 213 if (plot) { |
214 #if !GR_CACHE_HOISTED_LAYERS | 214 #if !GR_CACHE_HOISTED_LAYERS |
215 pictInfo->incPlotUsage(plot->id()); | 215 pictInfo->incPlotUsage(plot->id()); |
216 #endif | 216 #endif |
217 // The layer was successfully added to the atlas | 217 // The layer was successfully added to the atlas |
218 const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY, | 218 const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY, |
219 desc.fWidth, desc.fHeig
ht); | 219 desc.fWidth, desc.fHeig
ht); |
220 layer->setTexture(fAtlas->getTexture(), bounds); | 220 layer->setTexture(fAtlas->getTexture(), bounds); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 return false; | 260 return false; |
261 } | 261 } |
262 | 262 |
263 layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight)); | 263 layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight)); |
264 layer->setLocked(true); | 264 layer->setLocked(true); |
265 *needsRendering = true; | 265 *needsRendering = true; |
266 return true; | 266 return true; |
267 } | 267 } |
268 | 268 |
269 void GrLayerCache::unlock(GrCachedLayer* layer) { | 269 void GrLayerCache::unlock(GrCachedLayer* layer) { |
270 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : NULL, la
yer);) | 270 SkDEBUGCODE(GrAutoValidateLayer avl(fAtlas ? fAtlas->getTexture() : nullptr,
layer);) |
271 | 271 |
272 if (NULL == layer || !layer->locked()) { | 272 if (nullptr == layer || !layer->locked()) { |
273 // invalid or not locked | 273 // invalid or not locked |
274 return; | 274 return; |
275 } | 275 } |
276 | 276 |
277 if (layer->isAtlased()) { | 277 if (layer->isAtlased()) { |
278 const int plotID = layer->plot()->id(); | 278 const int plotID = layer->plot()->id(); |
279 | 279 |
280 this->decPlotLock(plotID); | 280 this->decPlotLock(plotID); |
281 // At this point we could aggressively clear out un-locked plots but | 281 // At this point we could aggressively clear out un-locked plots but |
282 // by delaying we may be able to reuse some of the atlased layers later. | 282 // by delaying we may be able to reuse some of the atlased layers later. |
283 #if !GR_CACHE_HOISTED_LAYERS | 283 #if !GR_CACHE_HOISTED_LAYERS |
284 // This testing code aggressively removes the atlased layers. This | 284 // This testing code aggressively removes the atlased layers. This |
285 // can be used to separate the performance contribution of less | 285 // can be used to separate the performance contribution of less |
286 // render target pingponging from that due to the re-use of cached layer
s | 286 // render target pingponging from that due to the re-use of cached layer
s |
287 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); | 287 GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); |
288 SkASSERT(pictInfo); | 288 SkASSERT(pictInfo); |
289 | 289 |
290 pictInfo->decPlotUsage(plotID); | 290 pictInfo->decPlotUsage(plotID); |
291 | 291 |
292 if (0 == pictInfo->plotUsage(plotID)) { | 292 if (0 == pictInfo->plotUsage(plotID)) { |
293 GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot()); | 293 GrAtlas::RemovePlot(&pictInfo->fPlotUsage, layer->plot()); |
294 | 294 |
295 if (pictInfo->fPlotUsage.isEmpty()) { | 295 if (pictInfo->fPlotUsage.isEmpty()) { |
296 fPictureHash.remove(pictInfo->fPictureID); | 296 fPictureHash.remove(pictInfo->fPictureID); |
297 delete pictInfo; | 297 delete pictInfo; |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 layer->setPlot(NULL); | 301 layer->setPlot(nullptr); |
302 layer->setTexture(NULL, SkIRect::MakeEmpty()); | 302 layer->setTexture(nullptr, SkIRect::MakeEmpty()); |
303 #endif | 303 #endif |
304 | 304 |
305 } else { | 305 } else { |
306 layer->setTexture(NULL, SkIRect::MakeEmpty()); | 306 layer->setTexture(nullptr, SkIRect::MakeEmpty()); |
307 } | 307 } |
308 | 308 |
309 layer->setLocked(false); | 309 layer->setLocked(false); |
310 } | 310 } |
311 | 311 |
312 #ifdef SK_DEBUG | 312 #ifdef SK_DEBUG |
313 void GrLayerCache::validate() const { | 313 void GrLayerCache::validate() const { |
314 int plotLocks[kNumPlotsX * kNumPlotsY]; | 314 int plotLocks[kNumPlotsX * kNumPlotsY]; |
315 memset(plotLocks, 0, sizeof(plotLocks)); | 315 memset(plotLocks, 0, sizeof(plotLocks)); |
316 | 316 |
317 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas
h); | 317 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::ConstIter iter(&fLayerHas
h); |
318 for (; !iter.done(); ++iter) { | 318 for (; !iter.done(); ++iter) { |
319 const GrCachedLayer* layer = &(*iter); | 319 const GrCachedLayer* layer = &(*iter); |
320 | 320 |
321 layer->validate(fAtlas.get() ? fAtlas->getTexture() : NULL); | 321 layer->validate(fAtlas.get() ? fAtlas->getTexture() : nullptr); |
322 | 322 |
323 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); | 323 const GrPictureInfo* pictInfo = fPictureHash.find(layer->pictureID()); |
324 if (!pictInfo) { | 324 if (!pictInfo) { |
325 // If there is no picture info for this picture then all of its | 325 // If there is no picture info for this picture then all of its |
326 // layers should be non-atlased. | 326 // layers should be non-atlased. |
327 SkASSERT(!layer->isAtlased()); | 327 SkASSERT(!layer->isAtlased()); |
328 } | 328 } |
329 | 329 |
330 if (layer->plot()) { | 330 if (layer->plot()) { |
331 SkASSERT(pictInfo); | 331 SkASSERT(pictInfo); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 for (int i = 0; i < deletedPictures.count(); i++) { | 482 for (int i = 0; i < deletedPictures.count(); i++) { |
483 this->purge(deletedPictures[i].fUniqueID); | 483 this->purge(deletedPictures[i].fUniqueID); |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 #ifdef SK_DEVELOPER | 487 #ifdef SK_DEVELOPER |
488 void GrLayerCache::writeLayersToDisk(const SkString& dirName) { | 488 void GrLayerCache::writeLayersToDisk(const SkString& dirName) { |
489 | 489 |
490 if (fAtlas) { | 490 if (fAtlas) { |
491 GrTexture* atlasTexture = fAtlas->getTexture(); | 491 GrTexture* atlasTexture = fAtlas->getTexture(); |
492 if (NULL != atlasTexture) { | 492 if (nullptr != atlasTexture) { |
493 SkString fileName(dirName); | 493 SkString fileName(dirName); |
494 fileName.append("\\atlas.png"); | 494 fileName.append("\\atlas.png"); |
495 | 495 |
496 atlasTexture->surfacePriv().savePixels(fileName.c_str()); | 496 atlasTexture->surfacePriv().savePixels(fileName.c_str()); |
497 } | 497 } |
498 } | 498 } |
499 | 499 |
500 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); | 500 SkTDynamicHash<GrCachedLayer, GrCachedLayer::Key>::Iter iter(&fLayerHash); |
501 for (; !iter.done(); ++iter) { | 501 for (; !iter.done(); ++iter) { |
502 GrCachedLayer* layer = &(*iter); | 502 GrCachedLayer* layer = &(*iter); |
503 | 503 |
504 if (layer->isAtlased() || !layer->texture()) { | 504 if (layer->isAtlased() || !layer->texture()) { |
505 continue; | 505 continue; |
506 } | 506 } |
507 | 507 |
508 SkString fileName(dirName); | 508 SkString fileName(dirName); |
509 fileName.appendf("\\%d", layer->fKey.pictureID()); | 509 fileName.appendf("\\%d", layer->fKey.pictureID()); |
510 for (int i = 0; i < layer->fKey.keySize(); ++i) { | 510 for (int i = 0; i < layer->fKey.keySize(); ++i) { |
511 fileName.appendf("-%d", layer->fKey.key()[i]); | 511 fileName.appendf("-%d", layer->fKey.key()[i]); |
512 } | 512 } |
513 fileName.appendf(".png"); | 513 fileName.appendf(".png"); |
514 | 514 |
515 layer->texture()->surfacePriv().savePixels(fileName.c_str()); | 515 layer->texture()->surfacePriv().savePixels(fileName.c_str()); |
516 } | 516 } |
517 } | 517 } |
518 #endif | 518 #endif |
OLD | NEW |