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

Unified Diff: src/effects/SkDisplacementMapEffect.cpp

Issue 137053003: Apply the CTM to filter parameters for 4 pixel-moving filters. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix displacement offsets, GM clipping, colors Created 6 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 side-by-side diff with in-line comments
Download patch
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));

Powered by Google App Engine
This is Rietveld 408576698