Index: src/effects/SkDisplacementMapEffect.cpp |
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp |
index e9a9acb4ce2fae14048d89b3aa19266c0596013f..8264ec8e0675113362858b7c68c419b3febe8fcd 100644 |
--- a/src/effects/SkDisplacementMapEffect.cpp |
+++ b/src/effects/SkDisplacementMapEffect.cpp |
@@ -47,22 +47,28 @@ 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& offset, |
+ SkBitmap* src, |
+ 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() + offset.fX, |
+ y + offset.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); |
@@ -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& offset, |
+ SkBitmap* src, |
+ const SkIRect& bounds) |
{ |
switch (yChannelSelector) { |
case SkDisplacementMapEffect::kR_ChannelSelectorType: |
computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorType>( |
- scale, dst, displ, src, bounds); |
+ scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kG_ChannelSelectorType: |
computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorType>( |
- scale, dst, displ, src, bounds); |
+ scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kB_ChannelSelectorType: |
computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorType>( |
- scale, dst, displ, src, bounds); |
+ scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kA_ChannelSelectorType: |
computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorType>( |
- scale, dst, displ, src, bounds); |
+ scale, dst, displ, offset, src, 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& offset, |
+ SkBitmap* src, |
+ const SkIRect& bounds) |
{ |
switch (xChannelSelector) { |
case SkDisplacementMapEffect::kR_ChannelSelectorType: |
computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>( |
- yChannelSelector, scale, dst, displ, src, bounds); |
+ yChannelSelector, scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kG_ChannelSelectorType: |
computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>( |
- yChannelSelector, scale, dst, displ, src, bounds); |
+ yChannelSelector, scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kB_ChannelSelectorType: |
computeDisplacement<SkDisplacementMapEffect::kB_ChannelSelectorType>( |
- yChannelSelector, scale, dst, displ, src, bounds); |
+ yChannelSelector, scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kA_ChannelSelectorType: |
computeDisplacement<SkDisplacementMapEffect::kA_ChannelSelectorType>( |
- yChannelSelector, scale, dst, displ, src, bounds); |
+ yChannelSelector, scale, dst, displ, offset, src, bounds); |
break; |
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: |
default: |
@@ -185,9 +197,10 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
SkIPoint* offset) { |
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))) { |
+ SkImageFilter* displInput = getDisplacementInput(); |
+ SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); |
+ if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, &colorOffset)) || |
+ (displInput && !displInput->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); |
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,13 @@ 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); |
+ SkIRect colorBounds = bounds; |
+ colorBounds.offset(-colorOffset); |
+ |
+ computeDisplacement(fXChannelSelector, fYChannelSelector, scale, dst, |
+ &displ, colorOffset - displOffset, &color, colorBounds); |
offset->fX = bounds.left(); |
offset->fY = bounds.top(); |
@@ -261,11 +282,14 @@ 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& offsetMatrix, |
+ GrTexture* color) { |
AutoEffectUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector, |
yChannelSelector, |
scale, |
displacement, |
+ offsetMatrix, |
color))); |
return CreateEffectRef(effect); |
} |
@@ -277,7 +301,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 +313,9 @@ private: |
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
- SkScalar scale, GrTexture* displacement, GrTexture* color); |
+ const SkVector& scale, |
+ GrTexture* displacement, const SkMatrix& offsetMatrix, |
+ GrTexture* color); |
GR_DECLARE_EFFECT_TEST; |
@@ -299,7 +325,7 @@ private: |
GrTextureAccess fColorAccess; |
SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; |
SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; |
- SkScalar fScale; |
+ SkVector fScale; |
typedef GrEffect INHERITED; |
}; |
@@ -324,8 +350,8 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
GrTextureDesc desc; |
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
- desc.fWidth = src.width(); |
- desc.fHeight = src.height(); |
+ desc.fWidth = colorBM.width(); |
+ desc.fHeight = colorBM.height(); |
desc.fConfig = kSkia8888_GrPixelConfig; |
GrAutoScratchTexture ast(context, desc); |
@@ -333,29 +359,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); |
+ colorBM.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 offsetMatrix = GrEffect::MakeDivByTextureWHMatrix(displacement); |
+ offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.fX), |
+ SkIntToScalar(colorOffset.fY - displacementOffset.fY)); |
+ |
+ paint.addColorEffect( |
+ GrDisplacementMapEffect::Create(fXChannelSelector, |
+ fYChannelSelector, |
+ scale, |
+ displacement, |
+ offsetMatrix, |
+ color))->unref(); |
+ SkIRect colorBounds = bounds; |
+ colorBounds.offset(-colorOffset); |
+ SkMatrix matrix; |
+ matrix.setTranslate(-SkIntToScalar(colorBounds.x()), |
+ -SkIntToScalar(colorBounds.y())); |
+ context->concatMatrix(matrix); |
+ context->drawRect(paint, SkRect::Make(colorBounds)); |
offset->fX = bounds.left(); |
offset->fY = bounds.top(); |
return SkImageFilterUtils::WrapTexture(dst, bounds.width(), bounds.height(), result); |
@@ -366,10 +406,11 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
GrDisplacementMapEffect::GrDisplacementMapEffect( |
SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, |
- SkScalar scale, |
+ const SkVector& scale, |
GrTexture* displacement, |
+ const SkMatrix& offsetMatrix, |
GrTexture* color) |
- : fDisplacementTransform(kLocal_GrCoordSet, displacement) |
+ : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement) |
, fDisplacementAccess(displacement) |
, fColorTransform(kLocal_GrCoordSet, color) |
, fColorAccess(color) |
@@ -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]); |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -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)); |