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

Side by Side Diff: src/core/SkImageFilter.cpp

Issue 1823573003: Change signatures of filter bounds methods to return a rect. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Hide legacy API behind #ifdef; switch callers to new API Created 4 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The Android Open Source Project 2 * Copyright 2012 The Android Open Source Project
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 "SkImageFilter.h" 8 #include "SkImageFilter.h"
9 #include "SkImageFilterCacheKey.h" 9 #include "SkImageFilterCacheKey.h"
10 10
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), 283 SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(),
284 this->mapContext(ctx), 284 this->mapContext(ctx),
285 offset)); 285 offset));
286 if (!tmp) { 286 if (!tmp) {
287 return false; 287 return false;
288 } 288 }
289 289
290 return tmp->internal_getBM(result); 290 return tmp->internal_getBM(result);
291 } 291 }
292 292
293 #ifdef SK_SUPPORT_LEGACY_FILTERBOUNDS_RETURN
293 bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRec t* dst, 294 bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRec t* dst,
294 MapDirection direction) const { 295 MapDirection direction) const {
295 SkASSERT(dst); 296 *dst = filterBounds(src, ctm, direction);
296 SkIRect bounds; 297 return true;
298 }
299 #endif
300
301 SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
302 MapDirection direction) const {
297 if (kReverse_MapDirection == direction) { 303 if (kReverse_MapDirection == direction) {
298 this->onFilterNodeBounds(src, ctm, &bounds, direction); 304 SkIRect bounds = this->onFilterNodeBounds(src, ctm, direction);
299 return this->onFilterBounds(bounds, ctm, dst, direction); 305 return this->onFilterBounds(bounds, ctm, direction);
300 } else { 306 } else {
301 SkIRect temp; 307 SkIRect bounds = this->onFilterBounds(src, ctm, direction);
302 if (!this->onFilterBounds(src, ctm, &bounds, direction)) { 308 bounds = this->onFilterNodeBounds(bounds, ctm, direction);
303 return false; 309 SkIRect dst;
304 } 310 this->getCropRect().applyTo(bounds, ctm, &dst);
305 this->onFilterNodeBounds(bounds, ctm, &temp, direction); 311 return dst;
306 this->getCropRect().applyTo(temp, ctm, dst);
307 return true;
308 } 312 }
309 } 313 }
310 314
311 void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 315 SkRect SkImageFilter::computeFastBounds(const SkRect& src) const {
312 if (0 == fInputCount) { 316 if (0 == fInputCount) {
313 *dst = src; 317 return src;
314 return;
315 } 318 }
316 // We can't work directly on dst, since src and dst may alias. 319 SkRect combinedBounds = this->getInput(0) ? this->getInput(0)->computeFastBo unds(src) : src;
317 SkRect combinedBounds;
318 if (this->getInput(0)) {
319 this->getInput(0)->computeFastBounds(src, &combinedBounds);
320 } else {
321 combinedBounds = src;
322 }
323 for (int i = 1; i < fInputCount; i++) { 320 for (int i = 1; i < fInputCount; i++) {
324 SkImageFilter* input = this->getInput(i); 321 SkImageFilter* input = this->getInput(i);
325 if (input) { 322 if (input) {
326 SkRect bounds; 323 combinedBounds.join(input->computeFastBounds(src));
327 input->computeFastBounds(src, &bounds);
328 combinedBounds.join(bounds);
329 } else { 324 } else {
330 combinedBounds.join(src); 325 combinedBounds.join(src);
331 } 326 }
332 } 327 }
333 *dst = combinedBounds; 328 return combinedBounds;
334 } 329 }
335 330
336 bool SkImageFilter::canComputeFastBounds() const { 331 bool SkImageFilter::canComputeFastBounds() const {
337 for (int i = 0; i < fInputCount; i++) { 332 for (int i = 0; i < fInputCount; i++) {
338 SkImageFilter* input = this->getInput(i); 333 SkImageFilter* input = this->getInput(i);
339 if (input && !input->canComputeFastBounds()) { 334 if (input && !input->canComputeFastBounds()) {
340 return false; 335 return false;
341 } 336 }
342 } 337 }
343 return true; 338 return true;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 } 430 }
436 if (nullptr != this->getInput(0) || (*filterPtr)->affectsTransparentBlack()) { 431 if (nullptr != this->getInput(0) || (*filterPtr)->affectsTransparentBlack()) {
437 (*filterPtr)->unref(); 432 (*filterPtr)->unref();
438 return false; 433 return false;
439 } 434 }
440 return true; 435 return true;
441 } 436 }
442 437
443 bool SkImageFilter::applyCropRect(const Context& ctx, const SkIRect& srcBounds, 438 bool SkImageFilter::applyCropRect(const Context& ctx, const SkIRect& srcBounds,
444 SkIRect* dstBounds) const { 439 SkIRect* dstBounds) const {
445 this->onFilterNodeBounds(srcBounds, ctx.ctm(), dstBounds, kForward_MapDirect ion); 440 SkIRect temp = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_MapDi rection);
446 fCropRect.applyTo(*dstBounds, ctx.ctm(), dstBounds); 441 fCropRect.applyTo(temp, ctx.ctm(), dstBounds);
447 // Intersect against the clip bounds, in case the crop rect has 442 // Intersect against the clip bounds, in case the crop rect has
448 // grown the bounds beyond the original clip. This can happen for 443 // grown the bounds beyond the original clip. This can happen for
449 // example in tiling, where the clip is much smaller than the filtered 444 // example in tiling, where the clip is much smaller than the filtered
450 // primitive. If we didn't do this, we would be processing the filter 445 // primitive. If we didn't do this, we would be processing the filter
451 // at the full crop rect size in every tile. 446 // at the full crop rect size in every tile.
452 return dstBounds->intersect(ctx.clipBounds()); 447 return dstBounds->intersect(ctx.clipBounds());
453 } 448 }
454 449
455 bool SkImageFilter::applyCropRectDeprecated(const Context& ctx, Proxy* proxy, co nst SkBitmap& src, 450 bool SkImageFilter::applyCropRectDeprecated(const Context& ctx, Proxy* proxy, co nst SkBitmap& src,
456 SkIPoint* srcOffset, SkIRect* bounds , 451 SkIPoint* srcOffset, SkIRect* bounds ,
457 SkBitmap* dst) const { 452 SkBitmap* dst) const {
458 SkIRect srcBounds; 453 SkIRect srcBounds;
459 src.getBounds(&srcBounds); 454 src.getBounds(&srcBounds);
460 srcBounds.offset(*srcOffset); 455 srcBounds.offset(*srcOffset);
461 SkIRect dstBounds; 456 SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_ MapDirection);
462 this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirec tion);
463 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); 457 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds);
464 if (!bounds->intersect(ctx.clipBounds())) { 458 if (!bounds->intersect(ctx.clipBounds())) {
465 return false; 459 return false;
466 } 460 }
467 461
468 if (srcBounds.contains(*bounds)) { 462 if (srcBounds.contains(*bounds)) {
469 *dst = src; 463 *dst = src;
470 return true; 464 return true;
471 } else { 465 } else {
472 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), b ounds->height())); 466 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), b ounds->height()));
(...skipping 30 matching lines...) Expand all
503 return surf->makeImageSnapshot(); 497 return surf->makeImageSnapshot();
504 } 498 }
505 499
506 SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx, 500 SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx,
507 SkSpecialImage* src, 501 SkSpecialImage* src,
508 SkIPoint* srcOffset, 502 SkIPoint* srcOffset,
509 SkIRect* bounds) const { 503 SkIRect* bounds) const {
510 SkIRect srcBounds; 504 SkIRect srcBounds;
511 srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), sr c->height()); 505 srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), sr c->height());
512 506
513 SkIRect dstBounds; 507 SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_ MapDirection);
514 this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirec tion);
515 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); 508 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds);
516 if (!bounds->intersect(ctx.clipBounds())) { 509 if (!bounds->intersect(ctx.clipBounds())) {
517 return nullptr; 510 return nullptr;
518 } 511 }
519 512
520 if (srcBounds.contains(*bounds)) { 513 if (srcBounds.contains(*bounds)) {
521 return SkRef(src); 514 return SkRef(src);
522 } else { 515 } else {
523 sk_sp<SkSpecialImage> img(pad_image(src, 516 sk_sp<SkSpecialImage> img(pad_image(src,
524 bounds->width(), bounds->height(), 517 bounds->width(), bounds->height(),
525 srcOffset->x() - bounds->x(), 518 srcOffset->x() - bounds->x(),
526 srcOffset->y() - bounds->y())); 519 srcOffset->y() - bounds->y()));
527 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); 520 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y());
528 return img.release(); 521 return img.release();
529 } 522 }
530 } 523 }
531 524
532 bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 525 SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
533 SkIRect* dst, MapDirection direction) const { 526 MapDirection direction) const {
534 if (fInputCount < 1) { 527 if (fInputCount < 1) {
535 *dst = src; 528 return src;
536 return true;
537 } 529 }
538 530
539 SkIRect totalBounds; 531 SkIRect totalBounds;
540 for (int i = 0; i < fInputCount; ++i) { 532 for (int i = 0; i < fInputCount; ++i) {
541 SkImageFilter* filter = this->getInput(i); 533 SkImageFilter* filter = this->getInput(i);
542 SkIRect rect = src; 534 SkIRect rect = filter ? filter->filterBounds(src, ctm, direction) : src;
543 if (filter && !filter->filterBounds(src, ctm, &rect, direction)) {
544 return false;
545 }
546 if (0 == i) { 535 if (0 == i) {
547 totalBounds = rect; 536 totalBounds = rect;
548 } else { 537 } else {
549 totalBounds.join(rect); 538 totalBounds.join(rect);
550 } 539 }
551 } 540 }
552 541
553 // don't modify dst until now, so we don't accidentally change it in the 542 return totalBounds;
554 // loop, but then return false on the next filter.
555 *dst = totalBounds;
556 return true;
557 } 543 }
558 544
559 void SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&, 545 SkIRect SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&, M apDirection) const {
560 SkIRect* dst, MapDirection) const { 546 return src;
561 *dst = src;
562 } 547 }
563 548
564 549
565 SkImageFilter::Context SkImageFilter::mapContext(const Context& ctx) const { 550 SkImageFilter::Context SkImageFilter::mapContext(const Context& ctx) const {
566 SkIRect clipBounds; 551 SkIRect clipBounds = this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(),
567 this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(), &clipBounds, 552 MapDirection::kReverse_MapDire ction);
568 MapDirection::kReverse_MapDirection);
569 return Context(ctx.ctm(), clipBounds, ctx.cache()); 553 return Context(ctx.ctm(), clipBounds, ctx.cache());
570 } 554 }
571 555
572 bool SkImageFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, 556 bool SkImageFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*,
573 const SkMatrix&, const SkIRect&) const { 557 const SkMatrix&, const SkIRect&) const {
574 return false; 558 return false;
575 } 559 }
576 560
577 SkImageFilter* SkImageFilter::CreateMatrixFilter(const SkMatrix& matrix, 561 SkImageFilter* SkImageFilter::CreateMatrixFilter(const SkMatrix& matrix,
578 SkFilterQuality filterQuality, 562 SkFilterQuality filterQuality,
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 } 806 }
823 return dev; 807 return dev;
824 } 808 }
825 809
826 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const SkBitmap& src, 810 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const SkBitmap& src,
827 const SkImageFilter::Context& ctx, 811 const SkImageFilter::Context& ctx,
828 SkBitmap* result, SkIPoint* offset) { 812 SkBitmap* result, SkIPoint* offset) {
829 return fDevice->filterImage(filter, src, ctx, result, offset); 813 return fDevice->filterImage(filter, src, ctx, result, offset);
830 } 814 }
831 815
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698