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>
getValue(SkColor,const SkUnPreMultiply::Scale *)23 uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) {
24 SkASSERT(!"Unknown channel selector");
25 return 0;
26 }
27
getValue(SkColor l,const SkUnPreMultiply::Scale * table)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
getValue(SkColor l,const SkUnPreMultiply::Scale * table)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
getValue(SkColor l,const SkUnPreMultiply::Scale * table)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
getValue(SkColor l,const SkUnPreMultiply::Scale *)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>
computeDisplacement(SkScalar scale,SkBitmap * dst,SkBitmap * displ,SkBitmap * src)50 void computeDisplacement(SkScalar scale, SkBitmap* dst, SkBitmap* displ, SkBitmap* src)
51 {
52 static const SkScalar Inv8bit = SkScalarDiv(SK_Scalar1, SkFloatToScalar(255.0f));
53 static const SkScalar Half8bit = SkFloatToScalar(255.0f * 0.5f);
54 const int dstW = displ->width();
55 const int dstH = displ->height();
56 const int srcW = src->width();
57 const int srcH = src->height();
58 const SkScalar scaleX = SkScalarMul(SkScalarMul(scale, SkIntToScalar(dstW)), Inv8bit);
59 const SkScalar scaleY = SkScalarMul(SkScalarMul(scale, SkIntToScalar(dstH)), Inv8bit);
60 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
61 for (int y = 0; y < dstH; ++y) {
62 const SkPMColor* displPtr = displ->getAddr32(0, y);
63 SkPMColor* dstPtr = dst->getAddr32(0, y);
64 for (int x = 0; x < dstW; ++x, ++displPtr, ++dstPtr) {
65 const SkScalar displX =
66 SkScalarMul(scaleX, SkIntToScalar(getValue<typeX>(*displPtr, table))-Half8bit);
67 const SkScalar displY =
68 SkScalarMul(scaleY, SkIntToScalar(getValue<typeY>(*displPtr, table))-Half8bit);
69 const int coordX = x + SkScalarRoundToInt(displX);
70 const int coordY = y + SkScalarRoundToInt(displY);
71 *dstPtr = ((coordX < 0) || (coordX >= srcW) || (coordY < 0) || (coordY >= srcH)) ?
72 0 : *(src->getAddr32(coordX, coordY));
73 }
74 }
75 }
76
77 template<SkDisplacementMapEffect::ChannelSelectorType typeX>
computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,SkScalar scale,SkBitmap * dst,SkBitmap * displ,SkBitmap * src)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
computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,SkScalar scale,SkBitmap * dst,SkBitmap * displ,SkBitmap * src)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
SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,ChannelSelectorType yChannelSelector,SkScalar scale,SkImageFilter * displacement,SkImageFilter * color)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
~SkDisplacementMapEffect()147 SkDisplacementMapEffect::~SkDisplacementMapEffect() {
148 }
149
SkDisplacementMapEffect(SkFlattenableReadBuffer & buffer)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
flatten(SkFlattenableWriteBuffer & buffer) const158 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
onFilterImage(Proxy * proxy,const SkBitmap & src,const SkMatrix & ctm,SkBitmap * dst,SkIPoint * offset)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 GrEffectRef& effect);
205 virtual ~GrGLDisplacementMapEffect();
206
207 virtual void emitCode(GrGLShaderBuilder*,
208 const GrEffectStage&,
209 EffectKey,
210 const char* vertexCoords,
211 const char* outputColor,
212 const char* inputColor,
213 const TextureSamplerArray&) SK_OVERRIDE;
214
215 static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
216
217 virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
218
219 private:
220 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
221 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
222 GrGLEffectMatrix fDisplacementEffectMatrix;
223 GrGLEffectMatrix fColorEffectMatrix;
224 GrGLUniformManager::UniformHandle fScaleUni;
225 GrGLUniformManager::UniformHandle fYSignColor;
226 GrGLUniformManager::UniformHandle fYSignDispl;
227
228 typedef GrGLEffect INHERITED;
229 };
230
231 ///////////////////////////////////////////////////////////////////////////////
232
233 class GrDisplacementMapEffect : public GrEffect {
234 public:
Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,SkScalar scale,GrTexture * displacement,GrTexture * color)235 static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
236 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
237 SkScalar scale, GrTexture* displacement, GrTexture* color) {
238 AutoEffectUnref effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector,
239 yChannelSelector,
240 scale,
241 displacement,
242 color)));
243 return CreateEffectRef(effect);
244 }
245
246 virtual ~GrDisplacementMapEffect();
247
248 const GrBackendEffectFactory& getFactory() const;
xChannelSelector() const249 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
250 { return fXChannelSelector; }
yChannelSelector() const251 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
252 { return fYChannelSelector; }
scale() const253 SkScalar scale() const { return fScale; }
254
255 typedef GrGLDisplacementMapEffect GLEffect;
Name()256 static const char* Name() { return "DisplacementMap"; }
257
258 void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
259
260 private:
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
filterImageGPU(Proxy * proxy,const SkBitmap & src,SkBitmap * result)278 bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitmap* result) {
279 SkBitmap colorBM;
280 if (!SkImageFilterUtils::GetInputResultGPU(getColorInput(), proxy, src, &colorBM)) {
281 return false;
282 }
283 GrTexture* color = (GrTexture*) colorBM.getTexture();
284 SkBitmap displacementBM;
285 if (!SkImageFilterUtils::GetInputResultGPU(getDisplacementInput(), proxy, src, &displacementBM)) {
286 return false;
287 }
288 GrTexture* displacement = (GrTexture*) displacementBM.getTexture();
289 GrContext* context = color->getContext();
290
291 GrTextureDesc desc;
292 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
293 desc.fWidth = src.width();
294 desc.fHeight = src.height();
295 desc.fConfig = kSkia8888_GrPixelConfig;
296
297 GrAutoScratchTexture ast(context, desc);
298 SkAutoTUnref<GrTexture> dst(ast.detach());
299
300 GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
301
302 GrPaint paint;
303 paint.colorStage(0)->setEffect(
304 GrDisplacementMapEffect::Create(fXChannelSelector,
305 fYChannelSelector,
306 fScale,
307 displacement,
308 color))->unref();
309 SkRect srcRect;
310 src.getBounds(&srcRect);
311 context->drawRect(paint, srcRect);
312 return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result);
313 }
314
315 ///////////////////////////////////////////////////////////////////////////////
316
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,SkScalar scale,GrTexture * displacement,GrTexture * color)317 GrDisplacementMapEffect::GrDisplacementMapEffect(
318 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
319 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
320 SkScalar scale,
321 GrTexture* displacement,
322 GrTexture* color)
323 : fDisplacementAccess(displacement)
324 , fColorAccess(color)
325 , fXChannelSelector(xChannelSelector)
326 , fYChannelSelector(yChannelSelector)
327 , fScale(scale) {
328 this->addTextureAccess(&fDisplacementAccess);
329 this->addTextureAccess(&fColorAccess);
330 }
331
~GrDisplacementMapEffect()332 GrDisplacementMapEffect::~GrDisplacementMapEffect() {
333 }
334
onIsEqual(const GrEffect & sBase) const335 bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const {
336 const GrDisplacementMapEffect& s = CastEffect<GrDisplacementMapEffect>(sBase);
337 return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture() &&
338 fColorAccess.getTexture() == s.fColorAccess.getTexture() &&
339 fXChannelSelector == s.fXChannelSelector &&
340 fYChannelSelector == s.fYChannelSelector &&
341 fScale == s.fScale;
342 }
343
getFactory() const344 const GrBackendEffectFactory& GrDisplacementMapEffect::getFactory() const {
345 return GrTBackendEffectFactory<GrDisplacementMapEffect>::getInstance();
346 }
347
getConstantColorComponents(GrColor * color,uint32_t * validFlags) const348 void GrDisplacementMapEffect::getConstantColorComponents(GrColor* color,
349 uint32_t* validFlags) const {
350 // Any displacement offset bringing a pixel out of bounds will output a color of (0,0,0,0),
351 // so the only way we'd get a constant alpha is if the input color image has a constant alpha
352 // and no displacement offset push any texture coordinates out of bounds OR if the constant
353 // alpha is 0. Since this isn't trivial to compute at this point, let's assume the output is
354 // not of constant color when a displacement effect is applied.
355 *validFlags = 0;
356 }
357
358 ///////////////////////////////////////////////////////////////////////////////
359
360 GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect);
361
TestCreate(SkRandom * random,GrContext * context,GrTexture * textures[])362 GrEffectRef* GrDisplacementMapEffect::TestCreate(SkRandom* random,
363 GrContext* context,
364 GrTexture* textures[]) {
365 int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
366 GrEffectUnitTest::kAlphaTextureIdx;
367 int texIdxColor = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
368 GrEffectUnitTest::kAlphaTextureIdx;
369 static const int kMaxComponent = 4;
370 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector =
371 static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
372 random->nextRangeU(1, kMaxComponent));
373 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector =
374 static_cast<SkDisplacementMapEffect::ChannelSelectorType>(
375 random->nextRangeU(1, kMaxComponent));
376 SkScalar scale = random->nextUScalar1();
377
378 return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale,
379 textures[texIdxDispl], textures[texIdxColor]);
380 }
381
382 ///////////////////////////////////////////////////////////////////////////////
383
GrGLDisplacementMapEffect(const GrBackendEffectFactory & factory,const GrEffectRef & effect)384 GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory,
385 const GrEffectRef& effect)
386 : INHERITED(factory)
387 , fXChannelSelector(CastEffect<GrDisplacementMapEffect>(effect).xChannelSelector())
388 , fYChannelSelector(CastEffect<GrDisplacementMapEffect>(effect).yChannelSelector()) {
389 }
390
~GrGLDisplacementMapEffect()391 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
392 }
393
emitCode(GrGLShaderBuilder * builder,const GrEffectStage &,EffectKey key,const char * vertexCoords,const char * outputColor,const char * inputColor,const TextureSamplerArray & samplers)394 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
395 const GrEffectStage&,
396 EffectKey key,
397 const char* vertexCoords,
398 const char* outputColor,
399 const char* inputColor,
400 const TextureSamplerArray& samplers) {
401 fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
402 kVec2f_GrSLType, "Scale");
403 const char* scaleUni = builder->getUniformCStr(fScaleUni);
404
405 const char* dCoordsIn;
406 GrSLType dCoordsType = fDisplacementEffectMatrix.emitCode(
407 builder, key, vertexCoords, &dCoordsIn, NULL, "DISPL");
408 const char* cCoordsIn;
409 GrSLType cCoordsType = fColorEffectMatrix.emitCode(
410 builder, key, vertexCoords, &cCoordsIn, NULL, "COLOR");
411
412 SkString* code = &builder->fFSCode;
413 const char* dColor = "dColor";
414 const char* cCoords = "cCoords";
415 const char* nearZero = "1e-6"; // Since 6.10352e−5 is the smallest half float, use
416 // a number smaller than that to approximate 0, but
417 // leave room for 32-bit float GPU rounding errors.
418
419 code->appendf("\t\tvec4 %s = ", dColor);
420 builder->appendTextureLookup(code, samplers[0], dCoordsIn, dCoordsType);
421 code->append(";\n");
422
423 // Unpremultiply the displacement
424 code->appendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
425 dColor, dColor, nearZero, dColor, dColor);
426
427 code->appendf("\t\tvec2 %s = %s + %s*(%s.",
428 cCoords, cCoordsIn, scaleUni, dColor);
429
430 switch (fXChannelSelector) {
431 case SkDisplacementMapEffect::kR_ChannelSelectorType:
432 code->append("r");
433 break;
434 case SkDisplacementMapEffect::kG_ChannelSelectorType:
435 code->append("g");
436 break;
437 case SkDisplacementMapEffect::kB_ChannelSelectorType:
438 code->append("b");
439 break;
440 case SkDisplacementMapEffect::kA_ChannelSelectorType:
441 code->append("a");
442 break;
443 case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
444 default:
445 SkASSERT(!"Unknown X channel selector");
446 }
447
448 switch (fYChannelSelector) {
449 case SkDisplacementMapEffect::kR_ChannelSelectorType:
450 code->append("r");
451 break;
452 case SkDisplacementMapEffect::kG_ChannelSelectorType:
453 code->append("g");
454 break;
455 case SkDisplacementMapEffect::kB_ChannelSelectorType:
456 code->append("b");
457 break;
458 case SkDisplacementMapEffect::kA_ChannelSelectorType:
459 code->append("a");
460 break;
461 case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
462 default:
463 SkASSERT(!"Unknown Y channel selector");
464 }
465 code->append("-vec2(0.5));\t\t");
466
467 // FIXME : This can be achieved with a "clamp to border" texture repeat mode and
468 // a 0 border color instead of computing if cCoords is out of bounds here.
469 code->appendf(
470 "%s = any(greaterThan(vec4(vec2(0.0), %s), vec4(%s, vec2(1.0)))) ? vec4(0.0) : ",
471 outputColor, cCoords, cCoords);
472 builder->appendTextureLookup(code, samplers[1], cCoords, cCoordsType);
473 code->append(";\n");
474 }
475
setData(const GrGLUniformManager & uman,const GrEffectStage & stage)476 void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
477 const GrDisplacementMapEffect& displacementMap = GetEffectFromStage<GrDisplacementMapEffect>(stage);
478 GrTexture* displTex = displacementMap.texture(0);
479 GrTexture* colorTex = displacementMap.texture(1);
480 fDisplacementEffectMatrix.setData(uman,
481 GrEffect::MakeDivByTextureWHMatrix(displTex),
482 stage.getCoordChangeMatrix(),
483 displTex);
484 fColorEffectMatrix.setData(uman,
485 GrEffect::MakeDivByTextureWHMatrix(colorTex),
486 stage.getCoordChangeMatrix(),
487 colorTex);
488
489 uman.set2f(fScaleUni, SkScalarToFloat(displacementMap.scale()),
490 colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
491 SkScalarToFloat(displacementMap.scale()) :
492 SkScalarToFloat(-displacementMap.scale()));
493 }
494
GenKey(const GrEffectStage & stage,const GrGLCaps &)495 GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrEffectStage& stage,
496 const GrGLCaps&) {
497 const GrDisplacementMapEffect& displacementMap =
498 GetEffectFromStage<GrDisplacementMapEffect>(stage);
499
500 GrTexture* displTex = displacementMap.texture(0);
501 GrTexture* colorTex = displacementMap.texture(1);
502
503 EffectKey displKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(displTex),
504 stage.getCoordChangeMatrix(),
505 displTex);
506
507 EffectKey colorKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(colorTex),
508 stage.getCoordChangeMatrix(),
509 colorTex);
510
511 colorKey <<= GrGLEffectMatrix::kKeyBits;
512 EffectKey xKey = displacementMap.xChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits);
513 EffectKey yKey = displacementMap.yChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits +
514 SkDisplacementMapEffect::kKeyBits);
515
516 return xKey | yKey | displKey | colorKey;
517 }
518 #endif
519