Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkDisplacementMapEffect.h"
      9 #include "SkFlattenableBuffers.h"
     10 #include "SkUnPreMultiply.h"
     11 #include "SkColorPriv.h"
     12 #if SK_SUPPORT_GPU
     13 #include "GrContext.h"
     14 #include "gl/GrGLEffect.h"
     15 #include "gl/GrGLEffectMatrix.h"
     16 #include "GrTBackendEffectFactory.h"
     17 #include "SkImageFilterUtils.h"
     18 #endif
     19 
     20 namespace {
     21 
     22 template<SkDisplacementMapEffect::ChannelSelectorType type>
     23 uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) {
     24     SkASSERT(!"Unknown channel selector");
     25     return 0;
     26 }
     27 
     28 template<> uint32_t getValue<SkDisplacementMapEffect::kR_ChannelSelectorType>(
     29     SkColor l, const SkUnPreMultiply::Scale* table) {
     30     return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedR32(l));
     31 }
     32 
     33 template<> uint32_t getValue<SkDisplacementMapEffect::kG_ChannelSelectorType>(
     34     SkColor l, const SkUnPreMultiply::Scale* table) {
     35     return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedG32(l));
     36 }
     37 
     38 template<> uint32_t getValue<SkDisplacementMapEffect::kB_ChannelSelectorType>(
     39     SkColor l, const SkUnPreMultiply::Scale* table) {
     40     return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedB32(l));
     41 }
     42 
     43 template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>(
     44     SkColor l, const SkUnPreMultiply::Scale*) {
     45     return SkGetPackedA32(l);
     46 }
     47 
     48 template<SkDisplacementMapEffect::ChannelSelectorType typeX,
     49          SkDisplacementMapEffect::ChannelSelectorType typeY>
     50 void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src)
     51 {
     52     static const SkScalar Inv8bit = SkScalarDiv(SK_Scalar1, SkFloatToScalar(255.0f));
     53     const int dstW = displ->width();
     54     const int dstH = displ->height();
     55     const int srcW = src->width();
     56     const int srcH = src->height();
     57     const SkScalar scaleForColor = SkScalarMul(scale, Inv8bit);
     58     const SkScalar scaleAdj = SK_ScalarHalf - SkScalarMul(scale, SK_ScalarHalf);
     59     const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
     60     for (int y = 0; y < dstH; ++y) {
     61         const SkPMColor* displPtr = displ->getAddr32(0, y);
     62         SkPMColor* dstPtr = dst->getAddr32(0, y);
     63         for (int x = 0; x < dstW; ++x, ++displPtr, ++dstPtr) {
     64             const SkScalar displX = SkScalarMul(scaleForColor,
     65                 SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj;
     66             const SkScalar displY = SkScalarMul(scaleForColor,
     67                 SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj;
     68             // Truncate the displacement values
     69             const int srcX = x + SkScalarTruncToInt(displX);
     70             const int srcY = y + SkScalarTruncToInt(displY);
     71             *dstPtr = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ?
     72                       0 : *(src->getAddr32(srcX, srcY));
     73         }
     74     }
     75 }
     76 
     77 template<SkDisplacementMapEffect::ChannelSelectorType typeX>
     78 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
     79                          SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src)
     80 {
     81     switch (yChannelSelector) {
     82       case SkDisplacementMapEffect::kR_ChannelSelectorType:
     83         computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorType>(
     84             scale, dst, displ, src);
     85         break;
     86       case SkDisplacementMapEffect::kG_ChannelSelectorType:
     87         computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorType>(
     88             scale, dst, displ, src);
     89         break;
     90       case SkDisplacementMapEffect::kB_ChannelSelectorType:
     91         computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorType>(
     92             scale, dst, displ, src);
     93         break;
     94       case SkDisplacementMapEffect::kA_ChannelSelectorType:
     95         computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorType>(
     96             scale, dst, displ, src);
     97         break;
     98       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
     99       default:
    100         SkASSERT(!"Unknown Y channel selector");
    101     }
    102 }
    103 
    104 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
    105                          SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
    106                          SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src)
    107 {
    108     switch (xChannelSelector) {
    109       case SkDisplacementMapEffect::kR_ChannelSelectorType:
    110         computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>(
    111             yChannelSelector, scale, dst, displ, src);
    112         break;
    113       case SkDisplacementMapEffect::kG_ChannelSelectorType:
    114         computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>(
    115             yChannelSelector, scale, dst, displ, src);
    116         break;
    117       case SkDisplacementMapEffect::kB_ChannelSelectorType:
    118         computeDisplacement<SkDisplacementMapEffect::kB_ChannelSelectorType>(
    119             yChannelSelector, scale, dst, displ, src);
    120         break;
    121       case SkDisplacementMapEffect::kA_ChannelSelectorType:
    122         computeDisplacement<SkDisplacementMapEffect::kA_ChannelSelectorType>(
    123             yChannelSelector, scale, dst, displ, src);
    124         break;
    125       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
    126       default:
    127         SkASSERT(!"Unknown X channel selector");
    128     }
    129 }
    130 
    131 } // end namespace
    132 
    133 ///////////////////////////////////////////////////////////////////////////////
    134 
    135 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
    136                                                  ChannelSelectorType yChannelSelector,
    137                                                  SkScalar scale,
    138                                                  SkImageFilter* displacement,
    139                                                  SkImageFilter* color)
    140   : INHERITED(displacement, color)
    141   , fXChannelSelector(xChannelSelector)
    142   , fYChannelSelector(yChannelSelector)
    143   , fScale(scale)
    144 {
    145 }
    146 
    147 SkDisplacementMapEffect::~SkDisplacementMapEffect() {
    148 }
    149 
    150 SkDisplacementMapEffect::SkDisplacementMapEffect(SkFlattenableReadBuffer& buffer)
    151   : INHERITED(buffer)
    152 {
    153     fXChannelSelector = (SkDisplacementMapEffect::ChannelSelectorType) buffer.readInt();
    154     fYChannelSelector = (SkDisplacementMapEffect::ChannelSelectorType) buffer.readInt();
    155     fScale            = buffer.readScalar();
    156 }
    157 
    158 void SkDisplacementMapEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
    159     this->INHERITED::flatten(buffer);
    160     buffer.writeInt((int) fXChannelSelector);
    161     buffer.writeInt((int) fYChannelSelector);
    162     buffer.writeScalar(fScale);
    163 }
    164 
    165 bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy,
    166                                             const SkBitmap& src,
    167                                             const SkMatrix& ctm,
    168                                             SkBitmap* dst,
    169                                             SkIPoint* offset) {
    170     SkBitmap displ, color = src;
    171     SkImageFilter* colorInput = getColorInput();
    172     SkImageFilter* displacementInput = getDisplacementInput();
    173     SkASSERT(NULL != displacementInput);
    174     if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, offset)) ||
    175         !displacementInput->filterImage(proxy, src, ctm, &displ, offset)) {
    176         return false;
    177     }
    178     if ((displ.config() != SkBitmap::kARGB_8888_Config) ||
    179         (color.config() != SkBitmap::kARGB_8888_Config)) {
    180         return false;
    181     }
    182 
    183     SkAutoLockPixels alp_displacement(displ), alp_color(color);
    184     if (!displ.getPixels() || !color.getPixels()) {
    185         return false;
    186     }
    187     dst->setConfig(displ.config(), displ.width(), displ.height());
    188     dst->allocPixels();
    189     if (!dst->getPixels()) {
    190         return false;
    191     }
    192 
    193     computeDisplacement(fXChannelSelector, fYChannelSelector, fScale, dst, &displ, &color);
    194 
    195     return true;
    196 }
    197 
    198 ///////////////////////////////////////////////////////////////////////////////
    199 
    200 #if SK_SUPPORT_GPU
    201 class GrGLDisplacementMapEffect : public GrGLEffect {
    202 public:
    203     GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
    204                               const GrDrawEffect& drawEffect);
    205     virtual ~GrGLDisplacementMapEffect();
    206 
    207     virtual void emitCode(GrGLShaderBuilder*,
    208                           const GrDrawEffect&,
    209                           EffectKey,
    210                           const char* outputColor,
    211                           const char* inputColor,
    212                           const TextureSamplerArray&) SK_OVERRIDE;
    213 
    214     static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
    215 
    216     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
    217 
    218 private:
    219     static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
    220 
    221     SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
    222     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
    223     GrGLEffectMatrix fDisplacementEffectMatrix;
    224     GrGLEffectMatrix fColorEffectMatrix;
    225     GrGLUniformManager::UniformHandle fScaleUni;
    226 
    227     typedef GrGLEffect INHERITED;
    228 };
    229 
    230 ///////////////////////////////////////////////////////////////////////////////
    231 
    232 class GrDisplacementMapEffect : public GrEffect {
    233 public:
    234     static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
    235                                SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
    236                                SkScalar scale, GrTexture* displacement, GrTexture* color) {
    237         AutoEffectUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector,
    238                                                                     yChannelSelector,
    239                                                                     scale,
    240                                                                     displacement,
    241                                                                     color)));
    242         return CreateEffectRef(effect);
    243     }
    244 
    245     virtual ~GrDisplacementMapEffect();
    246 
    247     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
    248     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
    249         { return fXChannelSelector; }
    250     SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
    251         { return fYChannelSelector; }
    252     SkScalar scale() const { return fScale; }
    253 
    254     typedef GrGLDisplacementMapEffect GLEffect;
    255     static const char* Name() { return "DisplacementMap"; }
    256 
    257     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
    258 
    259 private:
    260 
    261     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
    262 
    263     GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
    264                             SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
    265                             SkScalar scale, GrTexture* displacement, GrTexture* color);
    266 
    267     GR_DECLARE_EFFECT_TEST;
    268 
    269     GrTextureAccess             fDisplacementAccess;
    270     GrTextureAccess             fColorAccess;
    271     SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
    272     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
    273     SkScalar fScale;
    274 
    275     typedef GrEffect INHERITED;
    276 };
    277 
    278 bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
    279                                              SkBitmap* result, SkIPoint* offset) {
    280     SkBitmap colorBM;
    281     SkIPoint colorOffset = SkIPoint::Make(0, 0);
    282     if (!SkImageFilterUtils::GetInputResultGPU(getColorInput(), proxy, src, ctm, &colorBM,
    283                                                &colorOffset)) {
    284         return false;
    285     }
    286     GrTexture* color = colorBM.getTexture();
    287     SkBitmap displacementBM;
    288     SkIPoint displacementOffset = SkIPoint::Make(0, 0);
    289     if (!SkImageFilterUtils::GetInputResultGPU(getDisplacementInput(), proxy, src, ctm,
    290                                                &displacementBM, &displacementOffset)) {
    291         return false;
    292     }
    293     GrTexture* displacement = displacementBM.getTexture();
    294     GrContext* context = color->getContext();
    295 
    296     GrTextureDesc desc;
    297     desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
    298     desc.fWidth = src.width();
    299     desc.fHeight = src.height();
    300     desc.fConfig = kSkia8888_GrPixelConfig;
    301 
    302     GrAutoScratchTexture ast(context, desc);
    303     SkAutoTUnref<GrTexture> dst(ast.detach());
    304 
    305     GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
    306 
    307     GrPaint paint;
    308     paint.addColorEffect(
    309         GrDisplacementMapEffect::Create(fXChannelSelector,
    310                                         fYChannelSelector,
    311                                         fScale,
    312                                         displacement,
    313                                         color))->unref();
    314     SkRect srcRect;
    315     src.getBounds(&srcRect);
    316     SkRect dstRect = srcRect;
    317     dstRect.offset(SkIntToScalar(colorOffset.fX), SkIntToScalar(colorOffset.fY));
    318     context->drawRectToRect(paint, srcRect, dstRect);
    319     return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result);
    320 }
    321 
    322 ///////////////////////////////////////////////////////////////////////////////
    323 
    324 GrDisplacementMapEffect::GrDisplacementMapEffect(
    325                              SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
    326                              SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
    327                              SkScalar scale,
    328                              GrTexture* displacement,
    329                              GrTexture* color)
    330     : fDisplacementAccess(displacement)
    331     , fColorAccess(color)
    332     , fXChannelSelector(xChannelSelector)
    333     , fYChannelSelector(yChannelSelector)
    334     , fScale(scale) {
    335     this->addTextureAccess(&fDisplacementAccess);
    336     this->addTextureAccess(&fColorAccess);
    337 }
    338 
    339 GrDisplacementMapEffect::~GrDisplacementMapEffect() {
    340 }
    341 
    342 bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const {
    343     const GrDisplacementMapEffect& s = CastEffect<GrDisplacementMapEffect>(sBase);
    344     return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture() &&
    345            fColorAccess.getTexture() == s.fColorAccess.getTexture() &&
    346            fXChannelSelector == s.fXChannelSelector &&
    347            fYChannelSelector == s.fYChannelSelector &&
    348            fScale == s.fScale;
    349 }
    350 
    351 const GrBackendEffectFactory& GrDisplacementMapEffect::getFactory() const {
    352     return GrTBackendEffectFactory<GrDisplacementMapEffect>::getInstance();
    353 }
    354 
    355 void GrDisplacementMapEffect::getConstantColorComponents(GrColor*,
    356                                                          uint32_t* validFlags) const {
    357     // Any displacement offset bringing a pixel out of bounds will output a color of (0,0,0,0),
    358     // so the only way we'd get a constant alpha is if the input color image has a constant alpha
    359     // and no displacement offset push any texture coordinates out of bounds OR if the constant
    360     // alpha is 0. Since this isn't trivial to compute at this point, let's assume the output is
    361     // not of constant color when a displacement effect is applied.
    362     *validFlags = 0;
    363 }
    364 
    365 ///////////////////////////////////////////////////////////////////////////////
    366 
    367 GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect);
    368 
    369 GrEffectRef* GrDisplacementMapEffect::TestCreate(SkMWCRandom* random,
    370                                                  GrContext*,
    371                                                  const GrDrawTargetCaps&,
    372                                                  GrTexture* textures[]) {
    373     int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
    374                                            GrEffectUnitTest::kAlphaTextureIdx;
    375     int texIdxColor = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
    376                                            GrEffectUnitTest::kAlphaTextureIdx;
    377     static const int kMaxComponent = 4;
    378     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector =
    379         static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
    380         random->nextRangeU(1, kMaxComponent));
    381     SkDisplacementMapEffect::ChannelSelectorType yChannelSelector =
    382         static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
    383         random->nextRangeU(1, kMaxComponent));
    384     SkScalar scale = random->nextRangeScalar(0, SkFloatToScalar(100.0f));
    385 
    386     return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale,
    387                                            textures[texIdxDispl], textures[texIdxColor]);
    388 }
    389 
    390 ///////////////////////////////////////////////////////////////////////////////
    391 
    392 GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
    393                                                      const GrDrawEffect& drawEffect)
    394     : INHERITED(factory)
    395     , fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChannelSelector())
    396     , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChannelSelector())
    397     , fDisplacementEffectMatrix(kCoordsType)
    398     , fColorEffectMatrix(kCoordsType) {
    399 }
    400 
    401 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
    402 }
    403 
    404 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
    405                                          const GrDrawEffect&,
    406                                          EffectKey key,
    407                                          const char* outputColor,
    408                                          const char* inputColor,
    409                                          const TextureSamplerArray& samplers) {
    410     sk_ignore_unused_variable(inputColor);
    411 
    412     fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
    413                                     kVec2f_GrSLType, "Scale");
    414     const char* scaleUni = builder->getUniformCStr(fScaleUni);
    415 
    416     const char* dCoordsIn;
    417     GrSLType dCoordsType = fDisplacementEffectMatrix.emitCode(
    418                                 builder, key, &dCoordsIn, NULL, "DISPL");
    419     const char* cCoordsIn;
    420     GrSLType cCoordsType = fColorEffectMatrix.emitCode(
    421                                 builder, key, &cCoordsIn, NULL, "COLOR");
    422 
    423     const char* dColor = "dColor";
    424     const char* cCoords = "cCoords";
    425     const char* outOfBounds = "outOfBounds";
    426     const char* nearZero = "1e-6"; // Since 6.10352e5 is the smallest half float, use
    427                                    // a number smaller than that to approximate 0, but
    428                                    // leave room for 32-bit float GPU rounding errors.
    429 
    430     builder->fsCodeAppendf("\t\tvec4 %s = ", dColor);
    431     builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
    432                                  samplers[0],
    433                                  dCoordsIn,
    434                                  dCoordsType);
    435     builder->fsCodeAppend(";\n");
    436 
    437     // Unpremultiply the displacement
    438     builder->fsCodeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
    439                            dColor, dColor, nearZero, dColor, dColor);
    440 
    441     builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.",
    442                            cCoords, cCoordsIn, scaleUni, dColor);
    443 
    444     switch (fXChannelSelector) {
    445       case SkDisplacementMapEffect::kR_ChannelSelectorType:
    446         builder->fsCodeAppend("r");
    447         break;
    448       case SkDisplacementMapEffect::kG_ChannelSelectorType:
    449         builder->fsCodeAppend("g");
    450         break;
    451       case SkDisplacementMapEffect::kB_ChannelSelectorType:
    452         builder->fsCodeAppend("b");
    453         break;
    454       case SkDisplacementMapEffect::kA_ChannelSelectorType:
    455         builder->fsCodeAppend("a");
    456         break;
    457       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
    458       default:
    459         SkASSERT(!"Unknown X channel selector");
    460     }
    461 
    462     switch (fYChannelSelector) {
    463       case SkDisplacementMapEffect::kR_ChannelSelectorType:
    464         builder->fsCodeAppend("r");
    465         break;
    466       case SkDisplacementMapEffect::kG_ChannelSelectorType:
    467         builder->fsCodeAppend("g");
    468         break;
    469       case SkDisplacementMapEffect::kB_ChannelSelectorType:
    470         builder->fsCodeAppend("b");
    471         break;
    472       case SkDisplacementMapEffect::kA_ChannelSelectorType:
    473         builder->fsCodeAppend("a");
    474         break;
    475       case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
    476       default:
    477         SkASSERT(!"Unknown Y channel selector");
    478     }
    479     builder->fsCodeAppend("-vec2(0.5));\t\t");
    480 
    481     // FIXME : This can be achieved with a "clamp to border" texture repeat mode and
    482     //         a 0 border color instead of computing if cCoords is out of bounds here.
    483     builder->fsCodeAppendf(
    484         "bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);\t\t",
    485         outOfBounds, cCoords, cCoords, cCoords, cCoords);
    486     builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
    487     builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
    488                                  samplers[1],
    489                                  cCoords,
    490                                  cCoordsType);
    491     builder->fsCodeAppend(";\n");
    492 }
    493 
    494 void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman,
    495                                         const GrDrawEffect& drawEffect) {
    496     const GrDisplacementMapEffect& displacementMap =
    497         drawEffect.castEffect<GrDisplacementMapEffect>();
    498     GrTexture* displTex = displacementMap.texture(0);
    499     GrTexture* colorTex = displacementMap.texture(1);
    500     fDisplacementEffectMatrix.setData(uman,
    501                                      GrEffect::MakeDivByTextureWHMatrix(displTex),
    502                                      drawEffect,
    503                                      displTex);
    504     fColorEffectMatrix.setData(uman,
    505                                GrEffect::MakeDivByTextureWHMatrix(colorTex),
    506                                drawEffect,
    507                                colorTex);
    508 
    509     SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->width()));
    510     SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->height()));
    511     uman.set2f(fScaleUni, SkScalarToFloat(scaleX),
    512                colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
    513                SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
    514 }
    515 
    516 GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& drawEffect,
    517                                                         const GrGLCaps&) {
    518     const GrDisplacementMapEffect& displacementMap =
    519         drawEffect.castEffect<GrDisplacementMapEffect>();
    520 
    521     GrTexture* displTex = displacementMap.texture(0);
    522     GrTexture* colorTex = displacementMap.texture(1);
    523 
    524     EffectKey displKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(displTex),
    525                                                   drawEffect,
    526                                                   kCoordsType,
    527                                                   displTex);
    528 
    529     EffectKey colorKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(colorTex),
    530                                                   drawEffect,
    531                                                   kCoordsType,
    532                                                   colorTex);
    533 
    534     colorKey <<= GrGLEffectMatrix::kKeyBits;
    535     EffectKey xKey = displacementMap.xChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits);
    536     EffectKey yKey = displacementMap.yChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits +
    537                                                             SkDisplacementMapEffect::kKeyBits);
    538 
    539     return xKey | yKey | displKey | colorKey;
    540 }
    541 #endif
    542