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 |