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

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

Issue 790643009: Revert of Fix layer hoisting image filter corner cases (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years 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.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrLayerCache.h" 8 #include "GrLayerCache.h"
9 #include "GrLayerHoister.h" 9 #include "GrLayerHoister.h"
10 #include "GrRecordReplaceDraw.h" 10 #include "GrRecordReplaceDraw.h"
11 11
12 #include "SkCanvas.h" 12 #include "SkCanvas.h"
13 #include "SkGpuDevice.h" 13 #include "SkGpuDevice.h"
14 #include "SkGrPixelRef.h" 14 #include "SkGrPixelRef.h"
15 #include "SkLayerInfo.h" 15 #include "SkLayerInfo.h"
16 #include "SkRecordDraw.h" 16 #include "SkRecordDraw.h"
17 #include "SkSurface.h" 17 #include "SkSurface.h"
18 #include "SkSurface_Gpu.h" 18 #include "SkSurface_Gpu.h"
19 19
20 // Create the layer information for the hoisted layer and secure the 20 // Create the layer information for the hoisted layer and secure the
21 // required texture/render target resources. 21 // required texture/render target resources.
22 static void prepare_for_hoisting(GrLayerCache* layerCache, 22 static void prepare_for_hoisting(GrLayerCache* layerCache,
23 const SkPicture* topLevelPicture, 23 const SkPicture* topLevelPicture,
24 const SkMatrix& initialMat, 24 const SkMatrix& initialMat,
25 const SkLayerInfo::BlockInfo& info, 25 const SkLayerInfo::BlockInfo& info,
26 const SkIRect& srcIR, 26 const SkIRect& layerRect,
27 const SkIRect& dstIR,
28 SkTDArray<GrHoistedLayer>* needRendering, 27 SkTDArray<GrHoistedLayer>* needRendering,
29 SkTDArray<GrHoistedLayer>* recycled, 28 SkTDArray<GrHoistedLayer>* recycled,
30 bool attemptToAtlas, 29 bool attemptToAtlas,
31 int numSamples) { 30 int numSamples) {
32 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture; 31 const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
33 32
34 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->unique ID(), 33 GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->unique ID(),
35 SkToInt(info.fSaveLayer OpID), 34 SkToInt(info.fSaveLayer OpID),
36 SkToInt(info.fRestoreOp ID), 35 SkToInt(info.fRestoreOp ID),
37 srcIR, 36 layerRect,
38 dstIR,
39 initialMat, 37 initialMat,
40 info.fKey, 38 info.fKey,
41 info.fKeySize, 39 info.fKeySize,
42 info.fPaint); 40 info.fPaint);
43 GrSurfaceDesc desc; 41 GrSurfaceDesc desc;
44 desc.fFlags = kRenderTarget_GrSurfaceFlag; 42 desc.fFlags = kRenderTarget_GrSurfaceFlag;
45 desc.fWidth = srcIR.width(); 43 desc.fWidth = layerRect.width();
46 desc.fHeight = srcIR.height(); 44 desc.fHeight = layerRect.height();
47 desc.fConfig = kSkia8888_GrPixelConfig; 45 desc.fConfig = kSkia8888_GrPixelConfig;
48 desc.fSampleCnt = numSamples; 46 desc.fSampleCnt = numSamples;
49 47
50 bool locked, needsRendering; 48 bool locked, needsRendering;
51 if (attemptToAtlas) { 49 if (attemptToAtlas) {
52 locked = layerCache->tryToAtlas(layer, desc, &needsRendering); 50 locked = layerCache->tryToAtlas(layer, desc, &needsRendering);
53 } else { 51 } else {
54 locked = layerCache->lock(layer, desc, &needsRendering); 52 locked = layerCache->lock(layer, desc, &needsRendering);
55 } 53 }
56 if (!locked) { 54 if (!locked) {
(...skipping 18 matching lines...) Expand all
75 73
76 layerCache->addUse(layer); 74 layerCache->addUse(layer);
77 hl->fLayer = layer; 75 hl->fLayer = layer;
78 hl->fPicture = pict; 76 hl->fPicture = pict;
79 hl->fLocalMat = info.fLocalMat; 77 hl->fLocalMat = info.fLocalMat;
80 hl->fInitialMat = initialMat; 78 hl->fInitialMat = initialMat;
81 hl->fPreMat = initialMat; 79 hl->fPreMat = initialMat;
82 hl->fPreMat.preConcat(info.fPreMat); 80 hl->fPreMat.preConcat(info.fPreMat);
83 } 81 }
84 82
85 // Compute the source rect if possible and return false if further processing
86 // on the layer should be abandoned based on its source rect.
87 static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatr ix& 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, &clipBou nds);
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
112 if (!GrLayerCache::PlausiblyAtlasable(srcIR->width(), srcIR->height())) {
113 return false;
114 }
115
116 return true;
117 }
118
119 // Atlased layers must be small enough to fit in the atlas, not have a 83 // Atlased layers must be small enough to fit in the atlas, not have a
120 // paint with an image filter and be neither nested nor nesting. 84 // paint with an image filter and be neither nested nor nesting.
121 // TODO: allow leaf nested layers to appear in the atlas. 85 // TODO: allow leaf nested layers to appear in the atlas.
122 void GrLayerHoister::FindLayersToAtlas(GrContext* context, 86 void GrLayerHoister::FindLayersToAtlas(GrContext* context,
123 const SkPicture* topLevelPicture, 87 const SkPicture* topLevelPicture,
124 const SkMatrix& initialMat, 88 const SkMatrix& initialMat,
125 const SkRect& query, 89 const SkRect& query,
126 SkTDArray<GrHoistedLayer>* atlased, 90 SkTDArray<GrHoistedLayer>* atlased,
127 SkTDArray<GrHoistedLayer>* recycled, 91 SkTDArray<GrHoistedLayer>* recycled,
128 int numSamples) { 92 int numSamples) {
(...skipping 30 matching lines...) Expand all
159 if (disallowAtlasing) { 123 if (disallowAtlasing) {
160 continue; 124 continue;
161 } 125 }
162 126
163 SkRect layerRect; 127 SkRect layerRect;
164 initialMat.mapRect(&layerRect, info.fBounds); 128 initialMat.mapRect(&layerRect, info.fBounds);
165 if (!layerRect.intersect(query)) { 129 if (!layerRect.intersect(query)) {
166 continue; 130 continue;
167 } 131 }
168 132
169 const SkIRect dstIR = layerRect.roundOut(); 133 const SkIRect ir = layerRect.roundOut();
170 134
171 SkIRect srcIR; 135 if (!GrLayerCache::PlausiblyAtlasable(ir.width(), ir.height())) {
172
173 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
174 continue; 136 continue;
175 } 137 }
176 138
177 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, 139 prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
178 info, srcIR, dstIR, atlased, recycled, true, 0); 140 info, ir, atlased, recycled, true, 0);
179 } 141 }
180 142
181 } 143 }
182 144
183 void GrLayerHoister::FindLayersToHoist(GrContext* context, 145 void GrLayerHoister::FindLayersToHoist(GrContext* context,
184 const SkPicture* topLevelPicture, 146 const SkPicture* topLevelPicture,
185 const SkMatrix& initialMat, 147 const SkMatrix& initialMat,
186 const SkRect& query, 148 const SkRect& query,
187 SkTDArray<GrHoistedLayer>* needRendering, 149 SkTDArray<GrHoistedLayer>* needRendering,
188 SkTDArray<GrHoistedLayer>* recycled, 150 SkTDArray<GrHoistedLayer>* recycled,
(...skipping 21 matching lines...) Expand all
210 // Parent layers are currently hoisted while nested layers are not. 172 // Parent layers are currently hoisted while nested layers are not.
211 continue; 173 continue;
212 } 174 }
213 175
214 SkRect layerRect; 176 SkRect layerRect;
215 initialMat.mapRect(&layerRect, info.fBounds); 177 initialMat.mapRect(&layerRect, info.fBounds);
216 if (!layerRect.intersect(query)) { 178 if (!layerRect.intersect(query)) {
217 continue; 179 continue;
218 } 180 }
219 181
220 const SkIRect dstIR = layerRect.roundOut(); 182 const SkIRect ir = layerRect.roundOut();
221 183
222 SkIRect srcIR; 184 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, ir,
223 if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
224 continue;
225 }
226
227 prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcI R, dstIR,
228 needRendering, recycled, false, numSamples); 185 needRendering, recycled, false, numSamples);
229 } 186 }
230 } 187 }
231 188
232 void GrLayerHoister::DrawLayersToAtlas(GrContext* context, 189 void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
233 const SkTDArray<GrHoistedLayer>& atlased) { 190 const SkTDArray<GrHoistedLayer>& atlased) {
234 if (atlased.count() > 0) { 191 if (atlased.count() > 0) {
235 // All the atlased layers are rendered into the same GrTexture 192 // All the atlased layers are rendered into the same GrTexture
236 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( 193 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
237 atlased[0].fLayer->texture()->asRenderTa rget(), NULL)); 194 atlased[0].fLayer->texture()->asRenderTa rget(), NULL));
238 195
239 SkCanvas* atlasCanvas = surface->getCanvas(); 196 SkCanvas* atlasCanvas = surface->getCanvas();
240 197
241 for (int i = 0; i < atlased.count(); ++i) { 198 for (int i = 0; i < atlased.count(); ++i) {
242 const GrCachedLayer* layer = atlased[i].fLayer; 199 const GrCachedLayer* layer = atlased[i].fLayer;
243 const SkPicture* pict = atlased[i].fPicture; 200 const SkPicture* pict = atlased[i].fPicture;
244 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer-> srcIR().fTop); 201 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer-> bound().fTop);
245 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();) 202 SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
246 203
247 SkASSERT(!layerPaint || !layerPaint->getImageFilter()); 204 SkASSERT(!layerPaint || !layerPaint->getImageFilter());
248 SkASSERT(!layer->filter()); 205 SkASSERT(!layer->filter());
249 206
250 atlasCanvas->save(); 207 atlasCanvas->save();
251 208
252 // Add a rect clip to make sure the rendering doesn't 209 // Add a rect clip to make sure the rendering doesn't
253 // extend beyond the boundaries of the atlased sub-rect 210 // extend beyond the boundaries of the atlased sub-rect
254 const SkRect bound = SkRect::Make(layer->rect()); 211 const SkRect bound = SkRect::Make(layer->rect());
(...skipping 15 matching lines...) Expand all
270 pict->drawablePicts(), pict->drawableCount(), 227 pict->drawablePicts(), pict->drawableCount(),
271 layer->start() + 1, layer->stop(), initialCTM); 228 layer->start() + 1, layer->stop(), initialCTM);
272 229
273 atlasCanvas->restore(); 230 atlasCanvas->restore();
274 } 231 }
275 232
276 atlasCanvas->flush(); 233 atlasCanvas->flush();
277 } 234 }
278 } 235 }
279 236
280 void GrLayerHoister::FilterLayer(GrContext* context, 237 void GrLayerHoister::FilterLayer(GrContext* context, SkGpuDevice* device, GrCach edLayer* layer) {
281 SkGpuDevice* device,
282 const GrHoistedLayer& info) {
283 GrCachedLayer* layer = info.fLayer;
284
285 SkASSERT(layer->filter()); 238 SkASSERT(layer->filter());
286 SkASSERT(layer->filter()->canFilterImageGPU());
287 239
288 static const int kDefaultCacheSize = 32 * 1024 * 1024; 240 static const int kDefaultCacheSize = 32 * 1024 * 1024;
289 241
290 SkBitmap filteredBitmap; 242 if (layer->filter()->canFilterImageGPU()) {
291 SkIPoint offset = SkIPoint::Make(0, 0); 243 SkBitmap filteredBitmap;
244 SkIPoint offset = SkIPoint::Make(0, 0);
292 245
293 const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->sr cIR().fTop); 246 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
247 SkIRect clipBounds = layer->rect();
294 248
295 SkMatrix totMat = SkMatrix::I(); 249 // This cache is transient, and is freed (along with all its contained
296 totMat.preConcat(info.fPreMat); 250 // textures) when it goes out of scope.
297 totMat.preConcat(info.fLocalMat); 251 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kD efaultCacheSize));
298 totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterO ffset.fY)); 252 SkImageFilter::Context filterContext(SkMatrix::I(), clipBounds, cache);
299 253
254 if (!device->filterTexture(context, layer->texture(), layer->filter(),
255 filterContext, &filteredBitmap, &offset)) {
256 // Filtering failed. Press on with the unfiltered version
257 return;
258 }
300 259
301 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); 260 // TODO: need to fix up offset
302 SkIRect clipBounds = layer->rect(); 261 SkASSERT(0 == offset.fX && 0 == offset.fY);
303 262
304 // This cache is transient, and is freed (along with all its contained 263 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap .height());
305 // textures) when it goes out of scope. 264 layer->setTexture(filteredBitmap.getTexture(), newRect);
306 SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefau ltCacheSize));
307 SkImageFilter::Context filterContext(totMat, clipBounds, cache);
308
309 if (!device->filterTexture(context, layer->texture(), layer->filter(),
310 filterContext, &filteredBitmap, &offset)) {
311 // Filtering failed. Press on with the unfiltered version
312 return;
313 } 265 }
314
315 SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.hei ght());
316 layer->setTexture(filteredBitmap.getTexture(), newRect);
317 layer->setOffset(offset);
318 } 266 }
319 267
320 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay er>& layers) { 268 void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay er>& layers) {
321 for (int i = 0; i < layers.count(); ++i) { 269 for (int i = 0; i < layers.count(); ++i) {
322 GrCachedLayer* layer = layers[i].fLayer; 270 GrCachedLayer* layer = layers[i].fLayer;
323 const SkPicture* pict = layers[i].fPicture; 271 const SkPicture* pict = layers[i].fPicture;
324 const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcI R().fTop); 272 const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->boun d().fTop);
325 273
326 // Each non-atlased layer has its own GrTexture 274 // Each non-atlased layer has its own GrTexture
327 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( 275 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
328 layer->texture()->asRenderTarget(), NULL )); 276 layer->texture()->asRenderTarget(), NULL ));
329 277
330 SkCanvas* layerCanvas = surface->getCanvas(); 278 SkCanvas* layerCanvas = surface->getCanvas();
331 279
332 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop); 280 SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
333 281
334 // Add a rect clip to make sure the rendering doesn't 282 // Add a rect clip to make sure the rendering doesn't
(...skipping 11 matching lines...) Expand all
346 294
347 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, 295 SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas,
348 pict->drawablePicts(), pict->drawableCount(), 296 pict->drawablePicts(), pict->drawableCount(),
349 layer->start()+1, layer->stop(), initialCTM); 297 layer->start()+1, layer->stop(), initialCTM);
350 298
351 layerCanvas->flush(); 299 layerCanvas->flush();
352 300
353 if (layer->filter()) { 301 if (layer->filter()) {
354 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get()); 302 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get());
355 303
356 FilterLayer(context, gpuSurf->getDevice(), layers[i]); 304 FilterLayer(context, gpuSurf->getDevice(), layer);
357 } 305 }
358 } 306 }
359 } 307 }
360 308
361 void GrLayerHoister::UnlockLayers(GrContext* context, 309 void GrLayerHoister::UnlockLayers(GrContext* context,
362 const SkTDArray<GrHoistedLayer>& layers) { 310 const SkTDArray<GrHoistedLayer>& layers) {
363 GrLayerCache* layerCache = context->getLayerCache(); 311 GrLayerCache* layerCache = context->getLayerCache();
364 312
365 for (int i = 0; i < layers.count(); ++i) { 313 for (int i = 0; i < layers.count(); ++i) {
366 layerCache->removeUse(layers[i].fLayer); 314 layerCache->removeUse(layers[i].fLayer);
367 } 315 }
368 316
369 SkDEBUGCODE(layerCache->validate();) 317 SkDEBUGCODE(layerCache->validate();)
370 } 318 }
371 319
372 void GrLayerHoister::PurgeCache(GrContext* context) { 320 void GrLayerHoister::PurgeCache(GrContext* context) {
373 #if !GR_CACHE_HOISTED_LAYERS 321 #if !GR_CACHE_HOISTED_LAYERS
374 GrLayerCache* layerCache = context->getLayerCache(); 322 GrLayerCache* layerCache = context->getLayerCache();
375 323
376 // This code completely clears out the atlas. It is required when 324 // This code completely clears out the atlas. It is required when
377 // caching is disabled so the atlas doesn't fill up and force more 325 // caching is disabled so the atlas doesn't fill up and force more
378 // free floating layers 326 // free floating layers
379 layerCache->purgeAll(); 327 layerCache->purgeAll();
380 #endif 328 #endif
381 } 329 }
OLDNEW
« no previous file with comments | « src/gpu/GrLayerHoister.h ('k') | src/gpu/GrRecordReplaceDraw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698