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

Side by Side Diff: src/effects/SkBlurMaskFilter.cpp

Issue 729463002: Cache blur mask for rects which can not break into nine-patch (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: handle clipped path Created 5 years, 11 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/core/SkMaskFilter.cpp ('k') | no next file » | 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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkBlurMaskFilter.h" 9 #include "SkBlurMaskFilter.h"
10 #include "SkBlurMask.h" 10 #include "SkBlurMask.h"
11 #include "SkGpuBlurUtils.h" 11 #include "SkGpuBlurUtils.h"
12 #include "SkReadBuffer.h" 12 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkMaskCache.h"
14 #include "SkMaskFilter.h" 15 #include "SkMaskFilter.h"
15 #include "SkRRect.h" 16 #include "SkRRect.h"
16 #include "SkRTConf.h" 17 #include "SkRTConf.h"
17 #include "SkStringUtils.h" 18 #include "SkStringUtils.h"
18 #include "SkStrokeRec.h" 19 #include "SkStrokeRec.h"
19 20
20 #if SK_SUPPORT_GPU 21 #if SK_SUPPORT_GPU
21 #include "GrContext.h" 22 #include "GrContext.h"
22 #include "GrTexture.h" 23 #include "GrTexture.h"
23 #include "GrFragmentProcessor.h" 24 #include "GrFragmentProcessor.h"
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 canvas.drawPath(path, paint); 254 canvas.drawPath(path, paint);
254 } 255 }
255 return true; 256 return true;
256 } 257 }
257 258
258 static bool rect_exceeds(const SkRect& r, SkScalar v) { 259 static bool rect_exceeds(const SkRect& r, SkScalar v) {
259 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || 260 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v ||
260 r.width() > v || r.height() > v; 261 r.width() > v || r.height() > v;
261 } 262 }
262 263
263 #include "SkMaskCache.h"
264
265 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) {
266 const size_t size = data->size();
267 SkASSERT(mask->computeTotalImageSize() <= size);
268
269 mask->fImage = SkMask::AllocImage(size);
270 if (mask->fImage) {
271 memcpy(mask->fImage, data->data(), size);
272 return true;
273 }
274 return false;
275 }
276
277 static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) {
278 const size_t size = mask.computeTotalImageSize();
279 SkCachedData* data = SkResourceCache::NewCachedData(size);
280 if (data) {
281 memcpy(data->writable_data(), mask.fImage, size);
282 return data;
283 }
284 return NULL;
285 }
286
287 static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style,
288 SkBlurQuality quality, const SkRRect& rrect) {
289 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rrect, mask));
290 return data.get() && copy_cacheddata_to_mask(data, mask);
291 }
292
293 static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle sty le,
294 SkBlurQuality quality, const SkRRect& rrect) {
295 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
296 if (data.get()) {
297 SkMaskCache::Add(sigma, style, quality, rrect, mask, data);
298 }
299 }
300
301 static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style,
302 SkBlurQuality quality, const SkRect rects[], int c ount) {
303 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rects, count, mask));
304 return data.get() && copy_cacheddata_to_mask(data, mask);
305 }
306
307 static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle sty le,
308 SkBlurQuality quality, const SkRect rects[], int co unt) {
309 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask));
310 if (data.get()) {
311 SkMaskCache::Add(sigma, style, quality, rects, count, mask, data);
312 }
313 }
314
315 #ifdef SK_IGNORE_FAST_RRECT_BLUR 264 #ifdef SK_IGNORE_FAST_RRECT_BLUR
316 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" ); 265 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" );
317 #else 266 #else
318 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" ); 267 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" );
319 #endif 268 #endif
320 269
321 SkMaskFilter::FilterReturn 270 SkMaskFilter::FilterReturn
322 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, 271 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix,
323 const SkIRect& clipBounds, 272 const SkIRect& clipBounds,
324 NinePatch* patch) const { 273 NinePatch* patch) const {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 362
414 SkRRect smallRR; 363 SkRRect smallRR;
415 SkVector radii[4]; 364 SkVector radii[4];
416 radii[SkRRect::kUpperLeft_Corner] = UL; 365 radii[SkRRect::kUpperLeft_Corner] = UL;
417 radii[SkRRect::kUpperRight_Corner] = UR; 366 radii[SkRRect::kUpperRight_Corner] = UR;
418 radii[SkRRect::kLowerRight_Corner] = LR; 367 radii[SkRRect::kLowerRight_Corner] = LR;
419 radii[SkRRect::kLowerLeft_Corner] = LL; 368 radii[SkRRect::kLowerLeft_Corner] = LL;
420 smallRR.setRectRadii(smallR, radii); 369 smallRR.setRectRadii(smallR, radii);
421 370
422 const SkScalar sigma = this->computeXformedSigma(matrix); 371 const SkScalar sigma = this->computeXformedSigma(matrix);
423 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR)) { 372 if (!SkMaskCache::FindAndCopy(sigma, fBlurStyle, this->getQuality(), smallRR , &patch->fMask)) {
424 bool analyticBlurWorked = false; 373 bool analyticBlurWorked = false;
425 if (c_analyticBlurRRect) { 374 if (c_analyticBlurRRect) {
426 analyticBlurWorked = 375 analyticBlurWorked =
427 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, 376 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin,
428 SkMask::kComputeBoundsAndRenderImage_Creat eMode); 377 SkMask::kComputeBoundsAndRenderImage_Creat eMode);
429 } 378 }
430 379
431 if (!analyticBlurWorked) { 380 if (!analyticBlurWorked) {
432 if (!draw_rrect_into_mask(smallRR, &srcM)) { 381 if (!draw_rrect_into_mask(smallRR, &srcM)) {
433 return kFalse_FilterReturn; 382 return kFalse_FilterReturn;
434 } 383 }
435 384
436 SkAutoMaskFreeImage amf(srcM.fImage); 385 SkAutoMaskFreeImage amf(srcM.fImage);
437 386
438 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 387 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
439 return kFalse_FilterReturn; 388 return kFalse_FilterReturn;
440 } 389 }
441 } 390 }
442 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm allRR); 391 SkMaskCache::AddAndCopy(sigma, fBlurStyle, this->getQuality(), smallRR, patch->fMask);
443 } 392 }
444 393
445 patch->fMask.fBounds.offsetTo(0, 0); 394 patch->fMask.fBounds.offsetTo(0, 0);
446 patch->fOuterRect = dstM.fBounds; 395 patch->fOuterRect = dstM.fBounds;
447 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; 396 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1;
448 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; 397 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1;
449 return kTrue_FilterReturn; 398 return kTrue_FilterReturn;
450 } 399 }
451 400
452 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); 401 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" );
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 if (smallR[0].width() < 2 || smallR[0].height() < 2) { 492 if (smallR[0].width() < 2 || smallR[0].height() < 2) {
544 return kUnimplemented_FilterReturn; 493 return kUnimplemented_FilterReturn;
545 } 494 }
546 if (2 == count) { 495 if (2 == count) {
547 smallR[1].set(rects[1].left(), rects[1].top(), 496 smallR[1].set(rects[1].left(), rects[1].top(),
548 rects[1].right() - dx, rects[1].bottom() - dy); 497 rects[1].right() - dx, rects[1].bottom() - dy);
549 SkASSERT(!smallR[1].isEmpty()); 498 SkASSERT(!smallR[1].isEmpty());
550 } 499 }
551 500
552 const SkScalar sigma = this->computeXformedSigma(matrix); 501 const SkScalar sigma = this->computeXformedSigma(matrix);
553 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallR, count)) { 502 if (!SkMaskCache::FindAndCopy(sigma, fBlurStyle, this->getQuality(),
503 smallR, count, &patch->fMask)) {
554 if (count > 1 || !c_analyticBlurNinepatch) { 504 if (count > 1 || !c_analyticBlurNinepatch) {
555 if (!draw_rects_into_mask(smallR, count, &srcM)) { 505 if (!draw_rects_into_mask(smallR, count, &srcM)) {
556 return kFalse_FilterReturn; 506 return kFalse_FilterReturn;
557 } 507 }
558 508
559 SkAutoMaskFreeImage amf(srcM.fImage); 509 SkAutoMaskFreeImage amf(srcM.fImage);
560 510
561 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 511 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) {
562 return kFalse_FilterReturn; 512 return kFalse_FilterReturn;
563 } 513 }
564 } else { 514 } else {
565 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, 515 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin,
566 SkMask::kComputeBoundsAndRenderImage_Creat eMode)) { 516 SkMask::kComputeBoundsAndRenderImage_Creat eMode)) {
567 return kFalse_FilterReturn; 517 return kFalse_FilterReturn;
568 } 518 }
569 } 519 }
570 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm allR, count); 520 SkMaskCache::AddAndCopy(sigma, fBlurStyle, this->getQuality(), smallR, c ount, patch->fMask);
571 } 521 }
572 patch->fMask.fBounds.offsetTo(0, 0); 522 patch->fMask.fBounds.offsetTo(0, 0);
573 patch->fOuterRect = dstM.fBounds; 523 patch->fOuterRect = dstM.fBounds;
574 patch->fCenter = center; 524 patch->fCenter = center;
575 return kTrue_FilterReturn; 525 return kTrue_FilterReturn;
576 } 526 }
577 527
578 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, 528 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src,
579 SkRect* dst) const { 529 SkRect* dst) const {
580 SkScalar pad = 3.0f * fSigma; 530 SkScalar pad = 3.0f * fSigma;
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 } else { 1215 } else {
1266 str->append("None"); 1216 str->append("None");
1267 } 1217 }
1268 str->append("))"); 1218 str->append("))");
1269 } 1219 }
1270 #endif 1220 #endif
1271 1221
1272 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1222 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter)
1273 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1223 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl)
1274 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1224 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/SkMaskFilter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698