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 "GrLayerCache.h" | 8 #include "GrLayerCache.h" |
9 #include "GrLayerHoister.h" | 9 #include "GrLayerHoister.h" |
10 #include "GrRecordReplaceDraw.h" | 10 #include "GrRecordReplaceDraw.h" |
11 | 11 |
| 12 #include "SkBigPicture.h" |
12 #include "SkCanvas.h" | 13 #include "SkCanvas.h" |
13 #include "SkDeviceImageFilterProxy.h" | 14 #include "SkDeviceImageFilterProxy.h" |
14 #include "SkDeviceProperties.h" | 15 #include "SkDeviceProperties.h" |
15 #include "SkGpuDevice.h" | 16 #include "SkGpuDevice.h" |
16 #include "SkGrPixelRef.h" | 17 #include "SkGrPixelRef.h" |
17 #include "SkLayerInfo.h" | 18 #include "SkLayerInfo.h" |
18 #include "SkRecordDraw.h" | 19 #include "SkRecordDraw.h" |
19 #include "SkSurface.h" | 20 #include "SkSurface.h" |
20 #include "SkSurface_Gpu.h" | 21 #include "SkSurface_Gpu.h" |
21 | 22 |
22 // Create the layer information for the hoisted layer and secure the | 23 // Create the layer information for the hoisted layer and secure the |
23 // required texture/render target resources. | 24 // required texture/render target resources. |
24 static void prepare_for_hoisting(GrLayerCache* layerCache, | 25 static void prepare_for_hoisting(GrLayerCache* layerCache, |
25 const SkPicture* topLevelPicture, | 26 const SkPicture* topLevelPicture, |
26 const SkMatrix& initialMat, | 27 const SkMatrix& initialMat, |
27 const SkLayerInfo::BlockInfo& info, | 28 const SkLayerInfo::BlockInfo& info, |
28 const SkIRect& srcIR, | 29 const SkIRect& srcIR, |
29 const SkIRect& dstIR, | 30 const SkIRect& dstIR, |
30 SkTDArray<GrHoistedLayer>* needRendering, | 31 SkTDArray<GrHoistedLayer>* needRendering, |
31 SkTDArray<GrHoistedLayer>* recycled, | 32 SkTDArray<GrHoistedLayer>* recycled, |
32 bool attemptToAtlas, | 33 bool attemptToAtlas, |
33 int numSamples) { | 34 int numSamples) { |
34 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture; | 35 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 GrHoistedLayer* hl; | 68 GrHoistedLayer* hl; |
68 | 69 |
69 if (needsRendering) { | 70 if (needsRendering) { |
70 if (!attemptToAtlas) { | 71 if (!attemptToAtlas) { |
71 SkASSERT(!layer->isAtlased()); | 72 SkASSERT(!layer->isAtlased()); |
72 } | 73 } |
73 hl = needRendering->append(); | 74 hl = needRendering->append(); |
74 } else { | 75 } else { |
75 hl = recycled->append(); | 76 hl = recycled->append(); |
76 } | 77 } |
77 | 78 |
78 layerCache->addUse(layer); | 79 layerCache->addUse(layer); |
79 hl->fLayer = layer; | 80 hl->fLayer = layer; |
80 hl->fPicture = pict; | 81 hl->fPicture = pict; |
81 hl->fLocalMat = info.fLocalMat; | 82 hl->fLocalMat = info.fLocalMat; |
82 hl->fInitialMat = initialMat; | 83 hl->fInitialMat = initialMat; |
83 hl->fPreMat = initialMat; | 84 hl->fPreMat = initialMat; |
84 hl->fPreMat.preConcat(info.fPreMat); | 85 hl->fPreMat.preConcat(info.fPreMat); |
85 } | 86 } |
86 | 87 |
87 // Compute the source rect and return false if it is empty. | 88 // Compute the source rect and return false if it is empty. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 const SkRect& query, | 123 const SkRect& query, |
123 SkTDArray<GrHoistedLayer>* atlased, | 124 SkTDArray<GrHoistedLayer>* atlased, |
124 SkTDArray<GrHoistedLayer>* recycled, | 125 SkTDArray<GrHoistedLayer>* recycled, |
125 int numSamples) { | 126 int numSamples) { |
126 if (0 != numSamples) { | 127 if (0 != numSamples) { |
127 // MSAA layers are currently never atlased | 128 // MSAA layers are currently never atlased |
128 return; | 129 return; |
129 } | 130 } |
130 | 131 |
131 GrLayerCache* layerCache = context->getLayerCache(); | 132 GrLayerCache* layerCache = context->getLayerCache(); |
132 | |
133 layerCache->processDeletedPictures(); | 133 layerCache->processDeletedPictures(); |
134 | 134 |
135 SkPicture::AccelData::Key key = SkLayerInfo::ComputeKey(); | 135 const SkBigPicture::AccelData* topLevelData = NULL; |
136 | 136 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) { |
137 const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_get
AccelData(key); | 137 topLevelData = bp->accelData(); |
| 138 } |
138 if (!topLevelData) { | 139 if (!topLevelData) { |
139 return; | 140 return; |
140 } | 141 } |
141 | 142 |
142 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve
lData); | 143 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve
lData); |
143 if (0 == topLevelGPUData->numBlocks()) { | 144 if (0 == topLevelGPUData->numBlocks()) { |
144 return; | 145 return; |
145 } | 146 } |
146 | 147 |
147 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks()); | 148 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 const SkPicture* topLevelPicture, | 183 const SkPicture* topLevelPicture, |
183 const SkMatrix& initialMat, | 184 const SkMatrix& initialMat, |
184 const SkRect& query, | 185 const SkRect& query, |
185 SkTDArray<GrHoistedLayer>* needRendering, | 186 SkTDArray<GrHoistedLayer>* needRendering, |
186 SkTDArray<GrHoistedLayer>* recycled, | 187 SkTDArray<GrHoistedLayer>* recycled, |
187 int numSamples) { | 188 int numSamples) { |
188 GrLayerCache* layerCache = context->getLayerCache(); | 189 GrLayerCache* layerCache = context->getLayerCache(); |
189 | 190 |
190 layerCache->processDeletedPictures(); | 191 layerCache->processDeletedPictures(); |
191 | 192 |
192 SkPicture::AccelData::Key key = SkLayerInfo::ComputeKey(); | 193 const SkBigPicture::AccelData* topLevelData = NULL; |
193 | 194 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) { |
194 const SkPicture::AccelData* topLevelData = topLevelPicture->EXPERIMENTAL_get
AccelData(key); | 195 topLevelData = bp->accelData(); |
| 196 } |
195 if (!topLevelData) { | 197 if (!topLevelData) { |
196 return; | 198 return; |
197 } | 199 } |
198 | 200 |
199 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve
lData); | 201 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve
lData); |
200 if (0 == topLevelGPUData->numBlocks()) { | 202 if (0 == topLevelGPUData->numBlocks()) { |
201 return; | 203 return; |
202 } | 204 } |
203 | 205 |
204 // Find and prepare for hoisting all the layers that intersect the query rec
t | 206 // Find and prepare for hoisting all the layers that intersect the query rec
t |
(...skipping 27 matching lines...) Expand all Loading... |
232 if (atlased.count() > 0) { | 234 if (atlased.count() > 0) { |
233 // All the atlased layers are rendered into the same GrTexture | 235 // All the atlased layers are rendered into the same GrTexture |
234 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | 236 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
235 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 237 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
236 atlased[0].fLayer->texture()->asRenderTa
rget(), &props)); | 238 atlased[0].fLayer->texture()->asRenderTa
rget(), &props)); |
237 | 239 |
238 SkCanvas* atlasCanvas = surface->getCanvas(); | 240 SkCanvas* atlasCanvas = surface->getCanvas(); |
239 | 241 |
240 for (int i = 0; i < atlased.count(); ++i) { | 242 for (int i = 0; i < atlased.count(); ++i) { |
241 const GrCachedLayer* layer = atlased[i].fLayer; | 243 const GrCachedLayer* layer = atlased[i].fLayer; |
242 const SkPicture* pict = atlased[i].fPicture; | 244 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture(); |
| 245 if (!pict) { |
| 246 // TODO: can we assume / assert this? |
| 247 continue; |
| 248 } |
243 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->
srcIR().fTop); | 249 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->
srcIR().fTop); |
244 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();) | 250 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();) |
245 | 251 |
246 SkASSERT(!layerPaint || !layerPaint->getImageFilter()); | 252 SkASSERT(!layerPaint || !layerPaint->getImageFilter()); |
247 SkASSERT(!layer->filter()); | 253 SkASSERT(!layer->filter()); |
248 | 254 |
249 atlasCanvas->save(); | 255 atlasCanvas->save(); |
250 | 256 |
251 // Add a rect clip to make sure the rendering doesn't | 257 // Add a rect clip to make sure the rendering doesn't |
252 // extend beyond the boundaries of the atlased sub-rect | 258 // extend beyond the boundaries of the atlased sub-rect |
253 const SkRect bound = SkRect::Make(layer->rect()); | 259 const SkRect bound = SkRect::Make(layer->rect()); |
254 atlasCanvas->clipRect(bound); | 260 atlasCanvas->clipRect(bound); |
255 atlasCanvas->clear(0); | 261 atlasCanvas->clear(0); |
256 | 262 |
257 // '-offset' maps the layer's top/left to the origin. | 263 // '-offset' maps the layer's top/left to the origin. |
258 // Since this layer is atlased, the top/left corner needs | 264 // Since this layer is atlased, the top/left corner needs |
259 // to be offset to the correct location in the backing texture. | 265 // to be offset to the correct location in the backing texture. |
260 SkMatrix initialCTM; | 266 SkMatrix initialCTM; |
261 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-of
fset.fY)); | 267 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-of
fset.fY)); |
262 initialCTM.preTranslate(bound.fLeft, bound.fTop); | 268 initialCTM.preTranslate(bound.fLeft, bound.fTop); |
263 initialCTM.preConcat(atlased[i].fPreMat); | 269 initialCTM.preConcat(atlased[i].fPreMat); |
264 | 270 |
265 atlasCanvas->setMatrix(initialCTM); | 271 atlasCanvas->setMatrix(initialCTM); |
266 atlasCanvas->concat(atlased[i].fLocalMat); | 272 atlasCanvas->concat(atlased[i].fLocalMat); |
267 | 273 |
268 SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, | 274 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop()
, initialCTM); |
269 pict->drawablePicts(), pict->drawableCount(), | |
270 layer->start() + 1, layer->stop(), initialCTM); | |
271 | |
272 atlasCanvas->restore(); | 275 atlasCanvas->restore(); |
273 } | 276 } |
274 | 277 |
275 atlasCanvas->flush(); | 278 atlasCanvas->flush(); |
276 } | 279 } |
277 } | 280 } |
278 | 281 |
279 SkBitmap wrap_texture(GrTexture* texture) { | 282 SkBitmap wrap_texture(GrTexture* texture) { |
280 SkASSERT(texture); | 283 SkASSERT(texture); |
281 | 284 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 324 } |
322 | 325 |
323 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.hei
ght()); | 326 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.hei
ght()); |
324 layer->setTexture(filteredBitmap.getTexture(), newRect); | 327 layer->setTexture(filteredBitmap.getTexture(), newRect); |
325 layer->setOffset(offset); | 328 layer->setOffset(offset); |
326 } | 329 } |
327 | 330 |
328 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
er>& layers) { | 331 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
er>& layers) { |
329 for (int i = 0; i < layers.count(); ++i) { | 332 for (int i = 0; i < layers.count(); ++i) { |
330 GrCachedLayer* layer = layers[i].fLayer; | 333 GrCachedLayer* layer = layers[i].fLayer; |
331 const SkPicture* pict = layers[i].fPicture; | 334 const SkBigPicture* pict = layers[i].fPicture->asSkBigPicture(); |
| 335 if (!pict) { |
| 336 // TODO: can we assume / assert this? |
| 337 continue; |
| 338 } |
332 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcI
R().fTop); | 339 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcI
R().fTop); |
333 | 340 |
334 // Each non-atlased layer has its own GrTexture | 341 // Each non-atlased layer has its own GrTexture |
335 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | 342 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
336 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 343 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
337 layer->texture()->asRenderTarget(), &pro
ps)); | 344 layer->texture()->asRenderTarget(), &pro
ps)); |
338 | 345 |
339 SkCanvas* layerCanvas = surface->getCanvas(); | 346 SkCanvas* layerCanvas = surface->getCanvas(); |
340 | 347 |
341 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); | 348 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); |
342 | 349 |
343 // Add a rect clip to make sure the rendering doesn't | 350 // Add a rect clip to make sure the rendering doesn't |
344 // extend beyond the boundaries of the layer | 351 // extend beyond the boundaries of the layer |
345 const SkRect bound = SkRect::Make(layer->rect()); | 352 const SkRect bound = SkRect::Make(layer->rect()); |
346 layerCanvas->clipRect(bound); | 353 layerCanvas->clipRect(bound); |
347 layerCanvas->clear(SK_ColorTRANSPARENT); | 354 layerCanvas->clear(SK_ColorTRANSPARENT); |
348 | 355 |
349 SkMatrix initialCTM; | 356 SkMatrix initialCTM; |
350 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset
.fY)); | 357 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset
.fY)); |
351 initialCTM.preConcat(layers[i].fPreMat); | 358 initialCTM.preConcat(layers[i].fPreMat); |
352 | 359 |
353 layerCanvas->setMatrix(initialCTM); | 360 layerCanvas->setMatrix(initialCTM); |
354 layerCanvas->concat(layers[i].fLocalMat); | 361 layerCanvas->concat(layers[i].fLocalMat); |
355 | 362 |
356 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, | 363 pict->partialPlayback(layerCanvas, layer->start()+1, layer->stop(), init
ialCTM); |
357 pict->drawablePicts(), pict->drawableCount(), | |
358 layer->start()+1, layer->stop(), initialCTM); | |
359 | |
360 layerCanvas->flush(); | 364 layerCanvas->flush(); |
361 | 365 |
362 if (layer->filter()) { | 366 if (layer->filter()) { |
363 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get()); | 367 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get()); |
364 | 368 |
365 FilterLayer(context, gpuSurf->getDevice(), layers[i]); | 369 FilterLayer(context, gpuSurf->getDevice(), layers[i]); |
366 } | 370 } |
367 } | 371 } |
368 } | 372 } |
369 | 373 |
(...skipping 11 matching lines...) Expand all Loading... |
381 void GrLayerHoister::PurgeCache(GrContext* context) { | 385 void GrLayerHoister::PurgeCache(GrContext* context) { |
382 #if !GR_CACHE_HOISTED_LAYERS | 386 #if !GR_CACHE_HOISTED_LAYERS |
383 GrLayerCache* layerCache = context->getLayerCache(); | 387 GrLayerCache* layerCache = context->getLayerCache(); |
384 | 388 |
385 // This code completely clears out the atlas. It is required when | 389 // This code completely clears out the atlas. It is required when |
386 // caching is disabled so the atlas doesn't fill up and force more | 390 // caching is disabled so the atlas doesn't fill up and force more |
387 // free floating layers | 391 // free floating layers |
388 layerCache->purgeAll(); | 392 layerCache->purgeAll(); |
389 #endif | 393 #endif |
390 } | 394 } |
OLD | NEW |