blob: 71c0080d0ef7e6e2756f91ca92d4212df7a59a54 [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
mtklein9db912c2015-05-19 11:11:26 -07008#include "SkBigPicture.h"
robertphillips3aac6e02014-10-20 08:52:40 -07009#include "SkCanvas.h"
senorblanco900c3672016-04-27 11:31:23 -070010#include "SkImageFilterCache.h"
robertphillips82365912014-11-12 09:32:34 -080011#include "SkLayerInfo.h"
robertphillips3aac6e02014-10-20 08:52:40 -070012#include "SkRecordDraw.h"
robertphillips4418dba2016-03-07 12:45:14 -080013#include "SkSpecialImage.h"
robertphillips98d709b2014-09-02 10:20:50 -070014#include "SkSurface.h"
15
robertphillips325474d2016-05-04 11:26:46 -070016#include "GrLayerHoister.h"
17
18#if !defined(SK_IGNORE_GPU_LAYER_HOISTING) && SK_SUPPORT_GPU
19
20#include "GrContext.h"
21#include "GrLayerCache.h"
22#include "GrRecordReplaceDraw.h"
23
robertphillipscbe80ca2014-10-09 15:36:06 -070024// Create the layer information for the hoisted layer and secure the
25// required texture/render target resources.
mtklein9db912c2015-05-19 11:11:26 -070026static void prepare_for_hoisting(GrLayerCache* layerCache,
robertphillips232f6b02014-10-09 16:43:42 -070027 const SkPicture* topLevelPicture,
robertphillips01d6e5f2014-12-01 09:09:27 -080028 const SkMatrix& initialMat,
robertphillips82365912014-11-12 09:32:34 -080029 const SkLayerInfo::BlockInfo& info,
robertphillips478dd722014-12-16 08:25:55 -080030 const SkIRect& srcIR,
31 const SkIRect& dstIR,
robertphillipsfd61ed02014-10-28 07:21:44 -070032 SkTDArray<GrHoistedLayer>* needRendering,
33 SkTDArray<GrHoistedLayer>* recycled,
robertphillipsa63f32e2014-11-10 08:10:42 -080034 bool attemptToAtlas,
35 int numSamples) {
robertphillipscbe80ca2014-10-09 15:36:06 -070036 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
37
robertphillips01d6e5f2014-12-01 09:09:27 -080038 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->uniqueID(),
bsalomonfbaace02014-12-12 16:41:46 -080039 SkToInt(info.fSaveLayerOpID),
40 SkToInt(info.fRestoreOpID),
robertphillips478dd722014-12-16 08:25:55 -080041 srcIR,
42 dstIR,
robertphillips01d6e5f2014-12-01 09:09:27 -080043 initialMat,
44 info.fKey,
45 info.fKeySize,
robertphillipscbe80ca2014-10-09 15:36:06 -070046 info.fPaint);
bsalomonf2703d82014-10-28 14:33:06 -070047 GrSurfaceDesc desc;
48 desc.fFlags = kRenderTarget_GrSurfaceFlag;
robertphillips478dd722014-12-16 08:25:55 -080049 desc.fWidth = srcIR.width();
50 desc.fHeight = srcIR.height();
robertphillipscbe80ca2014-10-09 15:36:06 -070051 desc.fConfig = kSkia8888_GrPixelConfig;
robertphillipsa63f32e2014-11-10 08:10:42 -080052 desc.fSampleCnt = numSamples;
robertphillipscbe80ca2014-10-09 15:36:06 -070053
robertphillipsfd61ed02014-10-28 07:21:44 -070054 bool locked, needsRendering;
55 if (attemptToAtlas) {
56 locked = layerCache->tryToAtlas(layer, desc, &needsRendering);
57 } else {
58 locked = layerCache->lock(layer, desc, &needsRendering);
59 }
60 if (!locked) {
robertphillipscbe80ca2014-10-09 15:36:06 -070061 // GPU resources could not be secured for the hoisting of this layer
62 return;
63 }
64
robertphillipsfd61ed02014-10-28 07:21:44 -070065 if (attemptToAtlas) {
66 SkASSERT(layer->isAtlased());
67 }
68
robertphillipscbe80ca2014-10-09 15:36:06 -070069 GrHoistedLayer* hl;
70
71 if (needsRendering) {
robertphillipsfd61ed02014-10-28 07:21:44 -070072 if (!attemptToAtlas) {
73 SkASSERT(!layer->isAtlased());
robertphillipscbe80ca2014-10-09 15:36:06 -070074 }
robertphillipsfd61ed02014-10-28 07:21:44 -070075 hl = needRendering->append();
robertphillipscbe80ca2014-10-09 15:36:06 -070076 } else {
77 hl = recycled->append();
78 }
mtklein9db912c2015-05-19 11:11:26 -070079
robertphillips7bb9ed72014-10-10 11:38:29 -070080 layerCache->addUse(layer);
robertphillipscbe80ca2014-10-09 15:36:06 -070081 hl->fLayer = layer;
82 hl->fPicture = pict;
robertphillips9e6835d2014-10-22 05:33:52 -070083 hl->fLocalMat = info.fLocalMat;
robertphillips01d6e5f2014-12-01 09:09:27 -080084 hl->fInitialMat = initialMat;
85 hl->fPreMat = initialMat;
robertphillips30d78412014-11-24 09:49:17 -080086 hl->fPreMat.preConcat(info.fPreMat);
robertphillipscbe80ca2014-10-09 15:36:06 -070087}
88
robertphillips57f192d2015-01-08 10:15:25 -080089// Compute the source rect and return false if it is empty.
robertphillips478dd722014-12-16 08:25:55 -080090static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatrix& initialMat,
91 const SkIRect& dstIR, SkIRect* srcIR) {
92 SkIRect clipBounds = dstIR;
93
94 SkMatrix totMat = initialMat;
95 totMat.preConcat(info.fPreMat);
96 totMat.preConcat(info.fLocalMat);
97
98 if (info.fPaint && info.fPaint->getImageFilter()) {
senorblancoe5e79842016-03-21 14:51:59 -070099 clipBounds = info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat);
robertphillips478dd722014-12-16 08:25:55 -0800100 }
101
102 if (!info.fSrcBounds.isEmpty()) {
103 SkRect r;
104
105 totMat.mapRect(&r, info.fSrcBounds);
106 r.roundOut(srcIR);
107
108 if (!srcIR->intersect(clipBounds)) {
109 return false;
110 }
111 } else {
112 *srcIR = clipBounds;
113 }
114
robertphillips478dd722014-12-16 08:25:55 -0800115 return true;
116}
117
robertphillipsfd61ed02014-10-28 07:21:44 -0700118// Atlased layers must be small enough to fit in the atlas, not have a
119// paint with an image filter and be neither nested nor nesting.
120// TODO: allow leaf nested layers to appear in the atlas.
121void GrLayerHoister::FindLayersToAtlas(GrContext* context,
robertphillipsd61ef012014-10-08 05:17:02 -0700122 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800123 const SkMatrix& initialMat,
robertphillips98d709b2014-09-02 10:20:50 -0700124 const SkRect& query,
robertphillipsd61ef012014-10-08 05:17:02 -0700125 SkTDArray<GrHoistedLayer>* atlased,
robertphillipsa63f32e2014-11-10 08:10:42 -0800126 SkTDArray<GrHoistedLayer>* recycled,
127 int numSamples) {
128 if (0 != numSamples) {
129 // MSAA layers are currently never atlased
130 return;
131 }
132
robertphillipsd61ef012014-10-08 05:17:02 -0700133 GrLayerCache* layerCache = context->getLayerCache();
robertphillipsd61ef012014-10-08 05:17:02 -0700134 layerCache->processDeletedPictures();
135
halcanary96fcdcc2015-08-27 07:41:13 -0700136 const SkBigPicture::AccelData* topLevelData = nullptr;
mtklein9db912c2015-05-19 11:11:26 -0700137 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
138 topLevelData = bp->accelData();
139 }
robertphillipscbe80ca2014-10-09 15:36:06 -0700140 if (!topLevelData) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700141 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700142 }
143
robertphillips82365912014-11-12 09:32:34 -0800144 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
145 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700146 return;
robertphillips30d2cc62014-09-24 08:52:18 -0700147 }
148
robertphillips82365912014-11-12 09:32:34 -0800149 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
robertphillipscbe80ca2014-10-09 15:36:06 -0700150
robertphillips82365912014-11-12 09:32:34 -0800151 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
152 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillips98d709b2014-09-02 10:20:50 -0700153
robertphillipsfd61ed02014-10-28 07:21:44 -0700154 // TODO: ignore perspective projected layers here?
155 bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
156 (info.fPaint && info.fPaint->getImageFilter());
157
158 if (disallowAtlasing) {
159 continue;
160 }
161
robertphillips30d78412014-11-24 09:49:17 -0800162 SkRect layerRect;
163 initialMat.mapRect(&layerRect, info.fBounds);
robertphillips3aac6e02014-10-20 08:52:40 -0700164 if (!layerRect.intersect(query)) {
robertphillips2ed8a752014-09-03 13:46:02 -0700165 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700166 }
robertphillips98d709b2014-09-02 10:20:50 -0700167
robertphillips478dd722014-12-16 08:25:55 -0800168 const SkIRect dstIR = layerRect.roundOut();
robertphillips3aac6e02014-10-20 08:52:40 -0700169
robertphillips478dd722014-12-16 08:25:55 -0800170 SkIRect srcIR;
171
robertphillips57f192d2015-01-08 10:15:25 -0800172 if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
173 !GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
robertphillips2ed8a752014-09-03 13:46:02 -0700174 continue;
robertphillips98d709b2014-09-02 10:20:50 -0700175 }
robertphillips2ed8a752014-09-03 13:46:02 -0700176
robertphillips30d78412014-11-24 09:49:17 -0800177 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
robertphillips478dd722014-12-16 08:25:55 -0800178 info, srcIR, dstIR, atlased, recycled, true, 0);
robertphillips98d709b2014-09-02 10:20:50 -0700179 }
180
robertphillipsfd61ed02014-10-28 07:21:44 -0700181}
182
183void GrLayerHoister::FindLayersToHoist(GrContext* context,
184 const SkPicture* topLevelPicture,
robertphillips30d78412014-11-24 09:49:17 -0800185 const SkMatrix& initialMat,
robertphillipsfd61ed02014-10-28 07:21:44 -0700186 const SkRect& query,
187 SkTDArray<GrHoistedLayer>* needRendering,
robertphillipsa63f32e2014-11-10 08:10:42 -0800188 SkTDArray<GrHoistedLayer>* recycled,
189 int numSamples) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700190 GrLayerCache* layerCache = context->getLayerCache();
191
192 layerCache->processDeletedPictures();
193
halcanary96fcdcc2015-08-27 07:41:13 -0700194 const SkBigPicture::AccelData* topLevelData = nullptr;
mtklein9db912c2015-05-19 11:11:26 -0700195 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
196 topLevelData = bp->accelData();
197 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700198 if (!topLevelData) {
199 return;
200 }
201
robertphillips82365912014-11-12 09:32:34 -0800202 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLevelData);
203 if (0 == topLevelGPUData->numBlocks()) {
robertphillipsfd61ed02014-10-28 07:21:44 -0700204 return;
205 }
206
207 // Find and prepare for hoisting all the layers that intersect the query rect
robertphillips82365912014-11-12 09:32:34 -0800208 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
209 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
robertphillipsfd61ed02014-10-28 07:21:44 -0700210 if (info.fIsNested) {
211 // Parent layers are currently hoisted while nested layers are not.
212 continue;
213 }
214
robertphillips30d78412014-11-24 09:49:17 -0800215 SkRect layerRect;
216 initialMat.mapRect(&layerRect, info.fBounds);
robertphillipsfd61ed02014-10-28 07:21:44 -0700217 if (!layerRect.intersect(query)) {
218 continue;
219 }
220
robertphillips478dd722014-12-16 08:25:55 -0800221 const SkIRect dstIR = layerRect.roundOut();
robertphillipsfd61ed02014-10-28 07:21:44 -0700222
robertphillips478dd722014-12-16 08:25:55 -0800223 SkIRect srcIR;
224 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
225 continue;
226 }
227
228 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcIR, dstIR,
robertphillipsa63f32e2014-11-10 08:10:42 -0800229 needRendering, recycled, false, numSamples);
robertphillipsfd61ed02014-10-28 07:21:44 -0700230 }
robertphillips98d709b2014-09-02 10:20:50 -0700231}
232
robertphillipsfd61ed02014-10-28 07:21:44 -0700233void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
234 const SkTDArray<GrHoistedLayer>& atlased) {
robertphillips98d709b2014-09-02 10:20:50 -0700235 if (atlased.count() > 0) {
236 // All the atlased layers are rendered into the same GrTexture
robertphillipsa86a2332014-12-16 14:25:08 -0800237 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
robertphillipsb4511342016-05-03 09:37:08 -0700238 sk_sp<SkSurface> surface(SkSurface::MakeRenderTargetDirect(
robertphillipsa86a2332014-12-16 14:25:08 -0800239 atlased[0].fLayer->texture()->asRenderTarget(), &props));
robertphillips98d709b2014-09-02 10:20:50 -0700240
241 SkCanvas* atlasCanvas = surface->getCanvas();
242
robertphillips98d709b2014-09-02 10:20:50 -0700243 for (int i = 0; i < atlased.count(); ++i) {
robertphillips9e6835d2014-10-22 05:33:52 -0700244 const GrCachedLayer* layer = atlased[i].fLayer;
mtklein9db912c2015-05-19 11:11:26 -0700245 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
246 if (!pict) {
247 // TODO: can we assume / assert this?
248 continue;
249 }
robertphillips478dd722014-12-16 08:25:55 -0800250 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips9e6835d2014-10-22 05:33:52 -0700251 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
252
253 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
robertphillips7b9e8a42014-12-11 08:20:31 -0800254 SkASSERT(!layer->filter());
robertphillips98d709b2014-09-02 10:20:50 -0700255
256 atlasCanvas->save();
257
258 // Add a rect clip to make sure the rendering doesn't
259 // extend beyond the boundaries of the atlased sub-rect
robertphillipse99d4992014-12-03 07:33:57 -0800260 const SkRect bound = SkRect::Make(layer->rect());
robertphillips98d709b2014-09-02 10:20:50 -0700261 atlasCanvas->clipRect(bound);
reed8eddfb52014-12-04 07:50:14 -0800262 atlasCanvas->clear(0);
robertphillips98d709b2014-09-02 10:20:50 -0700263
robertphillipsfd61ed02014-10-28 07:21:44 -0700264 // '-offset' maps the layer's top/left to the origin.
robertphillips98d709b2014-09-02 10:20:50 -0700265 // Since this layer is atlased, the top/left corner needs
266 // to be offset to the correct location in the backing texture.
robertphillips4815fe52014-09-16 10:32:43 -0700267 SkMatrix initialCTM;
robertphillipsfd61ed02014-10-28 07:21:44 -0700268 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
269 initialCTM.preTranslate(bound.fLeft, bound.fTop);
270 initialCTM.preConcat(atlased[i].fPreMat);
robertphillips9e6835d2014-10-22 05:33:52 -0700271
robertphillipsfd61ed02014-10-28 07:21:44 -0700272 atlasCanvas->setMatrix(initialCTM);
robertphillips9e6835d2014-10-22 05:33:52 -0700273 atlasCanvas->concat(atlased[i].fLocalMat);
robertphillips98d709b2014-09-02 10:20:50 -0700274
mtklein9db912c2015-05-19 11:11:26 -0700275 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
robertphillips98d709b2014-09-02 10:20:50 -0700276 atlasCanvas->restore();
277 }
278
279 atlasCanvas->flush();
280 }
robertphillipsfd61ed02014-10-28 07:21:44 -0700281}
robertphillips98d709b2014-09-02 10:20:50 -0700282
robertphillips478dd722014-12-16 08:25:55 -0800283void GrLayerHoister::FilterLayer(GrContext* context,
robertphillips7715e062016-04-22 10:57:16 -0700284 const SkSurfaceProps* props,
robertphillips478dd722014-12-16 08:25:55 -0800285 const GrHoistedLayer& info) {
286 GrCachedLayer* layer = info.fLayer;
287
robertphillips7b9e8a42014-12-11 08:20:31 -0800288 SkASSERT(layer->filter());
289
290 static const int kDefaultCacheSize = 32 * 1024 * 1024;
291
robertphillips478dd722014-12-16 08:25:55 -0800292 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
robertphillips7b9e8a42014-12-11 08:20:31 -0800293
robertphillips4418dba2016-03-07 12:45:14 -0800294 SkMatrix totMat(info.fPreMat);
robertphillips478dd722014-12-16 08:25:55 -0800295 totMat.preConcat(info.fLocalMat);
296 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
robertphillips7b9e8a42014-12-11 08:20:31 -0800297
robertphillips478dd722014-12-16 08:25:55 -0800298 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
robertphillips4418dba2016-03-07 12:45:14 -0800299 const SkIRect& clipBounds = layer->rect();
robertphillips7b9e8a42014-12-11 08:20:31 -0800300
robertphillips478dd722014-12-16 08:25:55 -0800301 // This cache is transient, and is freed (along with all its contained
302 // textures) when it goes out of scope.
senorblanco900c3672016-04-27 11:31:23 -0700303 SkAutoTUnref<SkImageFilterCache> cache(SkImageFilterCache::Create(kDefaultCacheSize));
reed4e23cda2016-01-11 10:56:59 -0800304 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
robertphillips478dd722014-12-16 08:25:55 -0800305
robertphillips4418dba2016-03-07 12:45:14 -0800306 // TODO: should the layer hoister store stand alone layers as SkSpecialImages internally?
robertphillipsb4511342016-05-03 09:37:08 -0700307 SkASSERT(layer->rect().width() == layer->texture()->width() &&
308 layer->rect().height() == layer->texture()->height());
309 const SkIRect subset = SkIRect::MakeWH(layer->rect().width(), layer->rect().height());
robertphillips3e302272016-04-20 11:48:36 -0700310 sk_sp<SkSpecialImage> img(SkSpecialImage::MakeFromGpu(subset,
robertphillips37bd7c32016-03-17 14:31:39 -0700311 kNeedNewImageUniqueID_SpecialImage,
robertphillipsc91fd342016-04-25 12:32:54 -0700312 sk_ref_sp(layer->texture()),
robertphillips7715e062016-04-22 10:57:16 -0700313 props));
robertphillips4418dba2016-03-07 12:45:14 -0800314
315 SkIPoint offset = SkIPoint::Make(0, 0);
robertphillips2302de92016-03-24 07:26:32 -0700316 sk_sp<SkSpecialImage> result(layer->filter()->filterImage(img.get(),
317 filterContext,
318 &offset));
robertphillips4418dba2016-03-07 12:45:14 -0800319 if (!result) {
robertphillips95145a92015-01-14 08:08:21 -0800320 // 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
robertphillips64612512016-04-08 12:10:42 -0700324 SkASSERT(result->isTextureBacked());
robertphillipsc91fd342016-04-25 12:32:54 -0700325 sk_sp<GrTexture> texture(result->asTextureRef(context));
326 layer->setTexture(texture.get(), result->subset(), false);
robertphillips478dd722014-12-16 08:25:55 -0800327 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);
reede8f30622016-03-23 18:59:25 -0700342 auto surface(SkSurface::MakeRenderTargetDirect(
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()) {
robertphillips7715e062016-04-22 10:57:16 -0700366 FilterLayer(context, &surface->props(), layers[i]);
robertphillips7b9e8a42014-12-11 08:20:31 -0800367 }
robertphillips98d709b2014-09-02 10:20:50 -0700368 }
369}
370
robertphillipsd61ef012014-10-08 05:17:02 -0700371void GrLayerHoister::UnlockLayers(GrContext* context,
robertphillipsfd61ed02014-10-28 07:21:44 -0700372 const SkTDArray<GrHoistedLayer>& layers) {
robertphillipsd61ef012014-10-08 05:17:02 -0700373 GrLayerCache* layerCache = context->getLayerCache();
robertphillips30d2cc62014-09-24 08:52:18 -0700374
robertphillipsfd61ed02014-10-28 07:21:44 -0700375 for (int i = 0; i < layers.count(); ++i) {
376 layerCache->removeUse(layers[i].fLayer);
robertphillipsb5a97152014-09-30 11:33:02 -0700377 }
378
robertphillips4ab5a902014-10-29 13:56:02 -0700379 SkDEBUGCODE(layerCache->validate();)
380}
381
robertphillips60029a52015-11-09 13:51:06 -0800382void GrLayerHoister::Begin(GrContext* context) {
robertphillipscf1d1982015-11-06 05:59:14 -0800383 GrLayerCache* layerCache = context->getLayerCache();
robertphillips42597bc2015-11-06 04:14:55 -0800384
robertphillips60029a52015-11-09 13:51:06 -0800385 layerCache->begin();
386}
387
388void GrLayerHoister::End(GrContext* context) {
389 GrLayerCache* layerCache = context->getLayerCache();
390
391#if !GR_CACHE_HOISTED_LAYERS
392
robertphillips30d2cc62014-09-24 08:52:18 -0700393 // This code completely clears out the atlas. It is required when
394 // caching is disabled so the atlas doesn't fill up and force more
395 // free floating layers
robertphillips98d709b2014-09-02 10:20:50 -0700396 layerCache->purgeAll();
397#endif
robertphillips60029a52015-11-09 13:51:06 -0800398
399 layerCache->end();
robertphillips98d709b2014-09-02 10:20:50 -0700400}
robertphillips325474d2016-05-04 11:26:46 -0700401
402#endif