OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrConvolutionEffect.h" | 8 #include "GrConvolutionEffect.h" |
9 #include "gl/GrGLEffect.h" | 9 #include "gl/GrGLEffect.h" |
10 #include "gl/GrGLEffectMatrix.h" | 10 #include "gl/GrGLEffectMatrix.h" |
11 #include "gl/GrGLSL.h" | 11 #include "gl/GrGLSL.h" |
12 #include "gl/GrGLTexture.h" | 12 #include "gl/GrGLTexture.h" |
13 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
14 | 14 |
15 // For brevity | 15 // For brevity |
16 typedef GrGLUniformManager::UniformHandle UniformHandle; | 16 typedef GrGLUniformManager::UniformHandle UniformHandle; |
17 static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
niformHandle; | 17 static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
niformHandle; |
18 | 18 |
19 class GrGLConvolutionEffect : public GrGLEffect { | 19 class GrGLConvolutionEffect : public GrGLEffect { |
20 public: | 20 public: |
21 GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffectRef&); | 21 GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
22 | 22 |
23 virtual void emitCode(GrGLShaderBuilder*, | 23 virtual void emitCode(GrGLShaderBuilder*, |
24 const GrEffectStage&, | 24 const GrDrawEffect&, |
25 EffectKey, | 25 EffectKey, |
26 const char* vertexCoords, | |
27 const char* outputColor, | 26 const char* outputColor, |
28 const char* inputColor, | 27 const char* inputColor, |
29 const TextureSamplerArray&) SK_OVERRIDE; | 28 const TextureSamplerArray&) SK_OVERRIDE; |
30 | 29 |
31 virtual void setData(const GrGLUniformManager& uman, const GrEffectStage&) S
K_OVERRIDE; | 30 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK
_OVERRIDE; |
32 | 31 |
33 static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&); | 32 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); |
34 | 33 |
35 private: | 34 private: |
36 int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); } | 35 int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); } |
37 | 36 |
38 int fRadius; | 37 int fRadius; |
39 UniformHandle fKernelUni; | 38 UniformHandle fKernelUni; |
40 UniformHandle fImageIncrementUni; | 39 UniformHandle fImageIncrementUni; |
41 GrGLEffectMatrix fEffectMatrix; | 40 GrGLEffectMatrix fEffectMatrix; |
42 | 41 |
43 typedef GrGLEffect INHERITED; | 42 typedef GrGLEffect INHERITED; |
44 }; | 43 }; |
45 | 44 |
46 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& facto
ry, | 45 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& facto
ry, |
47 const GrEffectRef& effect) | 46 const GrDrawEffect& drawEffect) |
48 : INHERITED(factory) | 47 : INHERITED(factory) |
49 , fKernelUni(kInvalidUniformHandle) | 48 , fKernelUni(kInvalidUniformHandle) |
50 , fImageIncrementUni(kInvalidUniformHandle) { | 49 , fImageIncrementUni(kInvalidUniformHandle) |
51 const GrConvolutionEffect& c = CastEffect<GrConvolutionEffect>(effect); | 50 , fEffectMatrix(drawEffect.castEffect<GrConvolutionEffect>().coordsType()) { |
| 51 const GrConvolutionEffect& c = drawEffect.castEffect<GrConvolutionEffect>(); |
52 fRadius = c.radius(); | 52 fRadius = c.radius(); |
53 } | 53 } |
54 | 54 |
55 void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder, | 55 void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder, |
56 const GrEffectStage&, | 56 const GrDrawEffect&, |
57 EffectKey key, | 57 EffectKey key, |
58 const char* vertexCoords, | |
59 const char* outputColor, | 58 const char* outputColor, |
60 const char* inputColor, | 59 const char* inputColor, |
61 const TextureSamplerArray& samplers) { | 60 const TextureSamplerArray& samplers) { |
62 const char* coords; | 61 const char* coords; |
63 fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords); | 62 fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords); |
64 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Shader
Type, | 63 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Shader
Type, |
65 kVec2f_GrSLType, "ImageIncrement"); | 64 kVec2f_GrSLType, "ImageIncrement"); |
66 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderTyp
e, | 65 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderTyp
e, |
67 kFloat_GrSLType, "Kernel", this->width
()); | 66 kFloat_GrSLType, "Kernel", this->width
()); |
68 | 67 |
69 builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); | 68 builder->fsCodeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); |
70 | 69 |
71 int width = this ->width(); | 70 int width = this ->width(); |
72 const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni); | 71 const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni); |
73 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); | 72 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); |
74 | 73 |
75 builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords, fRadius
, imgInc); | 74 builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords, fRadius
, imgInc); |
76 | 75 |
77 // Manually unroll loop because some drivers don't; yields 20-30% speedup. | 76 // Manually unroll loop because some drivers don't; yields 20-30% speedup. |
78 for (int i = 0; i < width; i++) { | 77 for (int i = 0; i < width; i++) { |
79 SkString index; | 78 SkString index; |
80 SkString kernelIndex; | 79 SkString kernelIndex; |
81 index.appendS32(i); | 80 index.appendS32(i); |
82 kernel.appendArrayAccess(index.c_str(), &kernelIndex); | 81 kernel.appendArrayAccess(index.c_str(), &kernelIndex); |
83 builder->fsCodeAppendf("\t\t%s += ", outputColor); | 82 builder->fsCodeAppendf("\t\t%s += ", outputColor); |
84 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, sa
mplers[0], "coord"); | 83 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, sa
mplers[0], "coord"); |
85 builder->fsCodeAppendf(" * %s;\n", kernelIndex.c_str()); | 84 builder->fsCodeAppendf(" * %s;\n", kernelIndex.c_str()); |
86 builder->fsCodeAppendf("\t\tcoord += %s;\n", imgInc); | 85 builder->fsCodeAppendf("\t\tcoord += %s;\n", imgInc); |
87 } | 86 } |
88 SkString modulate; | 87 SkString modulate; |
89 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); | 88 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); |
90 builder->fsCodeAppend(modulate.c_str()); | 89 builder->fsCodeAppend(modulate.c_str()); |
91 } | 90 } |
92 | 91 |
93 void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffe
ctStage& stage) { | 92 void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, |
94 const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(st
age); | 93 const GrDrawEffect& drawEffect) { |
| 94 const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>
(); |
95 GrTexture& texture = *conv.texture(0); | 95 GrTexture& texture = *conv.texture(0); |
96 // the code we generated was for a specific kernel radius | 96 // the code we generated was for a specific kernel radius |
97 GrAssert(conv.radius() == fRadius); | 97 GrAssert(conv.radius() == fRadius); |
98 float imageIncrement[2] = { 0 }; | 98 float imageIncrement[2] = { 0 }; |
99 switch (conv.direction()) { | 99 switch (conv.direction()) { |
100 case Gr1DKernelEffect::kX_Direction: | 100 case Gr1DKernelEffect::kX_Direction: |
101 imageIncrement[0] = 1.0f / texture.width(); | 101 imageIncrement[0] = 1.0f / texture.width(); |
102 break; | 102 break; |
103 case Gr1DKernelEffect::kY_Direction: | 103 case Gr1DKernelEffect::kY_Direction: |
104 imageIncrement[1] = 1.0f / texture.height(); | 104 imageIncrement[1] = 1.0f / texture.height(); |
105 break; | 105 break; |
106 default: | 106 default: |
107 GrCrash("Unknown filter direction."); | 107 GrCrash("Unknown filter direction."); |
108 } | 108 } |
109 uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); | 109 uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); |
110 uman.set1fv(fKernelUni, 0, this->width(), conv.kernel()); | 110 uman.set1fv(fKernelUni, 0, this->width(), conv.kernel()); |
111 fEffectMatrix.setData(uman, conv.getMatrix(), stage.getCoordChangeMatrix(),
conv.texture(0)); | 111 fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0)); |
112 } | 112 } |
113 | 113 |
114 GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffectStage& s, cons
t GrGLCaps&) { | 114 GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffe
ct, |
115 const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(s)
; | 115 const GrGLCaps&) { |
| 116 const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>
(); |
116 EffectKey key = conv.radius(); | 117 EffectKey key = conv.radius(); |
117 key <<= GrGLEffectMatrix::kKeyBits; | 118 key <<= GrGLEffectMatrix::kKeyBits; |
118 EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(), | 119 EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(), |
119 s.getCoordChangeMatrix(), | 120 drawEffect, |
| 121 conv.coordsType(), |
120 conv.texture(0)); | 122 conv.texture(0)); |
121 return key | matrixKey; | 123 return key | matrixKey; |
122 } | 124 } |
123 | 125 |
124 /////////////////////////////////////////////////////////////////////////////// | 126 /////////////////////////////////////////////////////////////////////////////// |
125 | 127 |
126 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, | 128 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, |
127 Direction direction, | 129 Direction direction, |
128 int radius, | 130 int radius, |
129 const float* kernel) | 131 const float* kernel) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 GrEffectUnitTest::kAlphaTextureIdx; | 188 GrEffectUnitTest::kAlphaTextureIdx; |
187 Direction dir = random->nextBool() ? kX_Direction : kY_Direction; | 189 Direction dir = random->nextBool() ? kX_Direction : kY_Direction; |
188 int radius = random->nextRangeU(1, kMaxKernelRadius); | 190 int radius = random->nextRangeU(1, kMaxKernelRadius); |
189 float kernel[kMaxKernelRadius]; | 191 float kernel[kMaxKernelRadius]; |
190 for (int i = 0; i < kMaxKernelRadius; ++i) { | 192 for (int i = 0; i < kMaxKernelRadius; ++i) { |
191 kernel[i] = random->nextSScalar1(); | 193 kernel[i] = random->nextSScalar1(); |
192 } | 194 } |
193 | 195 |
194 return GrConvolutionEffect::Create(textures[texIdx], dir, radius,kernel); | 196 return GrConvolutionEffect::Create(textures[texIdx], dir, radius,kernel); |
195 } | 197 } |
OLD | NEW |