blob: 67e3c19a2fc6425e49a60b9db3884d60d2df4c10 [file] [log] [blame]
robertphillips98d709b2014-09-02 10:20:50 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrLayerCache.h"
9#include "GrLayerHoister.h"
robertphillips1c4c5282014-09-18 12:03:15 -070010#include "GrRecordReplaceDraw.h"
robertphillips3aac6e02014-10-20 08:52:40 -070011
mtklein9db912c2015-05-19 11:11:26 -070012#include "SkBigPicture.h"
robertphillips3aac6e02014-10-20 08:52:40 -070013#include "SkCanvas.h"
robertphillips95145a92015-01-14 08:08:21 -080014#include "SkDeviceImageFilterProxy.h"
15#include "SkDeviceProperties.h"
robertphillips7b9e8a42014-12-11 08:20:31 -080016#include "SkGpuDevice.h"
robertphillips1c4c5282014-09-18 12:03:15 -070017#include "SkGrPixelRef.h"
robertphillips82365912014-11-12 09:32:34 -080018#include "SkLayerInfo.h"
robertphillips3aac6e02014-10-20 08:52:40 -070019#include "SkRecordDraw.h"
robertphillips98d709b2014-09-02 10:20:50 -070020#include "SkSurface.h"
robertphillips7b9e8a42014-12-11 08:20:31 -080021#include "SkSurface_Gpu.h"
robertphillips98d709b2014-09-02 10:20:50 -070022
robertphillipscbe80ca2014-10-09 15:36:06 -070023// Create the layer information for the hoisted layer and secure the
24// required texture/render target resources.
mtklein9db912c2015-05-19 11:11:26 -070025static void prepare_for_hoisting(GrLayerCache* layerCache,
robertphillips232f6b02014-10-09 16:43:42 -070026 const SkPicture* topLevelPicture,
robertphillips01d6e5f2014-12-01 09:09:27 -080027 const SkMatrix& initialMat,
robertphillips82365912014-11-12 09:32:34 -080028 const SkLayerInfo::BlockInfo& info,
robertphillips478dd722014-12-16 08:25:55 -080029 const SkIRect& srcIR,
30 const SkIRect& dstIR,
robertphillipsfd61ed02014-10-28 07:21:44 -070031 SkTDArray<GrHoistedLayer>* needRendering,
32 SkTDArray<GrHoistedLayer>* recycled,
robertphillipsa63f32e2014-11-10 08:10:42 -080033 bool attemptToAtlas,
34 int numSamples) {
robertphillipscbe80ca2014-10-09 15:36:06 -070035 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
36
robertphillips01d6e5f2014-12-01 09:09:27 -080037 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->uniqueID(),
bsalomonfbaace02014-12-12 16:41:46 -080038 SkToInt(info.fSaveLayerOpID),
39 SkToInt(info.fRestoreOpID),
robertphillips478dd722014-12-16 08:25:55 -080040 srcIR,
41 dstIR,
robertphillips01d6e5f2014-12-01 09:09:27 -080042 initialMat,
43 info.fKey,
44 info.fKeySize,
robertphillipscbe80ca2014-10-09 15:36:06 -070045 info.fPaint);
bsalomonf2703d82014-10-28 14:33:06 -070046 GrSurfaceDesc desc;
47 desc.fFlags = kRenderTarget_GrSurfaceFlag;
robertphillips478dd722014-12-16 08:25:55 -080048 desc.fWidth = srcIR.width();
49 desc.fHeight = srcIR.height();
robertphillipscbe80ca2014-10-09 15:36:06 -070050 desc.fConfig = kSkia8888_GrPixelConfig;
robertphillipsa63f32e2014-11-10 08:10:42 -080051 desc.fSampleCnt = numSamples;
robertphillipscbe80ca2014-10-09 15:36:06 -070052
robertphillipsfd61ed02014-10-28 07:21:44 -070053 bool locked, needsRendering;
54 if (attemptToAtlas) {
55 locked = layerCache->tryToAtlas(layer, desc, &needsRendering);
56 } else {
57 locked = layerCache->lock(layer, desc, &needsRendering);
58 }
59 if (!locked) {
robertphillipscbe80ca2014-10-09 15:36:06 -070060 // GPU resources could not be secured for the hoisting of this layer
61 return;
62 }
63
robertphillipsfd61ed02014-10-28 07:21:44 -070064 if (attemptToAtlas) {
65 SkASSERT(layer->isAtlased());
66 }
67
robertphillipscbe80ca2014-10-09 15:36:06 -070068 GrHoistedLayer* hl;
69
70 if (needsRendering) {
robertphillipsfd61ed02014-10-28 07:21:44 -070071 if (!attemptToAtlas) {
72 SkASSERT(!layer->isAtlased());
robertphillipscbe80ca2014-10-09 15:36:06 -070073 }
robertphillipsfd61ed02014-10-28 07:21:44 -070074 hl = needRendering->append();
robertphillipscbe80ca2014-10-09 15:36:06 -070075 } else {
76 hl = recycled->append();
77 }
mtklein9db912c2015-05-19 11:11:26 -070078
robertphillips7bb9ed72014-10-10 11:38:29 -070079 layerCache->addUse(layer);
robertphillipscbe80ca2014-10-09 15:36:06 -070080 hl->fLayer = layer;
81 hl->fPicture = pict;
robertphillips9e6835d2014-10-22 05:33:52 -070082 hl->fLocalMat = info.fLocalMat;
robertphillips01d6e5f2014-12-01 09:09:27 -080083 hl->fInitialMat = initialMat;
84 hl->fPreMat = initialMat;
robertphillips30d78412014-11-24 09:49:17 -080085 hl->fPreMat.preConcat(info.fPreMat);
robertphillipscbe80ca2014-10-09 15:36:06 -070086}
87
robertphillips57f192d2015-01-08 10:15:25 -080088// Compute the source rect and return false if it is empty.
robertphillips478dd722014-12-16 08:25:55 -080089static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatrix& initialMat,
90 const SkIRect& dstIR, SkIRect* srcIR) {
91 SkIRect clipBounds = dstIR;
92
93 SkMatrix totMat = initialMat;
94 totMat.preConcat(info.fPreMat);
95 totMat.preConcat(info.fLocalMat);
96
97 if (info.fPaint && info.fPaint->getImageFilter()) {
98 info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat, &clipBounds);
99 }
100
101 if (!info.fSrcBounds.isEmpty()) {
102 SkRect r;
103
104 totMat.mapRect(&r, info.fSrcBounds);
105 r.roundOut(srcIR);
106
107 if (!srcIR->intersect(clipBounds)) {
108 return false;
109 }
110 } else {
111 *srcIR = clipBounds;
112 }
113
robertphillips478dd722014-12-16 08:25:55 -0800114 return true;
115}
116
robertphillipsfd61ed02014-10-28 07:21:44 -0700117// Atlased layers must be small enough to fit in the atlas, not have a
118// paint with an image filter and be neither nested nor nesting.
119// TODO: allow leaf nested layers to appear in the atlas.
120void GrLayerHoister::FindLayersToAtlas(GrContext* context,
robertphillipsd61ef012014-10-08 05:17:02 -0700121 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800122 const SkMatrix& initialMat,
robertphillips98d709b2014-09-02 10:20:50 -0700123 const SkRect& query,
robertphillipsd61ef012014-10-08 05:17:02 -0700124 SkTDArray<GrHoistedLayer>* atlased,
robertphillipsa63f32e2014-11-10 08:10:42 -0800125 SkTDArray<GrHoistedLayer>* recycled,
126 int numSamples) {
127 if (0 != numSamples) {
128 // MSAA layers are currently never atlased
129 return;
130 }
131
robertphillipsd61ef012014-10-08 05:17:02 -0700132 GrLayerCache* layerCache = context->getLayerCache();
robertphillipsd61ef012014-10-08 05:17:02 -0700133 layerCache->processDeletedPictures();
134
mtklein9db912c2015-05-19 11:11:26 -0700135 const SkBigPicture::AccelData* topLevelData = NULL;
136 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
137 topLevelData = bp->accelData();
138 }
robertphillipscbe80ca2014-10-09 15:36:06 -0700139 if (!topLevelData) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700140 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700141 }
142
robertphillips82365912014-11-12 09:32:34 -0800143 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
144 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700145 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700146 }
147
robertphillips82365912014-11-12 09:32:34 -0800148 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
robertphillipscbe80ca2014-10-09 15:36:06 -0700149
robertphillips82365912014-11-12 09:32:34 -0800150 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
151 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillips98d709b2014-09-02 10:20:50 -0700152
robertphillipsfd61ed02014-10-28 07:21:44 -0700153 // TODO: ignore perspective projected layers here?
154 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
155 (info.fPaint && info.fPaint->getImageFilter());
156
157 if (disallowAtlasing) {
158 continue;
159 }
160
robertphillips30d78412014-11-24 09:49:17 -0800161 SkRect layerRect;
162 initialMat.mapRect(&layerRect, info.fBounds);
robertphillips3aac6e02014-10-20 08:52:40 -0700163 if (!layerRect.intersect(query)) {
robertphillips2ed8a752014-09-03 13:46:02 -0700164 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700165 }
robertphillips98d709b2014-09-02 10:20:50 -0700166
robertphillips478dd722014-12-16 08:25:55 -0800167 const SkIRect dstIR = layerRect.roundOut();
robertphillips3aac6e02014-10-20 08:52:40 -0700168
robertphillips478dd722014-12-16 08:25:55 -0800169 SkIRect srcIR;
170
robertphillips57f192d2015-01-08 10:15:25 -0800171 if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
172 !GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
robertphillips2ed8a752014-09-03 13:46:02 -0700173 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700174 }
robertphillips2ed8a752014-09-03 13:46:02 -0700175
robertphillips30d78412014-11-24 09:49:17 -0800176 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
robertphillips478dd722014-12-16 08:25:55 -0800177 info, srcIR, dstIR, atlased, recycled, true, 0);
robertphillips98d709b2014-09-02 10:20:50 -0700178 }
179
robertphillipsfd61ed02014-10-28 07:21:44 -0700180}
181
182void GrLayerHoister::FindLayersToHoist(GrContext* context,
183 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800184 const SkMatrix& initialMat,
robertphillipsfd61ed02014-10-28 07:21:44 -0700185 const SkRect& query,
186 SkTDArray<GrHoistedLayer>* needRendering,
robertphillipsa63f32e2014-11-10 08:10:42 -0800187 SkTDArray<GrHoistedLayer>* recycled,
188 int numSamples) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700189 GrLayerCache* layerCache = context->getLayerCache();
190
191 layerCache->processDeletedPictures();
192
mtklein9db912c2015-05-19 11:11:26 -0700193 const SkBigPicture::AccelData* topLevelData = NULL;
194 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
195 topLevelData = bp->accelData();
196 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700197 if (!topLevelData) {
198 return;
199 }
200
robertphillips82365912014-11-12 09:32:34 -0800201 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
202 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700203 return;
204 }
205
206 // Find and prepare for hoisting all the layers that intersect the query rect
robertphillips82365912014-11-12 09:32:34 -0800207 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
208 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillipsfd61ed02014-10-28 07:21:44 -0700209 if (info.fIsNested) {
210 // Parent layers are currently hoisted while nested layers are not.
211 continue;
212 }
213
robertphillips30d78412014-11-24 09:49:17 -0800214 SkRect layerRect;
215 initialMat.mapRect(&layerRect, info.fBounds);
robertphillipsfd61ed02014-10-28 07:21:44 -0700216 if (!layerRect.intersect(query)) {
217 continue;
218 }
219
robertphillips478dd722014-12-16 08:25:55 -0800220 const SkIRect dstIR = layerRect.roundOut();
robertphillipsfd61ed02014-10-28 07:21:44 -0700221
robertphillips478dd722014-12-16 08:25:55 -0800222 SkIRect srcIR;
223 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
224 continue;
225 }
226
227 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcIR, dstIR,
robertphillipsa63f32e2014-11-10 08:10:42 -0800228 needRendering, recycled, false, numSamples);
robertphillipsfd61ed02014-10-28 07:21:44 -0700229 }
robertphillips98d709b2014-09-02 10:20:50 -0700230}
231
robertphillipsfd61ed02014-10-28 07:21:44 -0700232void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
233 const SkTDArray<GrHoistedLayer>& atlased) {
robertphillips98d709b2014-09-02 10:20:50 -0700234 if (atlased.count() > 0) {
235 // All the atlased layers are rendered into the same GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800236 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700237 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800238 atlased[0].fLayer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700239
240 SkCanvas* atlasCanvas = surface->getCanvas();
241
robertphillips98d709b2014-09-02 10:20:50 -0700242 for (int i = 0; i < atlased.count(); ++i) {
robertphillips9e6835d2014-10-22 05:33:52 -0700243 const GrCachedLayer* layer = atlased[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700244 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
245 if (!pict) {
246 // TODO: can we assume / assert this?
247 continue;
248 }
robertphillips478dd722014-12-16 08:25:55 -0800249 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips9e6835d2014-10-22 05:33:52 -0700250 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
251
252 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
robertphillips7b9e8a42014-12-11 08:20:31 -0800253 SkASSERT(!layer->filter());
robertphillips98d709b2014-09-02 10:20:50 -0700254
255 atlasCanvas->save();
256
257 // Add a rect clip to make sure the rendering doesn't
258 // extend beyond the boundaries of the atlased sub-rect
robertphillipse99d4992014-12-03 07:33:57 -0800259 const SkRect bound = SkRect::Make(layer->rect());
robertphillips98d709b2014-09-02 10:20:50 -0700260 atlasCanvas->clipRect(bound);
reed8eddfb52014-12-04 07:50:14 -0800261 atlasCanvas->clear(0);
robertphillips98d709b2014-09-02 10:20:50 -0700262
robertphillipsfd61ed02014-10-28 07:21:44 -0700263 // '-offset' maps the layer's top/left to the origin.
robertphillips98d709b2014-09-02 10:20:50 -0700264 // Since this layer is atlased, the top/left corner needs
265 // to be offset to the correct location in the backing texture.
robertphillips4815fe52014-09-16 10:32:43 -0700266 SkMatrix initialCTM;
robertphillipsfd61ed02014-10-28 07:21:44 -0700267 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
268 initialCTM.preTranslate(bound.fLeft, bound.fTop);
269 initialCTM.preConcat(atlased[i].fPreMat);
robertphillips9e6835d2014-10-22 05:33:52 -0700270
robertphillipsfd61ed02014-10-28 07:21:44 -0700271 atlasCanvas->setMatrix(initialCTM);
robertphillips9e6835d2014-10-22 05:33:52 -0700272 atlasCanvas->concat(atlased[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700273
mtklein9db912c2015-05-19 11:11:26 -0700274 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700275 atlasCanvas->restore();
276 }
277
278 atlasCanvas->flush();
279 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700280}
robertphillips98d709b2014-09-02 10:20:50 -0700281
robertphillips95145a92015-01-14 08:08:21 -0800282SkBitmap wrap_texture(GrTexture* texture) {
283 SkASSERT(texture);
284
285 SkBitmap result;
286 result.setInfo(texture->surfacePriv().info());
287 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
288 return result;
289}
290
robertphillips478dd722014-12-16 08:25:55 -0800291void GrLayerHoister::FilterLayer(GrContext* context,
292 SkGpuDevice* device,
293 const GrHoistedLayer& info) {
294 GrCachedLayer* layer = info.fLayer;
295
robertphillips7b9e8a42014-12-11 08:20:31 -0800296 SkASSERT(layer->filter());
297
298 static const int kDefaultCacheSize = 32 * 1024 * 1024;
299
robertphillips478dd722014-12-16 08:25:55 -0800300 SkBitmap filteredBitmap;
301 SkIPoint offset = SkIPoint::Make(0, 0);
robertphillips7b9e8a42014-12-11 08:20:31 -0800302
robertphillips478dd722014-12-16 08:25:55 -0800303 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips7b9e8a42014-12-11 08:20:31 -0800304
robertphillips478dd722014-12-16 08:25:55 -0800305 SkMatrix totMat = SkMatrix::I();
306 totMat.preConcat(info.fPreMat);
307 totMat.preConcat(info.fLocalMat);
308 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
robertphillips7b9e8a42014-12-11 08:20:31 -0800309
robertphillips478dd722014-12-16 08:25:55 -0800310 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
311 SkIRect clipBounds = layer->rect();
robertphillips7b9e8a42014-12-11 08:20:31 -0800312
robertphillips478dd722014-12-16 08:25:55 -0800313 // This cache is transient, and is freed (along with all its contained
314 // textures) when it goes out of scope.
315 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefaultCacheSize));
316 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
317
robertphillips95145a92015-01-14 08:08:21 -0800318 SkDeviceImageFilterProxy proxy(device, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
319 const SkBitmap src = wrap_texture(layer->texture());
320
321 if (!layer->filter()->filterImage(&proxy, src, filterContext, &filteredBitmap, &offset)) {
322 // Filtering failed. Press on with the unfiltered version.
robertphillips478dd722014-12-16 08:25:55 -0800323 return;
robertphillips7b9e8a42014-12-11 08:20:31 -0800324 }
robertphillips478dd722014-12-16 08:25:55 -0800325
326 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
327 layer->setTexture(filteredBitmap.getTexture(), newRect);
328 layer->setOffset(offset);
robertphillips7b9e8a42014-12-11 08:20:31 -0800329}
330
robertphillipsfd61ed02014-10-28 07:21:44 -0700331void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers) {
332 for (int i = 0; i < layers.count(); ++i) {
333 GrCachedLayer* layer = layers[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700334 const SkBigPicture* pict = layers[i].fPicture->asSkBigPicture();
335 if (!pict) {
336 // TODO: can we assume / assert this?
337 continue;
338 }
robertphillips478dd722014-12-16 08:25:55 -0800339 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips98d709b2014-09-02 10:20:50 -0700340
341 // Each non-atlased layer has its own GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800342 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700343 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800344 layer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700345
346 SkCanvas* layerCanvas = surface->getCanvas();
347
robertphillips9e6835d2014-10-22 05:33:52 -0700348 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
349
robertphillips98d709b2014-09-02 10:20:50 -0700350 // Add a rect clip to make sure the rendering doesn't
robertphillipsfd61ed02014-10-28 07:21:44 -0700351 // extend beyond the boundaries of the layer
robertphillipse99d4992014-12-03 07:33:57 -0800352 const SkRect bound = SkRect::Make(layer->rect());
robertphillipsfd61ed02014-10-28 07:21:44 -0700353 layerCanvas->clipRect(bound);
robertphillips98d709b2014-09-02 10:20:50 -0700354 layerCanvas->clear(SK_ColorTRANSPARENT);
355
robertphillips4815fe52014-09-16 10:32:43 -0700356 SkMatrix initialCTM;
robertphillips9e6835d2014-10-22 05:33:52 -0700357 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
robertphillipsfd61ed02014-10-28 07:21:44 -0700358 initialCTM.preConcat(layers[i].fPreMat);
robertphillips4815fe52014-09-16 10:32:43 -0700359
robertphillipsfd61ed02014-10-28 07:21:44 -0700360 layerCanvas->setMatrix(initialCTM);
361 layerCanvas->concat(layers[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700362
mtklein9db912c2015-05-19 11:11:26 -0700363 pict->partialPlayback(layerCanvas, layer->start()+1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700364 layerCanvas->flush();
robertphillips7b9e8a42014-12-11 08:20:31 -0800365
366 if (layer->filter()) {
367 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get());
368
robertphillips478dd722014-12-16 08:25:55 -0800369 FilterLayer(context, gpuSurf->getDevice(), layers[i]);
robertphillips7b9e8a42014-12-11 08:20:31 -0800370 }
robertphillips98d709b2014-09-02 10:20:50 -0700371 }
372}
373
robertphillipsd61ef012014-10-08 05:17:02 -0700374void GrLayerHoister::UnlockLayers(GrContext* context,
robertphillipsfd61ed02014-10-28 07:21:44 -0700375 const SkTDArray<GrHoistedLayer>& layers) {
robertphillipsd61ef012014-10-08 05:17:02 -0700376 GrLayerCache* layerCache = context->getLayerCache();
robertphillips30d2cc62014-09-24 08:52:18 -0700377
robertphillipsfd61ed02014-10-28 07:21:44 -0700378 for (int i = 0; i < layers.count(); ++i) {
379 layerCache->removeUse(layers[i].fLayer);
robertphillipsb5a97152014-09-30 11:33:02 -0700380 }
381
robertphillips4ab5a902014-10-29 13:56:02 -0700382 SkDEBUGCODE(layerCache->validate();)
383}
384
385void GrLayerHoister::PurgeCache(GrContext* context) {
386#if !GR_CACHE_HOISTED_LAYERS
387 GrLayerCache* layerCache = context->getLayerCache();
388
robertphillips30d2cc62014-09-24 08:52:18 -0700389 // This code completely clears out the atlas. It is required when
390 // caching is disabled so the atlas doesn't fill up and force more
391 // free floating layers
robertphillips98d709b2014-09-02 10:20:50 -0700392 layerCache->purgeAll();
393#endif
robertphillips98d709b2014-09-02 10:20:50 -0700394}