blob: 59a4da1b231a5351371bac7a781c145744c3c67e [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"
robertphillips7b9e8a42014-12-11 08:20:31 -080014#include "SkGpuDevice.h"
robertphillips1c4c5282014-09-18 12:03:15 -070015#include "SkGrPixelRef.h"
robertphillips82365912014-11-12 09:32:34 -080016#include "SkLayerInfo.h"
robertphillips3aac6e02014-10-20 08:52:40 -070017#include "SkRecordDraw.h"
robertphillips98d709b2014-09-02 10:20:50 -070018#include "SkSurface.h"
robertphillips7b9e8a42014-12-11 08:20:31 -080019#include "SkSurface_Gpu.h"
robertphillips98d709b2014-09-02 10:20:50 -070020
robertphillipscbe80ca2014-10-09 15:36:06 -070021// Create the layer information for the hoisted layer and secure the
22// required texture/render target resources.
mtklein9db912c2015-05-19 11:11:26 -070023static void prepare_for_hoisting(GrLayerCache* layerCache,
robertphillips232f6b02014-10-09 16:43:42 -070024 const SkPicture* topLevelPicture,
robertphillips01d6e5f2014-12-01 09:09:27 -080025 const SkMatrix& initialMat,
robertphillips82365912014-11-12 09:32:34 -080026 const SkLayerInfo::BlockInfo& info,
robertphillips478dd722014-12-16 08:25:55 -080027 const SkIRect& srcIR,
28 const SkIRect& dstIR,
robertphillipsfd61ed02014-10-28 07:21:44 -070029 SkTDArray<GrHoistedLayer>* needRendering,
30 SkTDArray<GrHoistedLayer>* recycled,
robertphillipsa63f32e2014-11-10 08:10:42 -080031 bool attemptToAtlas,
32 int numSamples) {
robertphillipscbe80ca2014-10-09 15:36:06 -070033 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
34
robertphillips01d6e5f2014-12-01 09:09:27 -080035 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->uniqueID(),
bsalomonfbaace02014-12-12 16:41:46 -080036 SkToInt(info.fSaveLayerOpID),
37 SkToInt(info.fRestoreOpID),
robertphillips478dd722014-12-16 08:25:55 -080038 srcIR,
39 dstIR,
robertphillips01d6e5f2014-12-01 09:09:27 -080040 initialMat,
41 info.fKey,
42 info.fKeySize,
robertphillipscbe80ca2014-10-09 15:36:06 -070043 info.fPaint);
bsalomonf2703d82014-10-28 14:33:06 -070044 GrSurfaceDesc desc;
45 desc.fFlags = kRenderTarget_GrSurfaceFlag;
robertphillips478dd722014-12-16 08:25:55 -080046 desc.fWidth = srcIR.width();
47 desc.fHeight = srcIR.height();
robertphillipscbe80ca2014-10-09 15:36:06 -070048 desc.fConfig = kSkia8888_GrPixelConfig;
robertphillipsa63f32e2014-11-10 08:10:42 -080049 desc.fSampleCnt = numSamples;
robertphillipscbe80ca2014-10-09 15:36:06 -070050
robertphillipsfd61ed02014-10-28 07:21:44 -070051 bool locked, needsRendering;
52 if (attemptToAtlas) {
53 locked = layerCache->tryToAtlas(layer, desc, &needsRendering);
54 } else {
55 locked = layerCache->lock(layer, desc, &needsRendering);
56 }
57 if (!locked) {
robertphillipscbe80ca2014-10-09 15:36:06 -070058 // GPU resources could not be secured for the hoisting of this layer
59 return;
60 }
61
robertphillipsfd61ed02014-10-28 07:21:44 -070062 if (attemptToAtlas) {
63 SkASSERT(layer->isAtlased());
64 }
65
robertphillipscbe80ca2014-10-09 15:36:06 -070066 GrHoistedLayer* hl;
67
68 if (needsRendering) {
robertphillipsfd61ed02014-10-28 07:21:44 -070069 if (!attemptToAtlas) {
70 SkASSERT(!layer->isAtlased());
robertphillipscbe80ca2014-10-09 15:36:06 -070071 }
robertphillipsfd61ed02014-10-28 07:21:44 -070072 hl = needRendering->append();
robertphillipscbe80ca2014-10-09 15:36:06 -070073 } else {
74 hl = recycled->append();
75 }
mtklein9db912c2015-05-19 11:11:26 -070076
robertphillips7bb9ed72014-10-10 11:38:29 -070077 layerCache->addUse(layer);
robertphillipscbe80ca2014-10-09 15:36:06 -070078 hl->fLayer = layer;
79 hl->fPicture = pict;
robertphillips9e6835d2014-10-22 05:33:52 -070080 hl->fLocalMat = info.fLocalMat;
robertphillips01d6e5f2014-12-01 09:09:27 -080081 hl->fInitialMat = initialMat;
82 hl->fPreMat = initialMat;
robertphillips30d78412014-11-24 09:49:17 -080083 hl->fPreMat.preConcat(info.fPreMat);
robertphillipscbe80ca2014-10-09 15:36:06 -070084}
85
robertphillips57f192d2015-01-08 10:15:25 -080086// Compute the source rect and return false if it is empty.
robertphillips478dd722014-12-16 08:25:55 -080087static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatrix& initialMat,
88 const SkIRect& dstIR, SkIRect* srcIR) {
89 SkIRect clipBounds = dstIR;
90
91 SkMatrix totMat = initialMat;
92 totMat.preConcat(info.fPreMat);
93 totMat.preConcat(info.fLocalMat);
94
95 if (info.fPaint && info.fPaint->getImageFilter()) {
96 info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat, &clipBounds);
97 }
98
99 if (!info.fSrcBounds.isEmpty()) {
100 SkRect r;
101
102 totMat.mapRect(&r, info.fSrcBounds);
103 r.roundOut(srcIR);
104
105 if (!srcIR->intersect(clipBounds)) {
106 return false;
107 }
108 } else {
109 *srcIR = clipBounds;
110 }
111
robertphillips478dd722014-12-16 08:25:55 -0800112 return true;
113}
114
robertphillipsfd61ed02014-10-28 07:21:44 -0700115// Atlased layers must be small enough to fit in the atlas, not have a
116// paint with an image filter and be neither nested nor nesting.
117// TODO: allow leaf nested layers to appear in the atlas.
118void GrLayerHoister::FindLayersToAtlas(GrContext* context,
robertphillipsd61ef012014-10-08 05:17:02 -0700119 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800120 const SkMatrix& initialMat,
robertphillips98d709b2014-09-02 10:20:50 -0700121 const SkRect& query,
robertphillipsd61ef012014-10-08 05:17:02 -0700122 SkTDArray<GrHoistedLayer>* atlased,
robertphillipsa63f32e2014-11-10 08:10:42 -0800123 SkTDArray<GrHoistedLayer>* recycled,
124 int numSamples) {
125 if (0 != numSamples) {
126 // MSAA layers are currently never atlased
127 return;
128 }
129
robertphillipsd61ef012014-10-08 05:17:02 -0700130 GrLayerCache* layerCache = context->getLayerCache();
robertphillipsd61ef012014-10-08 05:17:02 -0700131 layerCache->processDeletedPictures();
132
mtklein9db912c2015-05-19 11:11:26 -0700133 const SkBigPicture::AccelData* topLevelData = NULL;
134 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
135 topLevelData = bp->accelData();
136 }
robertphillipscbe80ca2014-10-09 15:36:06 -0700137 if (!topLevelData) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700138 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700139 }
140
robertphillips82365912014-11-12 09:32:34 -0800141 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
142 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700143 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700144 }
145
robertphillips82365912014-11-12 09:32:34 -0800146 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
robertphillipscbe80ca2014-10-09 15:36:06 -0700147
robertphillips82365912014-11-12 09:32:34 -0800148 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
149 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillips98d709b2014-09-02 10:20:50 -0700150
robertphillipsfd61ed02014-10-28 07:21:44 -0700151 // TODO: ignore perspective projected layers here?
152 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
153 (info.fPaint && info.fPaint->getImageFilter());
154
155 if (disallowAtlasing) {
156 continue;
157 }
158
robertphillips30d78412014-11-24 09:49:17 -0800159 SkRect layerRect;
160 initialMat.mapRect(&layerRect, info.fBounds);
robertphillips3aac6e02014-10-20 08:52:40 -0700161 if (!layerRect.intersect(query)) {
robertphillips2ed8a752014-09-03 13:46:02 -0700162 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700163 }
robertphillips98d709b2014-09-02 10:20:50 -0700164
robertphillips478dd722014-12-16 08:25:55 -0800165 const SkIRect dstIR = layerRect.roundOut();
robertphillips3aac6e02014-10-20 08:52:40 -0700166
robertphillips478dd722014-12-16 08:25:55 -0800167 SkIRect srcIR;
168
robertphillips57f192d2015-01-08 10:15:25 -0800169 if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
170 !GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
robertphillips2ed8a752014-09-03 13:46:02 -0700171 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700172 }
robertphillips2ed8a752014-09-03 13:46:02 -0700173
robertphillips30d78412014-11-24 09:49:17 -0800174 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
robertphillips478dd722014-12-16 08:25:55 -0800175 info, srcIR, dstIR, atlased, recycled, true, 0);
robertphillips98d709b2014-09-02 10:20:50 -0700176 }
177
robertphillipsfd61ed02014-10-28 07:21:44 -0700178}
179
180void GrLayerHoister::FindLayersToHoist(GrContext* context,
181 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800182 const SkMatrix& initialMat,
robertphillipsfd61ed02014-10-28 07:21:44 -0700183 const SkRect& query,
184 SkTDArray<GrHoistedLayer>* needRendering,
robertphillipsa63f32e2014-11-10 08:10:42 -0800185 SkTDArray<GrHoistedLayer>* recycled,
186 int numSamples) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700187 GrLayerCache* layerCache = context->getLayerCache();
188
189 layerCache->processDeletedPictures();
190
mtklein9db912c2015-05-19 11:11:26 -0700191 const SkBigPicture::AccelData* topLevelData = NULL;
192 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
193 topLevelData = bp->accelData();
194 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700195 if (!topLevelData) {
196 return;
197 }
198
robertphillips82365912014-11-12 09:32:34 -0800199 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
200 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700201 return;
202 }
203
204 // Find and prepare for hoisting all the layers that intersect the query rect
robertphillips82365912014-11-12 09:32:34 -0800205 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
206 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillipsfd61ed02014-10-28 07:21:44 -0700207 if (info.fIsNested) {
208 // Parent layers are currently hoisted while nested layers are not.
209 continue;
210 }
211
robertphillips30d78412014-11-24 09:49:17 -0800212 SkRect layerRect;
213 initialMat.mapRect(&layerRect, info.fBounds);
robertphillipsfd61ed02014-10-28 07:21:44 -0700214 if (!layerRect.intersect(query)) {
215 continue;
216 }
217
robertphillips478dd722014-12-16 08:25:55 -0800218 const SkIRect dstIR = layerRect.roundOut();
robertphillipsfd61ed02014-10-28 07:21:44 -0700219
robertphillips478dd722014-12-16 08:25:55 -0800220 SkIRect srcIR;
221 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
222 continue;
223 }
224
225 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcIR, dstIR,
robertphillipsa63f32e2014-11-10 08:10:42 -0800226 needRendering, recycled, false, numSamples);
robertphillipsfd61ed02014-10-28 07:21:44 -0700227 }
robertphillips98d709b2014-09-02 10:20:50 -0700228}
229
robertphillipsfd61ed02014-10-28 07:21:44 -0700230void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
231 const SkTDArray<GrHoistedLayer>& atlased) {
robertphillips98d709b2014-09-02 10:20:50 -0700232 if (atlased.count() > 0) {
233 // All the atlased layers are rendered into the same GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800234 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700235 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800236 atlased[0].fLayer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700237
238 SkCanvas* atlasCanvas = surface->getCanvas();
239
robertphillips98d709b2014-09-02 10:20:50 -0700240 for (int i = 0; i < atlased.count(); ++i) {
robertphillips9e6835d2014-10-22 05:33:52 -0700241 const GrCachedLayer* layer = atlased[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700242 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
243 if (!pict) {
244 // TODO: can we assume / assert this?
245 continue;
246 }
robertphillips478dd722014-12-16 08:25:55 -0800247 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips9e6835d2014-10-22 05:33:52 -0700248 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
249
250 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
robertphillips7b9e8a42014-12-11 08:20:31 -0800251 SkASSERT(!layer->filter());
robertphillips98d709b2014-09-02 10:20:50 -0700252
253 atlasCanvas->save();
254
255 // Add a rect clip to make sure the rendering doesn't
256 // extend beyond the boundaries of the atlased sub-rect
robertphillipse99d4992014-12-03 07:33:57 -0800257 const SkRect bound = SkRect::Make(layer->rect());
robertphillips98d709b2014-09-02 10:20:50 -0700258 atlasCanvas->clipRect(bound);
reed8eddfb52014-12-04 07:50:14 -0800259 atlasCanvas->clear(0);
robertphillips98d709b2014-09-02 10:20:50 -0700260
robertphillipsfd61ed02014-10-28 07:21:44 -0700261 // '-offset' maps the layer's top/left to the origin.
robertphillips98d709b2014-09-02 10:20:50 -0700262 // Since this layer is atlased, the top/left corner needs
263 // to be offset to the correct location in the backing texture.
robertphillips4815fe52014-09-16 10:32:43 -0700264 SkMatrix initialCTM;
robertphillipsfd61ed02014-10-28 07:21:44 -0700265 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
266 initialCTM.preTranslate(bound.fLeft, bound.fTop);
267 initialCTM.preConcat(atlased[i].fPreMat);
robertphillips9e6835d2014-10-22 05:33:52 -0700268
robertphillipsfd61ed02014-10-28 07:21:44 -0700269 atlasCanvas->setMatrix(initialCTM);
robertphillips9e6835d2014-10-22 05:33:52 -0700270 atlasCanvas->concat(atlased[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700271
mtklein9db912c2015-05-19 11:11:26 -0700272 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700273 atlasCanvas->restore();
274 }
275
276 atlasCanvas->flush();
277 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700278}
robertphillips98d709b2014-09-02 10:20:50 -0700279
robertphillips95145a92015-01-14 08:08:21 -0800280SkBitmap wrap_texture(GrTexture* texture) {
281 SkASSERT(texture);
282
283 SkBitmap result;
bsalomon74f681d2015-06-23 14:38:48 -0700284 result.setInfo(texture->surfacePriv().info(kPremul_SkAlphaType));
halcanary385fe4d2015-08-26 13:07:48 -0700285 result.setPixelRef(new SkGrPixelRef(result.info(), texture))->unref();
robertphillips95145a92015-01-14 08:08:21 -0800286 return result;
287}
288
robertphillips478dd722014-12-16 08:25:55 -0800289void GrLayerHoister::FilterLayer(GrContext* context,
290 SkGpuDevice* device,
291 const GrHoistedLayer& info) {
292 GrCachedLayer* layer = info.fLayer;
293
robertphillips7b9e8a42014-12-11 08:20:31 -0800294 SkASSERT(layer->filter());
295
296 static const int kDefaultCacheSize = 32 * 1024 * 1024;
297
robertphillips478dd722014-12-16 08:25:55 -0800298 SkBitmap filteredBitmap;
299 SkIPoint offset = SkIPoint::Make(0, 0);
robertphillips7b9e8a42014-12-11 08:20:31 -0800300
robertphillips478dd722014-12-16 08:25:55 -0800301 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips7b9e8a42014-12-11 08:20:31 -0800302
robertphillips478dd722014-12-16 08:25:55 -0800303 SkMatrix totMat = SkMatrix::I();
304 totMat.preConcat(info.fPreMat);
305 totMat.preConcat(info.fLocalMat);
306 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
robertphillips7b9e8a42014-12-11 08:20:31 -0800307
robertphillips478dd722014-12-16 08:25:55 -0800308 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
309 SkIRect clipBounds = layer->rect();
robertphillips7b9e8a42014-12-11 08:20:31 -0800310
robertphillips478dd722014-12-16 08:25:55 -0800311 // This cache is transient, and is freed (along with all its contained
312 // textures) when it goes out of scope.
313 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefaultCacheSize));
314 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
315
robertphillipsefbffed2015-06-22 12:06:08 -0700316 SkImageFilter::Proxy proxy(device);
robertphillips95145a92015-01-14 08:08:21 -0800317 const SkBitmap src = wrap_texture(layer->texture());
318
319 if (!layer->filter()->filterImage(&proxy, src, filterContext, &filteredBitmap, &offset)) {
320 // Filtering failed. Press on with the unfiltered version.
robertphillips478dd722014-12-16 08:25:55 -0800321 return;
robertphillips7b9e8a42014-12-11 08:20:31 -0800322 }
robertphillips478dd722014-12-16 08:25:55 -0800323
324 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
325 layer->setTexture(filteredBitmap.getTexture(), newRect);
326 layer->setOffset(offset);
robertphillips7b9e8a42014-12-11 08:20:31 -0800327}
328
robertphillipsfd61ed02014-10-28 07:21:44 -0700329void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers) {
330 for (int i = 0; i < layers.count(); ++i) {
331 GrCachedLayer* layer = layers[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700332 const SkBigPicture* pict = layers[i].fPicture->asSkBigPicture();
333 if (!pict) {
334 // TODO: can we assume / assert this?
335 continue;
336 }
robertphillips478dd722014-12-16 08:25:55 -0800337 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips98d709b2014-09-02 10:20:50 -0700338
339 // Each non-atlased layer has its own GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800340 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700341 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800342 layer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700343
344 SkCanvas* layerCanvas = surface->getCanvas();
345
robertphillips9e6835d2014-10-22 05:33:52 -0700346 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
347
robertphillips98d709b2014-09-02 10:20:50 -0700348 // Add a rect clip to make sure the rendering doesn't
robertphillipsfd61ed02014-10-28 07:21:44 -0700349 // extend beyond the boundaries of the layer
robertphillipse99d4992014-12-03 07:33:57 -0800350 const SkRect bound = SkRect::Make(layer->rect());
robertphillipsfd61ed02014-10-28 07:21:44 -0700351 layerCanvas->clipRect(bound);
robertphillips98d709b2014-09-02 10:20:50 -0700352 layerCanvas->clear(SK_ColorTRANSPARENT);
353
robertphillips4815fe52014-09-16 10:32:43 -0700354 SkMatrix initialCTM;
robertphillips9e6835d2014-10-22 05:33:52 -0700355 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
robertphillipsfd61ed02014-10-28 07:21:44 -0700356 initialCTM.preConcat(layers[i].fPreMat);
robertphillips4815fe52014-09-16 10:32:43 -0700357
robertphillipsfd61ed02014-10-28 07:21:44 -0700358 layerCanvas->setMatrix(initialCTM);
359 layerCanvas->concat(layers[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700360
mtklein9db912c2015-05-19 11:11:26 -0700361 pict->partialPlayback(layerCanvas, layer->start()+1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700362 layerCanvas->flush();
robertphillips7b9e8a42014-12-11 08:20:31 -0800363
364 if (layer->filter()) {
365 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get());
366
robertphillips478dd722014-12-16 08:25:55 -0800367 FilterLayer(context, gpuSurf->getDevice(), layers[i]);
robertphillips7b9e8a42014-12-11 08:20:31 -0800368 }
robertphillips98d709b2014-09-02 10:20:50 -0700369 }
370}
371
robertphillipsd61ef012014-10-08 05:17:02 -0700372void GrLayerHoister::UnlockLayers(GrContext* context,
robertphillipsfd61ed02014-10-28 07:21:44 -0700373 const SkTDArray<GrHoistedLayer>& layers) {
robertphillipsd61ef012014-10-08 05:17:02 -0700374 GrLayerCache* layerCache = context->getLayerCache();
robertphillips30d2cc62014-09-24 08:52:18 -0700375
robertphillipsfd61ed02014-10-28 07:21:44 -0700376 for (int i = 0; i < layers.count(); ++i) {
377 layerCache->removeUse(layers[i].fLayer);
robertphillipsb5a97152014-09-30 11:33:02 -0700378 }
379
robertphillips4ab5a902014-10-29 13:56:02 -0700380 SkDEBUGCODE(layerCache->validate();)
381}
382
383void GrLayerHoister::PurgeCache(GrContext* context) {
384#if !GR_CACHE_HOISTED_LAYERS
385 GrLayerCache* layerCache = context->getLayerCache();
386
robertphillips30d2cc62014-09-24 08:52:18 -0700387 // This code completely clears out the atlas. It is required when
388 // caching is disabled so the atlas doesn't fill up and force more
389 // free floating layers
robertphillips98d709b2014-09-02 10:20:50 -0700390 layerCache->purgeAll();
391#endif
robertphillips98d709b2014-09-02 10:20:50 -0700392}