blob: 5cc5fa3c0200699c3159f1ed184299196cc7719d [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 "SkDeviceProperties.h"
robertphillips7b9e8a42014-12-11 08:20:31 -080015#include "SkGpuDevice.h"
robertphillips1c4c5282014-09-18 12:03:15 -070016#include "SkGrPixelRef.h"
robertphillips82365912014-11-12 09:32:34 -080017#include "SkLayerInfo.h"
robertphillips3aac6e02014-10-20 08:52:40 -070018#include "SkRecordDraw.h"
robertphillips98d709b2014-09-02 10:20:50 -070019#include "SkSurface.h"
robertphillips7b9e8a42014-12-11 08:20:31 -080020#include "SkSurface_Gpu.h"
robertphillips98d709b2014-09-02 10:20:50 -070021
robertphillipscbe80ca2014-10-09 15:36:06 -070022// Create the layer information for the hoisted layer and secure the
23// required texture/render target resources.
mtklein9db912c2015-05-19 11:11:26 -070024static void prepare_for_hoisting(GrLayerCache* layerCache,
robertphillips232f6b02014-10-09 16:43:42 -070025 const SkPicture* topLevelPicture,
robertphillips01d6e5f2014-12-01 09:09:27 -080026 const SkMatrix& initialMat,
robertphillips82365912014-11-12 09:32:34 -080027 const SkLayerInfo::BlockInfo& info,
robertphillips478dd722014-12-16 08:25:55 -080028 const SkIRect& srcIR,
29 const SkIRect& dstIR,
robertphillipsfd61ed02014-10-28 07:21:44 -070030 SkTDArray<GrHoistedLayer>* needRendering,
31 SkTDArray<GrHoistedLayer>* recycled,
robertphillipsa63f32e2014-11-10 08:10:42 -080032 bool attemptToAtlas,
33 int numSamples) {
robertphillipscbe80ca2014-10-09 15:36:06 -070034 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
35
robertphillips01d6e5f2014-12-01 09:09:27 -080036 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->uniqueID(),
bsalomonfbaace02014-12-12 16:41:46 -080037 SkToInt(info.fSaveLayerOpID),
38 SkToInt(info.fRestoreOpID),
robertphillips478dd722014-12-16 08:25:55 -080039 srcIR,
40 dstIR,
robertphillips01d6e5f2014-12-01 09:09:27 -080041 initialMat,
42 info.fKey,
43 info.fKeySize,
robertphillipscbe80ca2014-10-09 15:36:06 -070044 info.fPaint);
bsalomonf2703d82014-10-28 14:33:06 -070045 GrSurfaceDesc desc;
46 desc.fFlags = kRenderTarget_GrSurfaceFlag;
robertphillips478dd722014-12-16 08:25:55 -080047 desc.fWidth = srcIR.width();
48 desc.fHeight = srcIR.height();
robertphillipscbe80ca2014-10-09 15:36:06 -070049 desc.fConfig = kSkia8888_GrPixelConfig;
robertphillipsa63f32e2014-11-10 08:10:42 -080050 desc.fSampleCnt = numSamples;
robertphillipscbe80ca2014-10-09 15:36:06 -070051
robertphillipsfd61ed02014-10-28 07:21:44 -070052 bool locked, needsRendering;
53 if (attemptToAtlas) {
54 locked = layerCache->tryToAtlas(layer, desc, &needsRendering);
55 } else {
56 locked = layerCache->lock(layer, desc, &needsRendering);
57 }
58 if (!locked) {
robertphillipscbe80ca2014-10-09 15:36:06 -070059 // GPU resources could not be secured for the hoisting of this layer
60 return;
61 }
62
robertphillipsfd61ed02014-10-28 07:21:44 -070063 if (attemptToAtlas) {
64 SkASSERT(layer->isAtlased());
65 }
66
robertphillipscbe80ca2014-10-09 15:36:06 -070067 GrHoistedLayer* hl;
68
69 if (needsRendering) {
robertphillipsfd61ed02014-10-28 07:21:44 -070070 if (!attemptToAtlas) {
71 SkASSERT(!layer->isAtlased());
robertphillipscbe80ca2014-10-09 15:36:06 -070072 }
robertphillipsfd61ed02014-10-28 07:21:44 -070073 hl = needRendering->append();
robertphillipscbe80ca2014-10-09 15:36:06 -070074 } else {
75 hl = recycled->append();
76 }
mtklein9db912c2015-05-19 11:11:26 -070077
robertphillips7bb9ed72014-10-10 11:38:29 -070078 layerCache->addUse(layer);
robertphillipscbe80ca2014-10-09 15:36:06 -070079 hl->fLayer = layer;
80 hl->fPicture = pict;
robertphillips9e6835d2014-10-22 05:33:52 -070081 hl->fLocalMat = info.fLocalMat;
robertphillips01d6e5f2014-12-01 09:09:27 -080082 hl->fInitialMat = initialMat;
83 hl->fPreMat = initialMat;
robertphillips30d78412014-11-24 09:49:17 -080084 hl->fPreMat.preConcat(info.fPreMat);
robertphillipscbe80ca2014-10-09 15:36:06 -070085}
86
robertphillips57f192d2015-01-08 10:15:25 -080087// Compute the source rect and return false if it is empty.
robertphillips478dd722014-12-16 08:25:55 -080088static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatrix& initialMat,
89 const SkIRect& dstIR, SkIRect* srcIR) {
90 SkIRect clipBounds = dstIR;
91
92 SkMatrix totMat = initialMat;
93 totMat.preConcat(info.fPreMat);
94 totMat.preConcat(info.fLocalMat);
95
96 if (info.fPaint && info.fPaint->getImageFilter()) {
97 info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat, &clipBounds);
98 }
99
100 if (!info.fSrcBounds.isEmpty()) {
101 SkRect r;
102
103 totMat.mapRect(&r, info.fSrcBounds);
104 r.roundOut(srcIR);
105
106 if (!srcIR->intersect(clipBounds)) {
107 return false;
108 }
109 } else {
110 *srcIR = clipBounds;
111 }
112
robertphillips478dd722014-12-16 08:25:55 -0800113 return true;
114}
115
robertphillipsfd61ed02014-10-28 07:21:44 -0700116// Atlased layers must be small enough to fit in the atlas, not have a
117// paint with an image filter and be neither nested nor nesting.
118// TODO: allow leaf nested layers to appear in the atlas.
119void GrLayerHoister::FindLayersToAtlas(GrContext* context,
robertphillipsd61ef012014-10-08 05:17:02 -0700120 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800121 const SkMatrix& initialMat,
robertphillips98d709b2014-09-02 10:20:50 -0700122 const SkRect& query,
robertphillipsd61ef012014-10-08 05:17:02 -0700123 SkTDArray<GrHoistedLayer>* atlased,
robertphillipsa63f32e2014-11-10 08:10:42 -0800124 SkTDArray<GrHoistedLayer>* recycled,
125 int numSamples) {
126 if (0 != numSamples) {
127 // MSAA layers are currently never atlased
128 return;
129 }
130
robertphillipsd61ef012014-10-08 05:17:02 -0700131 GrLayerCache* layerCache = context->getLayerCache();
robertphillipsd61ef012014-10-08 05:17:02 -0700132 layerCache->processDeletedPictures();
133
mtklein9db912c2015-05-19 11:11:26 -0700134 const SkBigPicture::AccelData* topLevelData = NULL;
135 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
136 topLevelData = bp->accelData();
137 }
robertphillipscbe80ca2014-10-09 15:36:06 -0700138 if (!topLevelData) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700139 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700140 }
141
robertphillips82365912014-11-12 09:32:34 -0800142 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
143 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700144 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700145 }
146
robertphillips82365912014-11-12 09:32:34 -0800147 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
robertphillipscbe80ca2014-10-09 15:36:06 -0700148
robertphillips82365912014-11-12 09:32:34 -0800149 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
150 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillips98d709b2014-09-02 10:20:50 -0700151
robertphillipsfd61ed02014-10-28 07:21:44 -0700152 // TODO: ignore perspective projected layers here?
153 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
154 (info.fPaint && info.fPaint->getImageFilter());
155
156 if (disallowAtlasing) {
157 continue;
158 }
159
robertphillips30d78412014-11-24 09:49:17 -0800160 SkRect layerRect;
161 initialMat.mapRect(&layerRect, info.fBounds);
robertphillips3aac6e02014-10-20 08:52:40 -0700162 if (!layerRect.intersect(query)) {
robertphillips2ed8a752014-09-03 13:46:02 -0700163 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700164 }
robertphillips98d709b2014-09-02 10:20:50 -0700165
robertphillips478dd722014-12-16 08:25:55 -0800166 const SkIRect dstIR = layerRect.roundOut();
robertphillips3aac6e02014-10-20 08:52:40 -0700167
robertphillips478dd722014-12-16 08:25:55 -0800168 SkIRect srcIR;
169
robertphillips57f192d2015-01-08 10:15:25 -0800170 if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
171 !GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
robertphillips2ed8a752014-09-03 13:46:02 -0700172 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700173 }
robertphillips2ed8a752014-09-03 13:46:02 -0700174
robertphillips30d78412014-11-24 09:49:17 -0800175 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
robertphillips478dd722014-12-16 08:25:55 -0800176 info, srcIR, dstIR, atlased, recycled, true, 0);
robertphillips98d709b2014-09-02 10:20:50 -0700177 }
178
robertphillipsfd61ed02014-10-28 07:21:44 -0700179}
180
181void GrLayerHoister::FindLayersToHoist(GrContext* context,
182 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800183 const SkMatrix& initialMat,
robertphillipsfd61ed02014-10-28 07:21:44 -0700184 const SkRect& query,
185 SkTDArray<GrHoistedLayer>* needRendering,
robertphillipsa63f32e2014-11-10 08:10:42 -0800186 SkTDArray<GrHoistedLayer>* recycled,
187 int numSamples) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700188 GrLayerCache* layerCache = context->getLayerCache();
189
190 layerCache->processDeletedPictures();
191
mtklein9db912c2015-05-19 11:11:26 -0700192 const SkBigPicture::AccelData* topLevelData = NULL;
193 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
194 topLevelData = bp->accelData();
195 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700196 if (!topLevelData) {
197 return;
198 }
199
robertphillips82365912014-11-12 09:32:34 -0800200 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
201 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700202 return;
203 }
204
205 // Find and prepare for hoisting all the layers that intersect the query rect
robertphillips82365912014-11-12 09:32:34 -0800206 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
207 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillipsfd61ed02014-10-28 07:21:44 -0700208 if (info.fIsNested) {
209 // Parent layers are currently hoisted while nested layers are not.
210 continue;
211 }
212
robertphillips30d78412014-11-24 09:49:17 -0800213 SkRect layerRect;
214 initialMat.mapRect(&layerRect, info.fBounds);
robertphillipsfd61ed02014-10-28 07:21:44 -0700215 if (!layerRect.intersect(query)) {
216 continue;
217 }
218
robertphillips478dd722014-12-16 08:25:55 -0800219 const SkIRect dstIR = layerRect.roundOut();
robertphillipsfd61ed02014-10-28 07:21:44 -0700220
robertphillips478dd722014-12-16 08:25:55 -0800221 SkIRect srcIR;
222 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
223 continue;
224 }
225
226 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcIR, dstIR,
robertphillipsa63f32e2014-11-10 08:10:42 -0800227 needRendering, recycled, false, numSamples);
robertphillipsfd61ed02014-10-28 07:21:44 -0700228 }
robertphillips98d709b2014-09-02 10:20:50 -0700229}
230
robertphillipsfd61ed02014-10-28 07:21:44 -0700231void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
232 const SkTDArray<GrHoistedLayer>& atlased) {
robertphillips98d709b2014-09-02 10:20:50 -0700233 if (atlased.count() > 0) {
234 // All the atlased layers are rendered into the same GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800235 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700236 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800237 atlased[0].fLayer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700238
239 SkCanvas* atlasCanvas = surface->getCanvas();
240
robertphillips98d709b2014-09-02 10:20:50 -0700241 for (int i = 0; i < atlased.count(); ++i) {
robertphillips9e6835d2014-10-22 05:33:52 -0700242 const GrCachedLayer* layer = atlased[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700243 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
244 if (!pict) {
245 // TODO: can we assume / assert this?
246 continue;
247 }
robertphillips478dd722014-12-16 08:25:55 -0800248 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips9e6835d2014-10-22 05:33:52 -0700249 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
250
251 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
robertphillips7b9e8a42014-12-11 08:20:31 -0800252 SkASSERT(!layer->filter());
robertphillips98d709b2014-09-02 10:20:50 -0700253
254 atlasCanvas->save();
255
256 // Add a rect clip to make sure the rendering doesn't
257 // extend beyond the boundaries of the atlased sub-rect
robertphillipse99d4992014-12-03 07:33:57 -0800258 const SkRect bound = SkRect::Make(layer->rect());
robertphillips98d709b2014-09-02 10:20:50 -0700259 atlasCanvas->clipRect(bound);
reed8eddfb52014-12-04 07:50:14 -0800260 atlasCanvas->clear(0);
robertphillips98d709b2014-09-02 10:20:50 -0700261
robertphillipsfd61ed02014-10-28 07:21:44 -0700262 // '-offset' maps the layer's top/left to the origin.
robertphillips98d709b2014-09-02 10:20:50 -0700263 // Since this layer is atlased, the top/left corner needs
264 // to be offset to the correct location in the backing texture.
robertphillips4815fe52014-09-16 10:32:43 -0700265 SkMatrix initialCTM;
robertphillipsfd61ed02014-10-28 07:21:44 -0700266 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
267 initialCTM.preTranslate(bound.fLeft, bound.fTop);
268 initialCTM.preConcat(atlased[i].fPreMat);
robertphillips9e6835d2014-10-22 05:33:52 -0700269
robertphillipsfd61ed02014-10-28 07:21:44 -0700270 atlasCanvas->setMatrix(initialCTM);
robertphillips9e6835d2014-10-22 05:33:52 -0700271 atlasCanvas->concat(atlased[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700272
mtklein9db912c2015-05-19 11:11:26 -0700273 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700274 atlasCanvas->restore();
275 }
276
277 atlasCanvas->flush();
278 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700279}
robertphillips98d709b2014-09-02 10:20:50 -0700280
robertphillips95145a92015-01-14 08:08:21 -0800281SkBitmap wrap_texture(GrTexture* texture) {
282 SkASSERT(texture);
283
284 SkBitmap result;
285 result.setInfo(texture->surfacePriv().info());
286 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
287 return result;
288}
289
robertphillips478dd722014-12-16 08:25:55 -0800290void GrLayerHoister::FilterLayer(GrContext* context,
291 SkGpuDevice* device,
292 const GrHoistedLayer& info) {
293 GrCachedLayer* layer = info.fLayer;
294
robertphillips7b9e8a42014-12-11 08:20:31 -0800295 SkASSERT(layer->filter());
296
297 static const int kDefaultCacheSize = 32 * 1024 * 1024;
298
robertphillips478dd722014-12-16 08:25:55 -0800299 SkBitmap filteredBitmap;
300 SkIPoint offset = SkIPoint::Make(0, 0);
robertphillips7b9e8a42014-12-11 08:20:31 -0800301
robertphillips478dd722014-12-16 08:25:55 -0800302 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips7b9e8a42014-12-11 08:20:31 -0800303
robertphillips478dd722014-12-16 08:25:55 -0800304 SkMatrix totMat = SkMatrix::I();
305 totMat.preConcat(info.fPreMat);
306 totMat.preConcat(info.fLocalMat);
307 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
robertphillips7b9e8a42014-12-11 08:20:31 -0800308
robertphillips478dd722014-12-16 08:25:55 -0800309 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
310 SkIRect clipBounds = layer->rect();
robertphillips7b9e8a42014-12-11 08:20:31 -0800311
robertphillips478dd722014-12-16 08:25:55 -0800312 // This cache is transient, and is freed (along with all its contained
313 // textures) when it goes out of scope.
314 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefaultCacheSize));
315 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
316
reed2c55d7b2015-06-09 08:18:39 -0700317 SkImageFilter::Proxy proxy(device, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
robertphillips95145a92015-01-14 08:08:21 -0800318 const SkBitmap src = wrap_texture(layer->texture());
319
320 if (!layer->filter()->filterImage(&proxy, src, filterContext, &filteredBitmap, &offset)) {
321 // Filtering failed. Press on with the unfiltered version.
robertphillips478dd722014-12-16 08:25:55 -0800322 return;
robertphillips7b9e8a42014-12-11 08:20:31 -0800323 }
robertphillips478dd722014-12-16 08:25:55 -0800324
325 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
326 layer->setTexture(filteredBitmap.getTexture(), newRect);
327 layer->setOffset(offset);
robertphillips7b9e8a42014-12-11 08:20:31 -0800328}
329
robertphillipsfd61ed02014-10-28 07:21:44 -0700330void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers) {
331 for (int i = 0; i < layers.count(); ++i) {
332 GrCachedLayer* layer = layers[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700333 const SkBigPicture* pict = layers[i].fPicture->asSkBigPicture();
334 if (!pict) {
335 // TODO: can we assume / assert this?
336 continue;
337 }
robertphillips478dd722014-12-16 08:25:55 -0800338 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips98d709b2014-09-02 10:20:50 -0700339
340 // Each non-atlased layer has its own GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800341 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillips98d709b2014-09-02 10:20:50 -0700342 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800343 layer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700344
345 SkCanvas* layerCanvas = surface->getCanvas();
346
robertphillips9e6835d2014-10-22 05:33:52 -0700347 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
348
robertphillips98d709b2014-09-02 10:20:50 -0700349 // Add a rect clip to make sure the rendering doesn't
robertphillipsfd61ed02014-10-28 07:21:44 -0700350 // extend beyond the boundaries of the layer
robertphillipse99d4992014-12-03 07:33:57 -0800351 const SkRect bound = SkRect::Make(layer->rect());
robertphillipsfd61ed02014-10-28 07:21:44 -0700352 layerCanvas->clipRect(bound);
robertphillips98d709b2014-09-02 10:20:50 -0700353 layerCanvas->clear(SK_ColorTRANSPARENT);
354
robertphillips4815fe52014-09-16 10:32:43 -0700355 SkMatrix initialCTM;
robertphillips9e6835d2014-10-22 05:33:52 -0700356 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
robertphillipsfd61ed02014-10-28 07:21:44 -0700357 initialCTM.preConcat(layers[i].fPreMat);
robertphillips4815fe52014-09-16 10:32:43 -0700358
robertphillipsfd61ed02014-10-28 07:21:44 -0700359 layerCanvas->setMatrix(initialCTM);
360 layerCanvas->concat(layers[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700361
mtklein9db912c2015-05-19 11:11:26 -0700362 pict->partialPlayback(layerCanvas, layer->start()+1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700363 layerCanvas->flush();
robertphillips7b9e8a42014-12-11 08:20:31 -0800364
365 if (layer->filter()) {
366 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get());
367
robertphillips478dd722014-12-16 08:25:55 -0800368 FilterLayer(context, gpuSurf->getDevice(), layers[i]);
robertphillips7b9e8a42014-12-11 08:20:31 -0800369 }
robertphillips98d709b2014-09-02 10:20:50 -0700370 }
371}
372
robertphillipsd61ef012014-10-08 05:17:02 -0700373void GrLayerHoister::UnlockLayers(GrContext* context,
robertphillipsfd61ed02014-10-28 07:21:44 -0700374 const SkTDArray<GrHoistedLayer>& layers) {
robertphillipsd61ef012014-10-08 05:17:02 -0700375 GrLayerCache* layerCache = context->getLayerCache();
robertphillips30d2cc62014-09-24 08:52:18 -0700376
robertphillipsfd61ed02014-10-28 07:21:44 -0700377 for (int i = 0; i < layers.count(); ++i) {
378 layerCache->removeUse(layers[i].fLayer);
robertphillipsb5a97152014-09-30 11:33:02 -0700379 }
380
robertphillips4ab5a902014-10-29 13:56:02 -0700381 SkDEBUGCODE(layerCache->validate();)
382}
383
384void GrLayerHoister::PurgeCache(GrContext* context) {
385#if !GR_CACHE_HOISTED_LAYERS
386 GrLayerCache* layerCache = context->getLayerCache();
387
robertphillips30d2cc62014-09-24 08:52:18 -0700388 // This code completely clears out the atlas. It is required when
389 // caching is disabled so the atlas doesn't fill up and force more
390 // free floating layers
robertphillips98d709b2014-09-02 10:20:50 -0700391 layerCache->purgeAll();
392#endif
robertphillips98d709b2014-09-02 10:20:50 -0700393}