diff options
author | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-15 19:02:43 +0000 |
---|---|---|
committer | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-15 19:02:43 +0000 |
commit | 01bdf3c568f9df2df4a787197caeba736b23fe73 (patch) | |
tree | 0e7686dbb7e36597d1f7c5792780a654b3ae53e6 | |
parent | b8aa4ddb2d8b2542b3fa4df28888bcd0fee51bd4 (diff) |
Add crop rect support for SkDisplacementMapEffect (raster and GPU paths).
Covered by new test cases added to displacement GM (will require rebaseline).
R=bsalomon@google.com
Review URL: https://codereview.chromium.org/26531002
git-svn-id: http://skia.googlecode.com/svn/trunk@11782 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | expectations/gm/ignored-tests.txt | 4 | ||||
-rw-r--r-- | gm/displacement.cpp | 61 | ||||
-rw-r--r-- | include/effects/SkDisplacementMapEffect.h | 3 | ||||
-rw-r--r-- | src/effects/SkDisplacementMapEffect.cpp | 68 |
4 files changed, 103 insertions, 33 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt index 9899bd86ea..16fad8e090 100644 --- a/expectations/gm/ignored-tests.txt +++ b/expectations/gm/ignored-tests.txt @@ -30,3 +30,7 @@ # Added by epoger for https://code.google.com/p/skia/issues/detail?id=1657 # ('Poppler random failures'): ignore any Poppler failures, for now pdf-poppler + +# Added by senorblanco as part of https://codereview.chromium.org/26531002/. +# New test cases added; will need rebaseline. +displacement diff --git a/gm/displacement.cpp b/gm/displacement.cpp index 503172011c..587843140b 100644 --- a/gm/displacement.cpp +++ b/gm/displacement.cpp @@ -60,14 +60,14 @@ protected: } virtual SkISize onISize() { - return make_isize(500, 200); + return make_isize(500, 400); } void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) { canvas->save(); - canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y), - SkIntToScalar(fBitmap.width()), SkIntToScalar(fBitmap.height()))); - canvas->drawBitmap(fBitmap, SkIntToScalar(x), SkIntToScalar(y), &paint); + canvas->translate(x, y); + canvas->clipRect(SkRect::MakeWH(SkIntToScalar(fBitmap.width()), SkIntToScalar(fBitmap.height()))); + canvas->drawBitmap(fBitmap, 0, 0, &paint); canvas->restore(); } @@ -121,6 +121,59 @@ protected: (SkDisplacementMapEffect::kR_ChannelSelectorType, SkDisplacementMapEffect::kA_ChannelSelectorType, 40.0f, displ)))->unref(); drawClippedBitmap(canvas, 400, 100, paint); + + SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(30, 30, 40, 40)); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kG_ChannelSelectorType, + 0.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 0, 200, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kB_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 16.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 100, 200, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kB_ChannelSelectorType, + 32.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 200, 200, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kG_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 48.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 300, 200, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 64.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 400, 200, paint); + + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kG_ChannelSelectorType, + 40.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 0, 300, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kB_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 40.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 100, 300, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kB_ChannelSelectorType, + 40.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 200, 300, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kG_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 40.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 300, 300, paint); + paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect, + (SkDisplacementMapEffect::kR_ChannelSelectorType, + SkDisplacementMapEffect::kA_ChannelSelectorType, + 40.0f, displ, NULL, &cropRect)))->unref(); + drawClippedBitmap(canvas, 400, 300, paint); } private: diff --git a/include/effects/SkDisplacementMapEffect.h b/include/effects/SkDisplacementMapEffect.h index ed9d15b15a..d789ca24f2 100644 --- a/include/effects/SkDisplacementMapEffect.h +++ b/include/effects/SkDisplacementMapEffect.h @@ -25,7 +25,8 @@ public: SkDisplacementMapEffect(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, SkScalar scale, SkImageFilter* displacement, - SkImageFilter* color = NULL); + SkImageFilter* color = NULL, + const CropRect* cropRect = NULL); ~SkDisplacementMapEffect(); diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 020ee02913..3722178c29 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -47,20 +47,18 @@ template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>( template<SkDisplacementMapEffect::ChannelSelectorType typeX, SkDisplacementMapEffect::ChannelSelectorType typeY> -void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src) +void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src, const SkIRect& bounds) { static const SkScalar Inv8bit = SkScalarDiv(SK_Scalar1, SkFloatToScalar(255.0f)); - const int dstW = displ->width(); - const int dstH = displ->height(); const int srcW = src->width(); const int srcH = src->height(); const SkScalar scaleForColor = SkScalarMul(scale, Inv8bit); const SkScalar scaleAdj = SK_ScalarHalf - SkScalarMul(scale, SK_ScalarHalf); const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); - for (int y = 0; y < dstH; ++y) { - const SkPMColor* displPtr = displ->getAddr32(0, y); - SkPMColor* dstPtr = dst->getAddr32(0, y); - for (int x = 0; x < dstW; ++x, ++displPtr, ++dstPtr) { + SkPMColor* dstPtr = dst->getAddr32(0, 0); + for (int y = bounds.top(); y < bounds.bottom(); ++y) { + const SkPMColor* displPtr = displ->getAddr32(bounds.left(), y); + for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) { const SkScalar displX = SkScalarMul(scaleForColor, SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj; const SkScalar displY = SkScalarMul(scaleForColor, @@ -68,7 +66,7 @@ void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitma // Truncate the displacement values const int srcX = x + SkScalarTruncToInt(displX); const int srcY = y + SkScalarTruncToInt(displY); - *dstPtr = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ? + *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ? 0 : *(src->getAddr32(srcX, srcY)); } } @@ -76,24 +74,24 @@ void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitma template<SkDisplacementMapEffect::ChannelSelectorType typeX> void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, - SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src) + SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src, const SkIRect& bounds) { switch (yChannelSelector) { case SkDisplacementMapEffect::kR_ChannelSelectorType: computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorType>( - scale, dst, displ, src); + scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kG_ChannelSelectorType: computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorType>( - scale, dst, displ, src); + scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kB_ChannelSelectorType: computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorType>( - scale, dst, displ, src); + scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kA_ChannelSelectorType: computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorType>( - scale, dst, displ, src); + scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: default: @@ -103,24 +101,24 @@ void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSe void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, - SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src) + SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src, const SkIRect& bounds) { switch (xChannelSelector) { case SkDisplacementMapEffect::kR_ChannelSelectorType: computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>( - yChannelSelector, scale, dst, displ, src); + yChannelSelector, scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kG_ChannelSelectorType: computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>( - yChannelSelector, scale, dst, displ, src); + yChannelSelector, scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kB_ChannelSelectorType: computeDisplacement<SkDisplacementMapEffect::kB_ChannelSelectorType>( - yChannelSelector, scale, dst, displ, src); + yChannelSelector, scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kA_ChannelSelectorType: computeDisplacement<SkDisplacementMapEffect::kA_ChannelSelectorType>( - yChannelSelector, scale, dst, displ, src); + yChannelSelector, scale, dst, displ, src, bounds); break; case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: default: @@ -136,8 +134,9 @@ SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSel ChannelSelectorType yChannelSelector, SkScalar scale, SkImageFilter* displacement, - SkImageFilter* color) - : INHERITED(displacement, color) + SkImageFilter* color, + const CropRect* cropRect) + : INHERITED(displacement, color, cropRect) , fXChannelSelector(xChannelSelector) , fYChannelSelector(yChannelSelector) , fScale(scale) @@ -184,14 +183,22 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, if (!displ.getPixels() || !color.getPixels()) { return false; } - dst->setConfig(displ.config(), displ.width(), displ.height()); + SkIRect bounds; + color.getBounds(&bounds); + if (!this->applyCropRect(&bounds, ctm)) { + return false; + } + + dst->setConfig(color.config(), bounds.width(), bounds.height()); dst->allocPixels(); if (!dst->getPixels()) { return false; } - computeDisplacement(fXChannelSelector, fYChannelSelector, fScale, dst, &displ, &color); + computeDisplacement(fXChannelSelector, fYChannelSelector, fScale, dst, &displ, &color, bounds); + offset->fX += bounds.left(); + offset->fY += bounds.top(); return true; } @@ -309,12 +316,17 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, fScale, displacement, color))->unref(); - SkRect srcRect; - src.getBounds(&srcRect); - SkRect dstRect = srcRect; - dstRect.offset(SkIntToScalar(colorOffset.fX), SkIntToScalar(colorOffset.fY)); - context->drawRectToRect(paint, srcRect, dstRect); - return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result); + SkIRect bounds; + src.getBounds(&bounds); + if (!this->applyCropRect(&bounds, ctm)) { + return false; + } + SkRect srcRect = SkRect::Make(bounds); + SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); + context->drawRectToRect(paint, dstRect, srcRect); + offset->fX += bounds.left(); + offset->fY += bounds.top(); + return SkImageFilterUtils::WrapTexture(dst, bounds.width(), bounds.height(), result); } /////////////////////////////////////////////////////////////////////////////// |