Chromium Code Reviews| Index: src/effects/SkDisplacementMapEffect.cpp |
| diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp |
| index e9a9acb4ce2fae14048d89b3aa19266c0596013f..d0a805dec400c98d75e62fab670aad4c94a7abcc 100644 |
| --- a/src/effects/SkDisplacementMapEffect.cpp |
| +++ b/src/effects/SkDisplacementMapEffect.cpp |
| @@ -47,25 +47,31 @@ template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>( |
| template<SkDisplacementMapEffect::ChannelSelectorType typeX, |
| SkDisplacementMapEffect::ChannelSelectorType typeY> |
| -void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src, const SkIRect& bounds) |
| +void computeDisplacement(const SkVector& scale, SkBitmap* dst, |
| + SkBitmap* displ, const SkIPoint& displOffset, |
| + SkBitmap* src, const SkIPoint& srcOffset, |
| + const SkIRect& bounds) |
| { |
| static const SkScalar Inv8bit = SkScalarDiv(SK_Scalar1, 255.0f); |
| 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 SkVector scaleForColor = SkVector::Make(SkScalarMul(scale.fX, Inv8bit), |
| + SkScalarMul(scale.fY, Inv8bit)); |
| + const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - SkScalarMul(scale.fX, SK_ScalarHalf), |
| + SK_ScalarHalf - SkScalarMul(scale.fY, SK_ScalarHalf)); |
| const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
| SkPMColor* dstPtr = dst->getAddr32(0, 0); |
| for (int y = bounds.top(); y < bounds.bottom(); ++y) { |
| - const SkPMColor* displPtr = displ->getAddr32(bounds.left(), y); |
| + const SkPMColor* displPtr = displ->getAddr32(bounds.left() - displOffset.fX, |
| + y - displOffset.fY); |
| 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, |
| - SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj; |
| + const SkScalar displX = SkScalarMul(scaleForColor.fX, |
| + SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj.fX; |
| + const SkScalar displY = SkScalarMul(scaleForColor.fY, |
| + SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj.fY; |
| // Truncate the displacement values |
| - const int srcX = x + SkScalarTruncToInt(displX); |
| - const int srcY = y + SkScalarTruncToInt(displY); |
| + const int srcX = x + SkScalarTruncToInt(displX) - srcOffset.fX; |
| + const int srcY = y + SkScalarTruncToInt(displY) - srcOffset.fY; |
| *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ? |
| 0 : *(src->getAddr32(srcX, srcY)); |
| } |
| @@ -74,24 +80,27 @@ 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, const SkIRect& bounds) |
| + const SkVector& scale, SkBitmap* dst, |
| + SkBitmap* displ, const SkIPoint& displOffset, |
| + SkBitmap* src, const SkIPoint& srcOffset, |
| + const SkIRect& bounds) |
| { |
| switch (yChannelSelector) { |
| case SkDisplacementMapEffect::kR_ChannelSelectorType: |
| computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorType>( |
| - scale, dst, displ, src, bounds); |
| + scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kG_ChannelSelectorType: |
| computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorType>( |
| - scale, dst, displ, src, bounds); |
| + scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kB_ChannelSelectorType: |
| computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorType>( |
| - scale, dst, displ, src, bounds); |
| + scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kA_ChannelSelectorType: |
| computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorType>( |
| - scale, dst, displ, src, bounds); |
| + scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: |
| default: |
| @@ -101,24 +110,27 @@ void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSe |
| void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
| - SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src, const SkIRect& bounds) |
| + const SkVector& scale, SkBitmap* dst, |
| + SkBitmap* displ, const SkIPoint& displOffset, |
| + SkBitmap* src, const SkIPoint& srcOffset, |
| + const SkIRect& bounds) |
| { |
| switch (xChannelSelector) { |
| case SkDisplacementMapEffect::kR_ChannelSelectorType: |
| computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>( |
| - yChannelSelector, scale, dst, displ, src, bounds); |
| + yChannelSelector, scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kG_ChannelSelectorType: |
| computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>( |
| - yChannelSelector, scale, dst, displ, src, bounds); |
| + yChannelSelector, scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kB_ChannelSelectorType: |
| computeDisplacement<SkDisplacementMapEffect::kB_ChannelSelectorType>( |
| - yChannelSelector, scale, dst, displ, src, bounds); |
| + yChannelSelector, scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kA_ChannelSelectorType: |
| computeDisplacement<SkDisplacementMapEffect::kA_ChannelSelectorType>( |
| - yChannelSelector, scale, dst, displ, src, bounds); |
| + yChannelSelector, scale, dst, displ, displOffset, src, srcOffset, bounds); |
| break; |
| case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: |
| default: |
| @@ -186,8 +198,9 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
| SkBitmap displ = src, color = src; |
| SkImageFilter* colorInput = getColorInput(); |
| SkImageFilter* displacementInput = getDisplacementInput(); |
| - if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, offset)) || |
| - (displacementInput && !displacementInput->filterImage(proxy, src, ctm, &displ, offset))) { |
| + SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); |
| + if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, &colorOffset)) || |
| + (displacementInput && !displacementInput->filterImage(proxy, src, ctm, &displ, &displOffset))) { |
| return false; |
| } |
| if ((displ.config() != SkBitmap::kARGB_8888_Config) || |
| @@ -201,11 +214,13 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
| } |
| SkIRect bounds; |
| color.getBounds(&bounds); |
| + bounds.offset(colorOffset); |
|
sugoi
2014/01/17 21:56:27
We offset the source here and then we subtract a c
Stephen White
2014/01/18 01:23:19
We have to offset it to intersect it below. But we
|
| if (!this->applyCropRect(&bounds, ctm)) { |
| return false; |
| } |
| SkIRect displBounds; |
| displ.getBounds(&displBounds); |
| + displBounds.offset(displOffset); |
| if (!this->applyCropRect(&displBounds, ctm)) { |
| return false; |
| } |
| @@ -219,7 +234,11 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
| return false; |
| } |
| - computeDisplacement(fXChannelSelector, fYChannelSelector, fScale, dst, &displ, &color, bounds); |
| + SkVector scale = SkVector::Make(fScale, fScale); |
| + ctm.mapVectors(&scale, 1); |
| + |
| + computeDisplacement(fXChannelSelector, fYChannelSelector, scale, dst, |
| + &displ, displOffset, &color, colorOffset, bounds); |
| offset->fX = bounds.left(); |
| offset->fY = bounds.top(); |
| @@ -261,12 +280,16 @@ class GrDisplacementMapEffect : public GrEffect { |
| public: |
| static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
| - SkScalar scale, GrTexture* displacement, GrTexture* color) { |
| + SkVector scale, |
| + GrTexture* displacement, const SkMatrix& displacementMatrix, |
| + GrTexture* color, const SkMatrix& colorMatrix) { |
| AutoEffectUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector, |
| yChannelSelector, |
| scale, |
| displacement, |
| - color))); |
| + displacementMatrix, |
| + color, |
| + colorMatrix))); |
| return CreateEffectRef(effect); |
| } |
| @@ -277,7 +300,7 @@ public: |
| { return fXChannelSelector; } |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const |
| { return fYChannelSelector; } |
| - SkScalar scale() const { return fScale; } |
| + const SkVector& scale() const { return fScale; } |
| typedef GrGLDisplacementMapEffect GLEffect; |
| static const char* Name() { return "DisplacementMap"; } |
| @@ -289,7 +312,9 @@ private: |
| GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
| - SkScalar scale, GrTexture* displacement, GrTexture* color); |
| + const SkVector& scale, |
| + GrTexture* displacement, const SkMatrix& displacementMatrix, |
| + GrTexture* color, const SkMatrix& colorMatrix); |
| GR_DECLARE_EFFECT_TEST; |
| @@ -299,7 +324,7 @@ private: |
| GrTextureAccess fColorAccess; |
| SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; |
| SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; |
| - SkScalar fScale; |
| + SkVector fScale; |
| typedef GrEffect INHERITED; |
| }; |
| @@ -333,29 +358,43 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
| GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); |
| - GrPaint paint; |
| - paint.addColorEffect( |
| - GrDisplacementMapEffect::Create(fXChannelSelector, |
| - fYChannelSelector, |
| - fScale, |
| - displacement, |
| - color))->unref(); |
| + SkVector scale = SkVector::Make(fScale, fScale); |
| + ctm.mapVectors(&scale, 1); |
| SkIRect bounds; |
| src.getBounds(&bounds); |
| + bounds.offset(colorOffset); |
| if (!this->applyCropRect(&bounds, ctm)) { |
| return false; |
| } |
| SkIRect displBounds; |
| displacementBM.getBounds(&displBounds); |
| + displBounds.offset(displacementOffset); |
| if (!this->applyCropRect(&displBounds, ctm)) { |
| return false; |
| } |
| if (!bounds.intersect(displBounds)) { |
| return false; |
| } |
| - SkRect srcRect = SkRect::Make(bounds); |
| - SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| - context->drawRectToRect(paint, dstRect, srcRect); |
| + |
| + GrPaint paint; |
| + SkMatrix colorMatrix = GrEffect::MakeDivByTextureWHMatrix(color); |
| + colorMatrix.preTranslate(-SkIntToScalar(colorOffset.fX), |
| + -SkIntToScalar(colorOffset.fY)); |
| + SkMatrix displacementMatrix = GrEffect::MakeDivByTextureWHMatrix(displacement); |
| + displacementMatrix.preTranslate(-SkIntToScalar(displacementOffset.fX), |
| + -SkIntToScalar(displacementOffset.fY)); |
| + paint.addColorEffect( |
| + GrDisplacementMapEffect::Create(fXChannelSelector, |
| + fYChannelSelector, |
| + scale, |
| + displacement, |
| + displacementMatrix, |
| + color, |
| + colorMatrix))->unref(); |
| + SkMatrix matrix; |
| + matrix.setTranslate(-SkIntToScalar(bounds.left()), -SkIntToScalar(bounds.top())); |
|
sugoi
2014/01/17 21:56:27
Same comment about offsetting the bounds and trans
Stephen White
2014/01/18 01:23:19
Fixed (although I don't think it'll make it any fa
|
| + context->concatMatrix(matrix); |
| + context->drawRect(paint, SkRect::Make(bounds)); |
| offset->fX = bounds.left(); |
| offset->fY = bounds.top(); |
| return SkImageFilterUtils::WrapTexture(dst, bounds.width(), bounds.height(), result); |
| @@ -366,12 +405,14 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
| GrDisplacementMapEffect::GrDisplacementMapEffect( |
| SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
| - SkScalar scale, |
| + const SkVector& scale, |
| GrTexture* displacement, |
| - GrTexture* color) |
| - : fDisplacementTransform(kLocal_GrCoordSet, displacement) |
| + const SkMatrix& displacementMatrix, |
| + GrTexture* color, |
| + const SkMatrix& colorMatrix) |
| + : fDisplacementTransform(kLocal_GrCoordSet, displacementMatrix, displacement) |
| , fDisplacementAccess(displacement) |
| - , fColorTransform(kLocal_GrCoordSet, color) |
| + , fColorTransform(kLocal_GrCoordSet, colorMatrix, color) |
| , fColorAccess(color) |
| , fXChannelSelector(xChannelSelector) |
| , fYChannelSelector(yChannelSelector) |
| @@ -428,10 +469,12 @@ GrEffectRef* GrDisplacementMapEffect::TestCreate(SkRandom* random, |
| SkDisplacementMapEffect::ChannelSelectorType yChannelSelector = |
| static_cast<SkDisplacementMapEffect::ChannelSelectorType>( |
| random->nextRangeU(1, kMaxComponent)); |
| - SkScalar scale = random->nextRangeScalar(0, 100.0f); |
| + SkVector scale = SkVector::Make(random->nextRangeScalar(0, 100.0f), |
| + random->nextRangeScalar(0, 100.0f)); |
| return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale, |
| - textures[texIdxDispl], textures[texIdxColor]); |
| + textures[texIdxDispl], SkMatrix::I(), |
| + textures[texIdxColor], SkMatrix::I()); |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -528,8 +571,8 @@ void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, |
| const GrDisplacementMapEffect& displacementMap = |
| drawEffect.castEffect<GrDisplacementMapEffect>(); |
| GrTexture* colorTex = displacementMap.texture(1); |
| - SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->width())); |
| - SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->height())); |
| + SkScalar scaleX = SkScalarDiv(displacementMap.scale().fX, SkIntToScalar(colorTex->width())); |
| + SkScalar scaleY = SkScalarDiv(displacementMap.scale().fY, SkIntToScalar(colorTex->height())); |
| uman.set2f(fScaleUni, SkScalarToFloat(scaleX), |
| colorTex->origin() == kTopLeft_GrSurfaceOrigin ? |
| SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY)); |