| 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 "SkCanvas.h" | 12 #include "SkCanvas.h" |
| 13 #include "SkGpuDevice.h" |
| 13 #include "SkGrPixelRef.h" | 14 #include "SkGrPixelRef.h" |
| 14 #include "SkLayerInfo.h" | 15 #include "SkLayerInfo.h" |
| 15 #include "SkRecordDraw.h" | 16 #include "SkRecordDraw.h" |
| 16 #include "SkSurface.h" | 17 #include "SkSurface.h" |
| 18 #include "SkSurface_Gpu.h" |
| 17 | 19 |
| 18 // Create the layer information for the hoisted layer and secure the | 20 // Create the layer information for the hoisted layer and secure the |
| 19 // required texture/render target resources. | 21 // required texture/render target resources. |
| 20 static void prepare_for_hoisting(GrLayerCache* layerCache, | 22 static void prepare_for_hoisting(GrLayerCache* layerCache, |
| 21 const SkPicture* topLevelPicture, | 23 const SkPicture* topLevelPicture, |
| 22 const SkMatrix& initialMat, | 24 const SkMatrix& initialMat, |
| 23 const SkLayerInfo::BlockInfo& info, | 25 const SkLayerInfo::BlockInfo& info, |
| 24 const SkIRect& layerRect, | 26 const SkIRect& layerRect, |
| 25 SkTDArray<GrHoistedLayer>* needRendering, | 27 SkTDArray<GrHoistedLayer>* needRendering, |
| 26 SkTDArray<GrHoistedLayer>* recycled, | 28 SkTDArray<GrHoistedLayer>* recycled, |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 195 |
| 194 SkCanvas* atlasCanvas = surface->getCanvas(); | 196 SkCanvas* atlasCanvas = surface->getCanvas(); |
| 195 | 197 |
| 196 for (int i = 0; i < atlased.count(); ++i) { | 198 for (int i = 0; i < atlased.count(); ++i) { |
| 197 const GrCachedLayer* layer = atlased[i].fLayer; | 199 const GrCachedLayer* layer = atlased[i].fLayer; |
| 198 const SkPicture* pict = atlased[i].fPicture; | 200 const SkPicture* pict = atlased[i].fPicture; |
| 199 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->
bound().fTop); | 201 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->
bound().fTop); |
| 200 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();) | 202 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();) |
| 201 | 203 |
| 202 SkASSERT(!layerPaint || !layerPaint->getImageFilter()); | 204 SkASSERT(!layerPaint || !layerPaint->getImageFilter()); |
| 205 SkASSERT(!layer->filter()); |
| 203 | 206 |
| 204 atlasCanvas->save(); | 207 atlasCanvas->save(); |
| 205 | 208 |
| 206 // Add a rect clip to make sure the rendering doesn't | 209 // Add a rect clip to make sure the rendering doesn't |
| 207 // extend beyond the boundaries of the atlased sub-rect | 210 // extend beyond the boundaries of the atlased sub-rect |
| 208 const SkRect bound = SkRect::Make(layer->rect()); | 211 const SkRect bound = SkRect::Make(layer->rect()); |
| 209 atlasCanvas->clipRect(bound); | 212 atlasCanvas->clipRect(bound); |
| 210 atlasCanvas->clear(0); | 213 atlasCanvas->clear(0); |
| 211 | 214 |
| 212 // '-offset' maps the layer's top/left to the origin. | 215 // '-offset' maps the layer's top/left to the origin. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 224 pict->drawablePicts(), pict->drawableCount(), | 227 pict->drawablePicts(), pict->drawableCount(), |
| 225 layer->start() + 1, layer->stop(), initialCTM); | 228 layer->start() + 1, layer->stop(), initialCTM); |
| 226 | 229 |
| 227 atlasCanvas->restore(); | 230 atlasCanvas->restore(); |
| 228 } | 231 } |
| 229 | 232 |
| 230 atlasCanvas->flush(); | 233 atlasCanvas->flush(); |
| 231 } | 234 } |
| 232 } | 235 } |
| 233 | 236 |
| 237 void GrLayerHoister::FilterLayer(GrContext* context, SkGpuDevice* device, GrCach
edLayer* layer) { |
| 238 SkASSERT(layer->filter()); |
| 239 |
| 240 static const int kDefaultCacheSize = 32 * 1024 * 1024; |
| 241 |
| 242 if (layer->filter()->canFilterImageGPU()) { |
| 243 SkBitmap filteredBitmap; |
| 244 SkIPoint offset = SkIPoint::Make(0, 0); |
| 245 |
| 246 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); |
| 247 SkIRect clipBounds = layer->rect(); |
| 248 |
| 249 // This cache is transient, and is freed (along with all its contained |
| 250 // textures) when it goes out of scope. |
| 251 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kD
efaultCacheSize)); |
| 252 SkImageFilter::Context filterContext(SkMatrix::I(), clipBounds, cache); |
| 253 |
| 254 if (!device->filterTexture(context, layer->texture(), layer->filter(), |
| 255 filterContext, &filteredBitmap, &offset)) { |
| 256 // Filtering failed. Press on with the unfiltered version |
| 257 return; |
| 258 } |
| 259 |
| 260 // TODO: need to fix up offset |
| 261 SkASSERT(0 == offset.fX && 0 == offset.fY); |
| 262 |
| 263 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap
.height()); |
| 264 layer->setTexture(filteredBitmap.getTexture(), newRect); |
| 265 } |
| 266 } |
| 267 |
| 234 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
er>& layers) { | 268 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
er>& layers) { |
| 235 for (int i = 0; i < layers.count(); ++i) { | 269 for (int i = 0; i < layers.count(); ++i) { |
| 236 GrCachedLayer* layer = layers[i].fLayer; | 270 GrCachedLayer* layer = layers[i].fLayer; |
| 237 const SkPicture* pict = layers[i].fPicture; | 271 const SkPicture* pict = layers[i].fPicture; |
| 238 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->boun
d().fTop); | 272 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->boun
d().fTop); |
| 239 | 273 |
| 240 // Each non-atlased layer has its own GrTexture | 274 // Each non-atlased layer has its own GrTexture |
| 241 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 275 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
| 242 layer->texture()->asRenderTarget(), NULL
)); | 276 layer->texture()->asRenderTarget(), NULL
)); |
| 243 | 277 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 256 initialCTM.preConcat(layers[i].fPreMat); | 290 initialCTM.preConcat(layers[i].fPreMat); |
| 257 | 291 |
| 258 layerCanvas->setMatrix(initialCTM); | 292 layerCanvas->setMatrix(initialCTM); |
| 259 layerCanvas->concat(layers[i].fLocalMat); | 293 layerCanvas->concat(layers[i].fLocalMat); |
| 260 | 294 |
| 261 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, | 295 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, |
| 262 pict->drawablePicts(), pict->drawableCount(), | 296 pict->drawablePicts(), pict->drawableCount(), |
| 263 layer->start()+1, layer->stop(), initialCTM); | 297 layer->start()+1, layer->stop(), initialCTM); |
| 264 | 298 |
| 265 layerCanvas->flush(); | 299 layerCanvas->flush(); |
| 300 |
| 301 if (layer->filter()) { |
| 302 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get()); |
| 303 |
| 304 FilterLayer(context, gpuSurf->getDevice(), layer); |
| 305 } |
| 266 } | 306 } |
| 267 } | 307 } |
| 268 | 308 |
| 269 void GrLayerHoister::UnlockLayers(GrContext* context, | 309 void GrLayerHoister::UnlockLayers(GrContext* context, |
| 270 const SkTDArray<GrHoistedLayer>& layers) { | 310 const SkTDArray<GrHoistedLayer>& layers) { |
| 271 GrLayerCache* layerCache = context->getLayerCache(); | 311 GrLayerCache* layerCache = context->getLayerCache(); |
| 272 | 312 |
| 273 for (int i = 0; i < layers.count(); ++i) { | 313 for (int i = 0; i < layers.count(); ++i) { |
| 274 layerCache->removeUse(layers[i].fLayer); | 314 layerCache->removeUse(layers[i].fLayer); |
| 275 } | 315 } |
| 276 | 316 |
| 277 SkDEBUGCODE(layerCache->validate();) | 317 SkDEBUGCODE(layerCache->validate();) |
| 278 } | 318 } |
| 279 | 319 |
| 280 void GrLayerHoister::PurgeCache(GrContext* context) { | 320 void GrLayerHoister::PurgeCache(GrContext* context) { |
| 281 #if !GR_CACHE_HOISTED_LAYERS | 321 #if !GR_CACHE_HOISTED_LAYERS |
| 282 GrLayerCache* layerCache = context->getLayerCache(); | 322 GrLayerCache* layerCache = context->getLayerCache(); |
| 283 | 323 |
| 284 // This code completely clears out the atlas. It is required when | 324 // This code completely clears out the atlas. It is required when |
| 285 // caching is disabled so the atlas doesn't fill up and force more | 325 // caching is disabled so the atlas doesn't fill up and force more |
| 286 // free floating layers | 326 // free floating layers |
| 287 layerCache->purgeAll(); | 327 layerCache->purgeAll(); |
| 288 #endif | 328 #endif |
| 289 } | 329 } |
| OLD | NEW |