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