Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Side by Side Diff: src/gpu/GrLayerHoister.cpp

Issue 1950523002: Remove GrLayerHoister (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Forgot to remove some files Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrLayerHoister.h ('k') | src/gpu/GrRecordReplaceDraw.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
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 "SkBigPicture.h"
9 #include "SkCanvas.h"
10 #include "SkImageFilterCache.h"
11 #include "SkLayerInfo.h"
12 #include "SkRecordDraw.h"
13 #include "SkSpecialImage.h"
14 #include "SkSurface.h"
15
16 #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
24 // Create the layer information for the hoisted layer and secure the
25 // required texture/render target resources.
26 static void prepare_for_hoisting(GrLayerCache* layerCache,
27 const SkPicture* topLevelPicture,
28 const SkMatrix& initialMat,
29 const SkLayerInfo::BlockInfo& info,
30 const SkIRect& srcIR,
31 const SkIRect& dstIR,
32 SkTDArray<GrHoistedLayer>* needRendering,
33 SkTDArray<GrHoistedLayer>* recycled,
34 bool attemptToAtlas,
35 int numSamples) {
36 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
37
38 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->unique ID(),
39 SkToInt(info.fSaveLayer OpID),
40 SkToInt(info.fRestoreOp ID),
41 srcIR,
42 dstIR,
43 initialMat,
44 info.fKey,
45 info.fKeySize,
46 info.fPaint);
47 GrSurfaceDesc desc;
48 desc.fFlags = kRenderTarget_GrSurfaceFlag;
49 desc.fWidth = srcIR.width();
50 desc.fHeight = srcIR.height();
51 desc.fConfig = kSkia8888_GrPixelConfig;
52 desc.fSampleCnt = numSamples;
53
54 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) {
61 // GPU resources could not be secured for the hoisting of this layer
62 return;
63 }
64
65 if (attemptToAtlas) {
66 SkASSERT(layer->isAtlased());
67 }
68
69 GrHoistedLayer* hl;
70
71 if (needsRendering) {
72 if (!attemptToAtlas) {
73 SkASSERT(!layer->isAtlased());
74 }
75 hl = needRendering->append();
76 } else {
77 hl = recycled->append();
78 }
79
80 layerCache->addUse(layer);
81 hl->fLayer = layer;
82 hl->fPicture = pict;
83 hl->fLocalMat = info.fLocalMat;
84 hl->fInitialMat = initialMat;
85 hl->fPreMat = initialMat;
86 hl->fPreMat.preConcat(info.fPreMat);
87 }
88
89 // Compute the source rect and return false if it is empty.
90 static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatr ix& 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()) {
99 clipBounds = info.fPaint->getImageFilter()->filterBounds(clipBounds, tot Mat);
100 }
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
115 return true;
116 }
117
118 // 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.
121 void GrLayerHoister::FindLayersToAtlas(GrContext* context,
122 const SkPicture* topLevelPicture,
123 const SkMatrix& initialMat,
124 const SkRect& query,
125 SkTDArray<GrHoistedLayer>* atlased,
126 SkTDArray<GrHoistedLayer>* recycled,
127 int numSamples) {
128 if (0 != numSamples) {
129 // MSAA layers are currently never atlased
130 return;
131 }
132
133 GrLayerCache* layerCache = context->getLayerCache();
134 layerCache->processDeletedPictures();
135
136 const SkBigPicture::AccelData* topLevelData = nullptr;
137 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
138 topLevelData = bp->accelData();
139 }
140 if (!topLevelData) {
141 return;
142 }
143
144 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve lData);
145 if (0 == topLevelGPUData->numBlocks()) {
146 return;
147 }
148
149 atlased->setReserve(atlased->count() + topLevelGPUData->numBlocks());
150
151 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
152 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
153
154 // 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
162 SkRect layerRect;
163 initialMat.mapRect(&layerRect, info.fBounds);
164 if (!layerRect.intersect(query)) {
165 continue;
166 }
167
168 const SkIRect dstIR = layerRect.roundOut();
169
170 SkIRect srcIR;
171
172 if (!compute_source_rect(info, initialMat, dstIR, &srcIR) ||
173 !GrLayerCache::PlausiblyAtlasable(srcIR.width(), srcIR.height())) {
174 continue;
175 }
176
177 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
178 info, srcIR, dstIR, atlased, recycled, true, 0);
179 }
180
181 }
182
183 void GrLayerHoister::FindLayersToHoist(GrContext* context,
184 const SkPicture* topLevelPicture,
185 const SkMatrix& initialMat,
186 const SkRect& query,
187 SkTDArray<GrHoistedLayer>* needRendering,
188 SkTDArray<GrHoistedLayer>* recycled,
189 int numSamples) {
190 GrLayerCache* layerCache = context->getLayerCache();
191
192 layerCache->processDeletedPictures();
193
194 const SkBigPicture::AccelData* topLevelData = nullptr;
195 if (const SkBigPicture* bp = topLevelPicture->asSkBigPicture()) {
196 topLevelData = bp->accelData();
197 }
198 if (!topLevelData) {
199 return;
200 }
201
202 const SkLayerInfo *topLevelGPUData = static_cast<const SkLayerInfo*>(topLeve lData);
203 if (0 == topLevelGPUData->numBlocks()) {
204 return;
205 }
206
207 // Find and prepare for hoisting all the layers that intersect the query rec t
208 for (int i = 0; i < topLevelGPUData->numBlocks(); ++i) {
209 const SkLayerInfo::BlockInfo& info = topLevelGPUData->block(i);
210 if (info.fIsNested) {
211 // Parent layers are currently hoisted while nested layers are not.
212 continue;
213 }
214
215 SkRect layerRect;
216 initialMat.mapRect(&layerRect, info.fBounds);
217 if (!layerRect.intersect(query)) {
218 continue;
219 }
220
221 const SkIRect dstIR = layerRect.roundOut();
222
223 SkIRect srcIR;
224 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
225 continue;
226 }
227
228 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcI R, dstIR,
229 needRendering, recycled, false, numSamples);
230 }
231 }
232
233 void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
234 const SkTDArray<GrHoistedLayer>& atlased) {
235 if (atlased.count() > 0) {
236 // All the atlased layers are rendered into the same GrTexture
237 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
238 sk_sp<SkSurface> surface(SkSurface::MakeRenderTargetDirect(
239 atlased[0].fLayer->texture()->asRenderTa rget(), &props));
240
241 SkCanvas* atlasCanvas = surface->getCanvas();
242
243 for (int i = 0; i < atlased.count(); ++i) {
244 const GrCachedLayer* layer = atlased[i].fLayer;
245 const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
246 if (!pict) {
247 // TODO: can we assume / assert this?
248 continue;
249 }
250 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer-> srcIR().fTop);
251 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
252
253 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
254 SkASSERT(!layer->filter());
255
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
260 const SkRect bound = SkRect::Make(layer->rect());
261 atlasCanvas->clipRect(bound);
262 atlasCanvas->clear(0);
263
264 // '-offset' maps the layer's top/left to the origin.
265 // Since this layer is atlased, the top/left corner needs
266 // to be offset to the correct location in the backing texture.
267 SkMatrix initialCTM;
268 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-of fset.fY));
269 initialCTM.preTranslate(bound.fLeft, bound.fTop);
270 initialCTM.preConcat(atlased[i].fPreMat);
271
272 atlasCanvas->setMatrix(initialCTM);
273 atlasCanvas->concat(atlased[i].fLocalMat);
274
275 pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop() , initialCTM);
276 atlasCanvas->restore();
277 }
278
279 atlasCanvas->flush();
280 }
281 }
282
283 void GrLayerHoister::FilterLayer(GrContext* context,
284 const SkSurfaceProps* props,
285 const GrHoistedLayer& info) {
286 GrCachedLayer* layer = info.fLayer;
287
288 SkASSERT(layer->filter());
289
290 static const int kDefaultCacheSize = 32 * 1024 * 1024;
291
292 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->sr cIR().fTop);
293
294 SkMatrix totMat(info.fPreMat);
295 totMat.preConcat(info.fLocalMat);
296 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterO ffset.fY));
297
298 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
299 const SkIRect& clipBounds = layer->rect();
300
301 // This cache is transient, and is freed (along with all its contained
302 // textures) when it goes out of scope.
303 SkAutoTUnref<SkImageFilterCache> cache(SkImageFilterCache::Create(kDefaultCa cheSize));
304 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
305
306 // TODO: should the layer hoister store stand alone layers as SkSpecialImage s internally?
307 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());
310 sk_sp<SkSpecialImage> img(SkSpecialImage::MakeFromGpu(subset,
311 kNeedNewImageUniqueID_ SpecialImage,
312 sk_ref_sp(layer->textu re()),
313 props));
314
315 SkIPoint offset = SkIPoint::Make(0, 0);
316 sk_sp<SkSpecialImage> result(layer->filter()->filterImage(img.get(),
317 filterContext,
318 &offset));
319 if (!result) {
320 // Filtering failed. Press on with the unfiltered version.
321 return;
322 }
323
324 SkASSERT(result->isTextureBacked());
325 sk_sp<GrTexture> texture(result->asTextureRef(context));
326 layer->setTexture(texture.get(), result->subset(), false);
327 layer->setOffset(offset);
328 }
329
330 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay er>& layers) {
331 for (int i = 0; i < layers.count(); ++i) {
332 GrCachedLayer* layer = layers[i].fLayer;
333 const SkBigPicture* pict = layers[i].fPicture->asSkBigPicture();
334 if (!pict) {
335 // TODO: can we assume / assert this?
336 continue;
337 }
338 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcI R().fTop);
339
340 // Each non-atlased layer has its own GrTexture
341 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
342 auto surface(SkSurface::MakeRenderTargetDirect(
343 layer->texture()->asRenderTarget(), &pro ps));
344
345 SkCanvas* layerCanvas = surface->getCanvas();
346
347 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
348
349 // Add a rect clip to make sure the rendering doesn't
350 // extend beyond the boundaries of the layer
351 const SkRect bound = SkRect::Make(layer->rect());
352 layerCanvas->clipRect(bound);
353 layerCanvas->clear(SK_ColorTRANSPARENT);
354
355 SkMatrix initialCTM;
356 initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset .fY));
357 initialCTM.preConcat(layers[i].fPreMat);
358
359 layerCanvas->setMatrix(initialCTM);
360 layerCanvas->concat(layers[i].fLocalMat);
361
362 pict->partialPlayback(layerCanvas, layer->start()+1, layer->stop(), init ialCTM);
363 layerCanvas->flush();
364
365 if (layer->filter()) {
366 FilterLayer(context, &surface->props(), layers[i]);
367 }
368 }
369 }
370
371 void GrLayerHoister::UnlockLayers(GrContext* context,
372 const SkTDArray<GrHoistedLayer>& layers) {
373 GrLayerCache* layerCache = context->getLayerCache();
374
375 for (int i = 0; i < layers.count(); ++i) {
376 layerCache->removeUse(layers[i].fLayer);
377 }
378
379 SkDEBUGCODE(layerCache->validate();)
380 }
381
382 void GrLayerHoister::Begin(GrContext* context) {
383 GrLayerCache* layerCache = context->getLayerCache();
384
385 layerCache->begin();
386 }
387
388 void GrLayerHoister::End(GrContext* context) {
389 GrLayerCache* layerCache = context->getLayerCache();
390
391 #if !GR_CACHE_HOISTED_LAYERS
392
393 // 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
396 layerCache->purgeAll();
397 #endif
398
399 layerCache->end();
400 }
401
402 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrLayerHoister.h ('k') | src/gpu/GrRecordReplaceDraw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698