OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrBicubicEffect.h" | 8 #include "GrBicubicEffect.h" |
9 #include "GrInvariantOutput.h" | 9 #include "GrInvariantOutput.h" |
10 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 10 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
11 #include "glsl/GrGLSLProgramDataManager.h" | 11 #include "glsl/GrGLSLProgramDataManager.h" |
12 #include "glsl/GrGLSLUniformHandler.h" | 12 #include "glsl/GrGLSLUniformHandler.h" |
13 | 13 |
14 #define DS(x) SkDoubleToScalar(x) | 14 #define DS(x) SkDoubleToScalar(x) |
15 | 15 |
16 const SkScalar GrBicubicEffect::gMitchellCoefficients[16] = { | 16 const SkScalar GrBicubicEffect::gMitchellCoefficients[16] = { |
17 DS( 1.0 / 18.0), DS(-9.0 / 18.0), DS( 15.0 / 18.0), DS( -7.0 / 18.0), | 17 DS( 1.0 / 18.0), DS(-9.0 / 18.0), DS( 15.0 / 18.0), DS( -7.0 / 18.0), |
18 DS(16.0 / 18.0), DS( 0.0 / 18.0), DS(-36.0 / 18.0), DS( 21.0 / 18.0), | 18 DS(16.0 / 18.0), DS( 0.0 / 18.0), DS(-36.0 / 18.0), DS( 21.0 / 18.0), |
19 DS( 1.0 / 18.0), DS( 9.0 / 18.0), DS( 27.0 / 18.0), DS(-21.0 / 18.0), | 19 DS( 1.0 / 18.0), DS( 9.0 / 18.0), DS( 27.0 / 18.0), DS(-21.0 / 18.0), |
20 DS( 0.0 / 18.0), DS( 0.0 / 18.0), DS( -6.0 / 18.0), DS( 7.0 / 18.0), | 20 DS( 0.0 / 18.0), DS( 0.0 / 18.0), DS( -6.0 / 18.0), DS( 7.0 / 18.0), |
21 }; | 21 }; |
22 | 22 |
23 | 23 |
24 class GrGLBicubicEffect : public GrGLSLFragmentProcessor { | 24 class GrGLBicubicEffect : public GrGLSLFragmentProcessor { |
25 public: | 25 public: |
26 void emitCode(EmitArgs&) override; | 26 void emitCode(EmitArgs&) override; |
27 | 27 |
28 static inline void GenKey(const GrProcessor& effect, const GrGLSLCaps&, | 28 static inline void GenKey(const GrProcessor& effect, const GrGLSLCaps&, |
29 GrProcessorKeyBuilder* b) { | 29 GrProcessorKeyBuilder* b) { |
30 const GrTextureDomain& domain = effect.cast<GrBicubicEffect>().domain(); | 30 const GrBicubicEffect& bicubicEffect = effect.cast<GrBicubicEffect>(); |
31 b->add32(GrTextureDomain::GLDomain::DomainKey(domain)); | 31 b->add32(GrTextureDomain::GLDomain::DomainKey(bicubicEffect.domain())); |
32 b->add32(SkToInt(SkToBool(bicubicEffect.colorSpaceXform()))); | |
32 } | 33 } |
33 | 34 |
34 protected: | 35 protected: |
35 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; | 36 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; |
36 | 37 |
37 private: | 38 private: |
38 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; | 39 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; |
39 | 40 |
40 UniformHandle fCoefficientsUni; | 41 UniformHandle fCoefficientsUni; |
41 UniformHandle fImageIncrementUni; | 42 UniformHandle fImageIncrementUni; |
43 UniformHandle fColorSpaceXformUni; | |
42 GrTextureDomain::GLDomain fDomain; | 44 GrTextureDomain::GLDomain fDomain; |
43 | 45 |
44 typedef GrGLSLFragmentProcessor INHERITED; | 46 typedef GrGLSLFragmentProcessor INHERITED; |
45 }; | 47 }; |
46 | 48 |
47 void GrGLBicubicEffect::emitCode(EmitArgs& args) { | 49 void GrGLBicubicEffect::emitCode(EmitArgs& args) { |
48 const GrTextureDomain& domain = args.fFp.cast<GrBicubicEffect>().domain(); | 50 const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>(); |
49 | 51 |
50 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 52 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
51 fCoefficientsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 53 fCoefficientsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
52 kMat44f_GrSLType, kDefault_GrS LPrecision, | 54 kMat44f_GrSLType, kDefault_GrS LPrecision, |
53 "Coefficients"); | 55 "Coefficients"); |
54 fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 56 fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
55 kVec2f_GrSLType, kDefault_Gr SLPrecision, | 57 kVec2f_GrSLType, kDefault_Gr SLPrecision, |
56 "ImageIncrement"); | 58 "ImageIncrement"); |
57 | 59 |
58 const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); | 60 const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); |
59 const char* coeff = uniformHandler->getUniformCStr(fCoefficientsUni); | 61 const char* coeff = uniformHandler->getUniformCStr(fCoefficientsUni); |
60 | 62 |
63 const char* xformMatrix = nullptr; | |
64 if (SkToBool(bicubicEffect.colorSpaceXform())) { | |
65 fColorSpaceXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | |
66 kMat44f_GrSLType, kDefa ult_GrSLPrecision, | |
67 "ColorXform", &xformMat rix); | |
68 } | |
69 | |
61 SkString cubicBlendName; | 70 SkString cubicBlendName; |
62 | 71 |
63 static const GrGLSLShaderVar gCubicBlendArgs[] = { | 72 static const GrGLSLShaderVar gCubicBlendArgs[] = { |
64 GrGLSLShaderVar("coefficients", kMat44f_GrSLType), | 73 GrGLSLShaderVar("coefficients", kMat44f_GrSLType), |
65 GrGLSLShaderVar("t", kFloat_GrSLType), | 74 GrGLSLShaderVar("t", kFloat_GrSLType), |
66 GrGLSLShaderVar("c0", kVec4f_GrSLType), | 75 GrGLSLShaderVar("c0", kVec4f_GrSLType), |
67 GrGLSLShaderVar("c1", kVec4f_GrSLType), | 76 GrGLSLShaderVar("c1", kVec4f_GrSLType), |
68 GrGLSLShaderVar("c2", kVec4f_GrSLType), | 77 GrGLSLShaderVar("c2", kVec4f_GrSLType), |
69 GrGLSLShaderVar("c3", kVec4f_GrSLType), | 78 GrGLSLShaderVar("c3", kVec4f_GrSLType), |
70 }; | 79 }; |
(...skipping 18 matching lines...) Expand all Loading... | |
89 fragBuilder->codeAppend("\tvec4 rowColors[4];\n"); | 98 fragBuilder->codeAppend("\tvec4 rowColors[4];\n"); |
90 for (int y = 0; y < 4; ++y) { | 99 for (int y = 0; y < 4; ++y) { |
91 for (int x = 0; x < 4; ++x) { | 100 for (int x = 0; x < 4; ++x) { |
92 SkString coord; | 101 SkString coord; |
93 coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1); | 102 coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1); |
94 SkString sampleVar; | 103 SkString sampleVar; |
95 sampleVar.printf("rowColors[%d]", x); | 104 sampleVar.printf("rowColors[%d]", x); |
96 fDomain.sampleTexture(fragBuilder, | 105 fDomain.sampleTexture(fragBuilder, |
97 args.fUniformHandler, | 106 args.fUniformHandler, |
98 args.fGLSLCaps, | 107 args.fGLSLCaps, |
99 domain, | 108 bicubicEffect.domain(), |
100 sampleVar.c_str(), | 109 sampleVar.c_str(), |
101 coord, | 110 coord, |
102 args.fTexSamplers[0]); | 111 args.fTexSamplers[0]); |
103 } | 112 } |
104 fragBuilder->codeAppendf( | 113 fragBuilder->codeAppendf( |
105 "\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", | 114 "\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", |
106 y, cubicBlendName.c_str(), coeff); | 115 y, cubicBlendName.c_str(), coeff); |
107 } | 116 } |
108 SkString bicubicColor; | 117 SkString bicubicColor; |
109 bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), c oeff); | 118 bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), c oeff); |
119 if (xformMatrix) { | |
bsalomon
2016/07/18 13:56:36
Do we need a TODO about handling translations in t
Brian Osman
2016/07/18 14:07:34
I thought about it more - I think that even with a
| |
120 bicubicColor.appendf(" * %s", xformMatrix); | |
121 } | |
110 fragBuilder->codeAppendf("\t%s = %s;\n", | 122 fragBuilder->codeAppendf("\t%s = %s;\n", |
111 args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str( )) * | 123 args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str( )) * |
112 GrGLSLExpr4(args.fInputColor)). c_str()); | 124 GrGLSLExpr4(args.fInputColor)). c_str()); |
113 } | 125 } |
114 | 126 |
115 void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, | 127 void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, |
116 const GrProcessor& processor) { | 128 const GrProcessor& processor) { |
117 const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>(); | 129 const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>(); |
118 const GrTexture& texture = *processor.texture(0); | 130 const GrTexture& texture = *processor.texture(0); |
119 float imageIncrement[2]; | 131 float imageIncrement[2]; |
120 imageIncrement[0] = 1.0f / texture.width(); | 132 imageIncrement[0] = 1.0f / texture.width(); |
121 imageIncrement[1] = 1.0f / texture.height(); | 133 imageIncrement[1] = 1.0f / texture.height(); |
122 pdman.set2fv(fImageIncrementUni, 1, imageIncrement); | 134 pdman.set2fv(fImageIncrementUni, 1, imageIncrement); |
123 pdman.setMatrix4f(fCoefficientsUni, bicubicEffect.coefficients()); | 135 pdman.setMatrix4f(fCoefficientsUni, bicubicEffect.coefficients()); |
124 fDomain.setData(pdman, bicubicEffect.domain(), texture.origin()); | 136 fDomain.setData(pdman, bicubicEffect.domain(), texture.origin()); |
137 if (SkToBool(bicubicEffect.colorSpaceXform())) { | |
138 float xformMatrix[16]; | |
139 bicubicEffect.colorSpaceXform()->srcToDst().asColMajorf(xformMatrix); | |
140 pdman.setMatrix4f(fColorSpaceXformUni, xformMatrix); | |
141 } | |
125 } | 142 } |
126 | 143 |
127 static inline void convert_row_major_scalar_coeffs_to_column_major_floats(float dst[16], | 144 static inline void convert_row_major_scalar_coeffs_to_column_major_floats(float dst[16], |
128 const SkScalar src[16]) { | 145 const SkScalar src[16]) { |
129 for (int y = 0; y < 4; y++) { | 146 for (int y = 0; y < 4; y++) { |
130 for (int x = 0; x < 4; x++) { | 147 for (int x = 0; x < 4; x++) { |
131 dst[x * 4 + y] = SkScalarToFloat(src[y * 4 + x]); | 148 dst[x * 4 + y] = SkScalarToFloat(src[y * 4 + x]); |
132 } | 149 } |
133 } | 150 } |
134 } | 151 } |
135 | 152 |
136 GrBicubicEffect::GrBicubicEffect(GrTexture* texture, | 153 GrBicubicEffect::GrBicubicEffect(GrTexture* texture, |
154 sk_sp<GrColorSpaceXform> colorSpaceXform, | |
137 const SkScalar coefficients[16], | 155 const SkScalar coefficients[16], |
138 const SkMatrix &matrix, | 156 const SkMatrix &matrix, |
139 const SkShader::TileMode tileModes[2]) | 157 const SkShader::TileMode tileModes[2]) |
140 : INHERITED(texture, matrix, GrTextureParams(tileModes, GrTextureParams::kNone _FilterMode)) | 158 : INHERITED(texture, nullptr, matrix, |
141 , fDomain(GrTextureDomain::IgnoredDomain()) { | 159 GrTextureParams(tileModes, GrTextureParams::kNone_FilterMode)) |
160 , fDomain(GrTextureDomain::IgnoredDomain()) | |
161 , fColorSpaceXform(std::move(colorSpaceXform)) { | |
142 this->initClassID<GrBicubicEffect>(); | 162 this->initClassID<GrBicubicEffect>(); |
143 convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coeffi cients); | 163 convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coeffi cients); |
144 } | 164 } |
145 | 165 |
146 GrBicubicEffect::GrBicubicEffect(GrTexture* texture, | 166 GrBicubicEffect::GrBicubicEffect(GrTexture* texture, |
167 sk_sp<GrColorSpaceXform> colorSpaceXform, | |
147 const SkScalar coefficients[16], | 168 const SkScalar coefficients[16], |
148 const SkMatrix &matrix, | 169 const SkMatrix &matrix, |
149 const SkRect& domain) | 170 const SkRect& domain) |
150 : INHERITED(texture, matrix, | 171 : INHERITED(texture, nullptr, matrix, |
151 GrTextureParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_ FilterMode)) | 172 GrTextureParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_ FilterMode)) |
152 , fDomain(domain, GrTextureDomain::kClamp_Mode) { | 173 , fDomain(domain, GrTextureDomain::kClamp_Mode) |
174 , fColorSpaceXform(std::move(colorSpaceXform)) { | |
153 this->initClassID<GrBicubicEffect>(); | 175 this->initClassID<GrBicubicEffect>(); |
154 convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coeffi cients); | 176 convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coeffi cients); |
155 } | 177 } |
156 | 178 |
157 GrBicubicEffect::~GrBicubicEffect() { | 179 GrBicubicEffect::~GrBicubicEffect() { |
158 } | 180 } |
159 | 181 |
160 void GrBicubicEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 182 void GrBicubicEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
161 GrProcessorKeyBuilder* b) const { | 183 GrProcessorKeyBuilder* b) const { |
162 GrGLBicubicEffect::GenKey(*this, caps, b); | 184 GrGLBicubicEffect::GenKey(*this, caps, b); |
(...skipping 16 matching lines...) Expand all Loading... | |
179 | 201 |
180 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect); | 202 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect); |
181 | 203 |
182 sk_sp<GrFragmentProcessor> GrBicubicEffect::TestCreate(GrProcessorTestData* d) { | 204 sk_sp<GrFragmentProcessor> GrBicubicEffect::TestCreate(GrProcessorTestData* d) { |
183 int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : | 205 int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
184 GrProcessorUnitTest::kAlphaTextureIdx; | 206 GrProcessorUnitTest::kAlphaTextureIdx; |
185 SkScalar coefficients[16]; | 207 SkScalar coefficients[16]; |
186 for (int i = 0; i < 16; i++) { | 208 for (int i = 0; i < 16; i++) { |
187 coefficients[i] = d->fRandom->nextSScalar1(); | 209 coefficients[i] = d->fRandom->nextSScalar1(); |
188 } | 210 } |
189 return GrBicubicEffect::Make(d->fTextures[texIdx], coefficients); | 211 return GrBicubicEffect::Make(d->fTextures[texIdx], nullptr, coefficients); |
190 } | 212 } |
191 | 213 |
192 ////////////////////////////////////////////////////////////////////////////// | 214 ////////////////////////////////////////////////////////////////////////////// |
193 | 215 |
194 bool GrBicubicEffect::ShouldUseBicubic(const SkMatrix& matrix, | 216 bool GrBicubicEffect::ShouldUseBicubic(const SkMatrix& matrix, |
195 GrTextureParams::FilterMode* filterMode) { | 217 GrTextureParams::FilterMode* filterMode) { |
196 if (matrix.isIdentity()) { | 218 if (matrix.isIdentity()) { |
197 *filterMode = GrTextureParams::kNone_FilterMode; | 219 *filterMode = GrTextureParams::kNone_FilterMode; |
198 return false; | 220 return false; |
199 } | 221 } |
(...skipping 14 matching lines...) Expand all Loading... | |
214 // Use bilerp to handle rotation or fractional translation. | 236 // Use bilerp to handle rotation or fractional translation. |
215 *filterMode = GrTextureParams::kBilerp_FilterMode; | 237 *filterMode = GrTextureParams::kBilerp_FilterMode; |
216 } | 238 } |
217 return false; | 239 return false; |
218 } | 240 } |
219 // When we use the bicubic filtering effect each sample is read from the tex ture using | 241 // When we use the bicubic filtering effect each sample is read from the tex ture using |
220 // nearest neighbor sampling. | 242 // nearest neighbor sampling. |
221 *filterMode = GrTextureParams::kNone_FilterMode; | 243 *filterMode = GrTextureParams::kNone_FilterMode; |
222 return true; | 244 return true; |
223 } | 245 } |
OLD | NEW |