Fix for displacement mapping
Fixed the skia displacement map effect to match the WebKit displacement map fix.
Review URL: https://codereview.chromium.org/12787007
git-svn-id: http://skia.googlecode.com/svn/trunk@8225 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index b270501..9c89a6a 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -50,26 +50,26 @@
void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src)
{
static const SkScalar Inv8bit = SkScalarDiv(SK_Scalar1, SkFloatToScalar(255.0f));
- static const SkScalar Half8bit = SkFloatToScalar(255.0f * 0.5f);
const int dstW = displ->width();
const int dstH = displ->height();
const int srcW = src->width();
const int srcH = src->height();
- const SkScalar scaleX = SkScalarMul(SkScalarMul(scale, SkIntToScalar(dstW)), Inv8bit);
- const SkScalar scaleY = SkScalarMul(SkScalarMul(scale, SkIntToScalar(dstH)), Inv8bit);
+ 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) {
- const SkScalar displX =
- SkScalarMul(scaleX, SkIntToScalar(getValue<typeX>(*displPtr, table))-Half8bit);
- const SkScalar displY =
- SkScalarMul(scaleY, SkIntToScalar(getValue<typeY>(*displPtr, table))-Half8bit);
- const int coordX = x + SkScalarRoundToInt(displX);
- const int coordY = y + SkScalarRoundToInt(displY);
- *dstPtr = ((coordX < 0) || (coordX >= srcW) || (coordY < 0) || (coordY >= srcH)) ?
- 0 : *(src->getAddr32(coordX, coordY));
+ const SkScalar displX = SkScalarMul(scaleForColor,
+ SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj;
+ const SkScalar displY = SkScalarMul(scaleForColor,
+ SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj;
+ // 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)) ?
+ 0 : *(src->getAddr32(srcX, srcY));
}
}
}
@@ -345,7 +345,7 @@
return GrTBackendEffectFactory<GrDisplacementMapEffect>::getInstance();
}
-void GrDisplacementMapEffect::getConstantColorComponents(GrColor* color,
+void GrDisplacementMapEffect::getConstantColorComponents(GrColor*,
uint32_t* validFlags) const {
// Any displacement offset bringing a pixel out of bounds will output a color of (0,0,0,0),
// so the only way we'd get a constant alpha is if the input color image has a constant alpha
@@ -360,7 +360,7 @@
GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect);
GrEffectRef* GrDisplacementMapEffect::TestCreate(SkMWCRandom* random,
- GrContext* context,
+ GrContext*,
GrTexture* textures[]) {
int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
GrEffectUnitTest::kAlphaTextureIdx;
@@ -373,7 +373,7 @@
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector =
static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
random->nextRangeU(1, kMaxComponent));
- SkScalar scale = random->nextUScalar1();
+ SkScalar scale = random->nextRangeScalar(0, SkFloatToScalar(100.0f));
return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale,
textures[texIdxDispl], textures[texIdxColor]);
@@ -491,10 +491,11 @@
stage.getCoordChangeMatrix(),
colorTex);
- uman.set2f(fScaleUni, SkScalarToFloat(displacementMap.scale()),
- colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
- SkScalarToFloat(displacementMap.scale()) :
- SkScalarToFloat(-displacementMap.scale()));
+ SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->width()));
+ SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->height()));
+ uman.set2f(fScaleUni, SkScalarToFloat(scaleX),
+ colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
+ SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
}
GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrEffectStage& stage,