OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrDistanceFieldTextureEffect.h" | 8 #include "GrDistanceFieldTextureEffect.h" |
9 #include "GrInvariantOutput.h" | 9 #include "GrInvariantOutput.h" |
10 #include "GrTexture.h" | 10 #include "GrTexture.h" |
11 #include "SkDistanceFieldGen.h" | 11 #include "SkDistanceFieldGen.h" |
12 #include "gl/GrGLProcessor.h" | 12 #include "gl/GrGLProcessor.h" |
13 #include "gl/GrGLSL.h" | 13 #include "gl/GrGLSL.h" |
14 #include "gl/GrGLTexture.h" | 14 #include "gl/GrGLTexture.h" |
15 #include "gl/GrGLGeometryProcessor.h" | 15 #include "gl/GrGLGeometryProcessor.h" |
16 #include "gl/builders/GrGLProgramBuilder.h" | 16 #include "gl/builders/GrGLProgramBuilder.h" |
17 | 17 |
18 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 | 18 // Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/
2 |
19 #define SK_DistanceFieldAAFactor "0.7071" | 19 #define SK_DistanceFieldAAFactor "0.7071" |
20 | 20 |
| 21 struct DistanceFieldBatchTracker { |
| 22 GPInput fInputColorType; |
| 23 GrColor fColor; |
| 24 }; |
| 25 |
21 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { | 26 class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { |
22 public: | 27 public: |
23 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&, | 28 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&, |
24 const GrBatchTracker&) | 29 const GrBatchTracker&) |
25 : fTextureSize(SkISize::Make(-1,-1)) | 30 : fTextureSize(SkISize::Make(-1,-1)) |
26 #ifdef SK_GAMMA_APPLY_TO_A8 | 31 #ifdef SK_GAMMA_APPLY_TO_A8 |
27 , fLuminance(-1.0f) | 32 , fLuminance(-1.0f) |
28 #endif | 33 #endif |
29 {} | 34 {} |
30 | 35 |
31 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 36 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
32 const GrDistanceFieldTextureEffect& dfTexEffect = | 37 const GrDistanceFieldTextureEffect& dfTexEffect = |
33 args.fGP.cast<GrDistanceFieldTextureEffect>(); | 38 args.fGP.cast<GrDistanceFieldTextureEffect>(); |
34 | 39 const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatc
hTracker>(); |
| 40 GrGLGPBuilder* pb = args.fPB; |
35 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 41 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
36 SkAssertResult(fsBuilder->enableFeature( | 42 SkAssertResult(fsBuilder->enableFeature( |
37 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 43 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
38 | 44 |
39 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 45 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
40 GrGLVertToFrag v(kVec2f_GrSLType); | 46 GrGLVertToFrag v(kVec2f_GrSLType); |
41 args.fPB->addVarying("TextureCoords", &v); | 47 args.fPB->addVarying("TextureCoords", &v); |
42 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); | 48 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); |
43 | 49 |
44 // setup color attribute | 50 // Setup pass through color |
45 if(dfTexEffect.inColor()) { | 51 this->setupColor(pb, local.fInputColorType, args.fOutputColor, dfTexEffe
ct.inColor(), |
46 args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutpu
tColor); | 52 &fColorUniform); |
47 } | |
48 | 53 |
49 // setup position varying | 54 // setup position varying |
50 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition()
, | 55 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition()
, |
51 vsBuilder->uViewM(), dfTexEffect.inPosition()->fN
ame); | 56 vsBuilder->uViewM(), dfTexEffect.inPosition()->fN
ame); |
52 | 57 |
53 // setup output coords | 58 // setup output coords |
54 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), | 59 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), |
55 dfTexEffect.inPosition()->fName); | 60 dfTexEffect.inPosition()->fName); |
56 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), | 61 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), |
57 dfTexEffect.inPosition()->fName); | 62 dfTexEffect.inPosition()->fName); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 120 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
116 fsBuilder->codeAppend(";\n"); | 121 fsBuilder->codeAppend(";\n"); |
117 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); | 122 fsBuilder->codeAppend("\tval = gammaColor.r;\n"); |
118 #endif | 123 #endif |
119 | 124 |
120 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 125 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
121 } | 126 } |
122 | 127 |
123 virtual void setData(const GrGLProgramDataManager& pdman, | 128 virtual void setData(const GrGLProgramDataManager& pdman, |
124 const GrGeometryProcessor& proc, | 129 const GrGeometryProcessor& proc, |
125 const GrBatchTracker&) SK_OVERRIDE { | 130 const GrBatchTracker& bt) SK_OVERRIDE { |
126 SkASSERT(fTextureSizeUni.isValid()); | 131 SkASSERT(fTextureSizeUni.isValid()); |
127 | 132 |
128 GrTexture* texture = proc.texture(0); | 133 GrTexture* texture = proc.texture(0); |
129 if (texture->width() != fTextureSize.width() || | 134 if (texture->width() != fTextureSize.width() || |
130 texture->height() != fTextureSize.height()) { | 135 texture->height() != fTextureSize.height()) { |
131 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 136 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
132 pdman.set2f(fTextureSizeUni, | 137 pdman.set2f(fTextureSizeUni, |
133 SkIntToScalar(fTextureSize.width()), | 138 SkIntToScalar(fTextureSize.width()), |
134 SkIntToScalar(fTextureSize.height())); | 139 SkIntToScalar(fTextureSize.height())); |
135 } | 140 } |
136 #ifdef SK_GAMMA_APPLY_TO_A8 | 141 #ifdef SK_GAMMA_APPLY_TO_A8 |
137 const GrDistanceFieldTextureEffect& dfTexEffect = | 142 const GrDistanceFieldTextureEffect& dfTexEffect = |
138 proc.cast<GrDistanceFieldTextureEffect>(); | 143 proc.cast<GrDistanceFieldTextureEffect>(); |
139 float luminance = dfTexEffect.getLuminance(); | 144 float luminance = dfTexEffect.getLuminance(); |
140 if (luminance != fLuminance) { | 145 if (luminance != fLuminance) { |
141 pdman.set1f(fLuminanceUni, luminance); | 146 pdman.set1f(fLuminanceUni, luminance); |
142 fLuminance = luminance; | 147 fLuminance = luminance; |
143 } | 148 } |
144 #endif | 149 #endif |
| 150 |
| 151 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack
er>(); |
| 152 this->setUniformColorIfRequired(pdman, local.fInputColorType, local.fCol
or, fColorUniform); |
145 } | 153 } |
146 | 154 |
147 static inline void GenKey(const GrGeometryProcessor& processor, | 155 static inline void GenKey(const GrGeometryProcessor& processor, |
148 const GrBatchTracker&, | 156 const GrBatchTracker& bt, |
149 const GrGLCaps&, | 157 const GrGLCaps&, |
150 GrProcessorKeyBuilder* b) { | 158 GrProcessorKeyBuilder* b) { |
151 const GrDistanceFieldTextureEffect& dfTexEffect = | 159 const GrDistanceFieldTextureEffect& dfTexEffect = |
152 processor.cast<GrDistanceFieldTextureEffect>(); | 160 processor.cast<GrDistanceFieldTextureEffect>(); |
153 | 161 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack
er>(); |
154 b->add32(dfTexEffect.getFlags()); | 162 b->add32(dfTexEffect.getFlags()); |
| 163 b->add32(local.fInputColorType); |
155 } | 164 } |
156 | 165 |
157 private: | 166 private: |
158 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 167 UniformHandle fColorUniform; |
159 SkISize fTextureSize; | 168 UniformHandle fTextureSizeUni; |
160 GrGLProgramDataManager::UniformHandle fLuminanceUni; | 169 SkISize fTextureSize; |
161 float fLuminance; | 170 UniformHandle fLuminanceUni; |
| 171 float fLuminance; |
162 | 172 |
163 typedef GrGLGeometryProcessor INHERITED; | 173 typedef GrGLGeometryProcessor INHERITED; |
164 }; | 174 }; |
165 | 175 |
166 /////////////////////////////////////////////////////////////////////////////// | 176 /////////////////////////////////////////////////////////////////////////////// |
167 | 177 |
168 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, | 178 GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, |
169 GrTexture* texture, | 179 GrTexture* texture, |
170 const GrTextureParams
& params, | 180 const GrTextureParams
& params, |
171 #ifdef SK_GAMMA_APPLY_TO_A8 | 181 #ifdef SK_GAMMA_APPLY_TO_A8 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 const GrGLCaps& caps, | 224 const GrGLCaps& caps, |
215 GrProcessorKeyBuilder* b) c
onst { | 225 GrProcessorKeyBuilder* b) c
onst { |
216 GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b); | 226 GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b); |
217 } | 227 } |
218 | 228 |
219 GrGLGeometryProcessor* | 229 GrGLGeometryProcessor* |
220 GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt) const { | 230 GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt) const { |
221 return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt)); | 231 return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt)); |
222 } | 232 } |
223 | 233 |
| 234 void GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt, const In
itBT& init) const { |
| 235 DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>(); |
| 236 local->fColor = init.fColor; |
| 237 local->fInputColorType = GetColorInputType(init, SkToBool(fInColor)); |
| 238 } |
| 239 |
| 240 bool GrDistanceFieldTextureEffect::onCanBatch(const GrBatchTracker& l, |
| 241 const GrBatchTracker& r) const { |
| 242 const DistanceFieldBatchTracker& left = l.cast<DistanceFieldBatchTracker>(); |
| 243 const DistanceFieldBatchTracker& right = r.cast<DistanceFieldBatchTracker>()
; |
| 244 return CanCombineOutput(left.fInputColorType, left.fColor, |
| 245 right.fInputColorType, right.fColor); |
| 246 } |
| 247 |
224 /////////////////////////////////////////////////////////////////////////////// | 248 /////////////////////////////////////////////////////////////////////////////// |
225 | 249 |
226 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect); | 250 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect); |
227 | 251 |
228 GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, | 252 GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, |
229 GrContext*, | 253 GrContext*, |
230 const GrDrawTarget
Caps&, | 254 const GrDrawTarget
Caps&, |
231 GrTexture* texture
s[]) { | 255 GrTexture* texture
s[]) { |
232 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : | 256 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
233 GrProcessorUnitTest::kAlphaTextureIdx; | 257 GrProcessorUnitTest::kAlphaTextureIdx; |
(...skipping 22 matching lines...) Expand all Loading... |
256 textures[texIdx2], params2, | 280 textures[texIdx2], params2, |
257 random->nextF(), | 281 random->nextF(), |
258 #endif | 282 #endif |
259 random->nextBool() ? | 283 random->nextBool() ? |
260 kSimilarity_DistanceFieldEff
ectFlag : 0, | 284 kSimilarity_DistanceFieldEff
ectFlag : 0, |
261 random->nextBool()); | 285 random->nextBool()); |
262 } | 286 } |
263 | 287 |
264 /////////////////////////////////////////////////////////////////////////////// | 288 /////////////////////////////////////////////////////////////////////////////// |
265 | 289 |
| 290 struct DistanceFieldNoGammaBatchTracker { |
| 291 GPInput fInputColorType; |
| 292 GrColor fColor; |
| 293 }; |
| 294 |
266 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { | 295 class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { |
267 public: | 296 public: |
268 GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&, | 297 GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&, |
269 const GrBatchTracker&) | 298 const GrBatchTracker&) |
270 : fTextureSize(SkISize::Make(-1, -1)) {} | 299 : fTextureSize(SkISize::Make(-1, -1)) {} |
271 | 300 |
272 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 301 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
273 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = | 302 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
274 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); | 303 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); |
275 | 304 |
| 305 const DistanceFieldNoGammaBatchTracker& local = |
| 306 args.fBT.cast<DistanceFieldNoGammaBatchTracker>(); |
| 307 GrGLGPBuilder* pb = args.fPB; |
276 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 308 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
277 SkAssertResult(fsBuilder->enableFeature( | 309 SkAssertResult(fsBuilder->enableFeature( |
278 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); | 310 GrGLFragmentShaderBuilder::kStandardDerivat
ives_GLSLFeature)); |
279 | 311 |
280 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 312 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
281 GrGLVertToFrag v(kVec2f_GrSLType); | 313 GrGLVertToFrag v(kVec2f_GrSLType); |
282 args.fPB->addVarying("TextureCoords", &v); | 314 args.fPB->addVarying("TextureCoords", &v); |
283 | 315 |
284 // setup color attribute | 316 // setup pass through color |
285 if(dfTexEffect.inColor()) { | 317 this->setupColor(pb, local.fInputColorType, args.fOutputColor, dfTexEffe
ct.inColor(), |
286 args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutpu
tColor); | 318 &fColorUniform); |
287 } | |
288 | 319 |
289 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); | 320 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); |
290 | 321 |
291 // setup coord outputs | 322 // setup coord outputs |
292 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), | 323 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), |
293 dfTexEffect.inPosition()->fName); | 324 dfTexEffect.inPosition()->fName); |
294 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), | 325 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), |
295 dfTexEffect.inPosition()->fName); | 326 dfTexEffect.inPosition()->fName); |
296 | 327 |
297 // setup position varying | 328 // setup position varying |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 // this gives us a smooth step across approximately one fragment | 373 // this gives us a smooth step across approximately one fragment |
343 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); | 374 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length
(grad);"); |
344 } | 375 } |
345 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); | 376 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distanc
e);"); |
346 | 377 |
347 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 378 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
348 } | 379 } |
349 | 380 |
350 virtual void setData(const GrGLProgramDataManager& pdman, | 381 virtual void setData(const GrGLProgramDataManager& pdman, |
351 const GrGeometryProcessor& proc, | 382 const GrGeometryProcessor& proc, |
352 const GrBatchTracker&) SK_OVERRIDE { | 383 const GrBatchTracker& bt) SK_OVERRIDE { |
353 SkASSERT(fTextureSizeUni.isValid()); | 384 SkASSERT(fTextureSizeUni.isValid()); |
354 | 385 |
355 GrTexture* texture = proc.texture(0); | 386 GrTexture* texture = proc.texture(0); |
356 if (texture->width() != fTextureSize.width() || | 387 if (texture->width() != fTextureSize.width() || |
357 texture->height() != fTextureSize.height()) { | 388 texture->height() != fTextureSize.height()) { |
358 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 389 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
359 pdman.set2f(fTextureSizeUni, | 390 pdman.set2f(fTextureSizeUni, |
360 SkIntToScalar(fTextureSize.width()), | 391 SkIntToScalar(fTextureSize.width()), |
361 SkIntToScalar(fTextureSize.height())); | 392 SkIntToScalar(fTextureSize.height())); |
362 } | 393 } |
| 394 |
| 395 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoG
ammaBatchTracker>(); |
| 396 this->setUniformColorIfRequired(pdman, local.fInputColorType, local.fCol
or, fColorUniform); |
363 } | 397 } |
364 | 398 |
365 static inline void GenKey(const GrGeometryProcessor& proc, | 399 static inline void GenKey(const GrGeometryProcessor& proc, |
366 const GrBatchTracker&, | 400 const GrBatchTracker& bt, |
367 const GrGLCaps&, | 401 const GrGLCaps&, |
368 GrProcessorKeyBuilder* b) { | 402 GrProcessorKeyBuilder* b) { |
369 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = | 403 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
370 proc.cast<GrDistanceFieldNoGammaTextureEffect>(); | 404 proc.cast<GrDistanceFieldNoGammaTextureEffect>(); |
371 | 405 |
| 406 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoG
ammaBatchTracker>(); |
372 b->add32(dfTexEffect.getFlags()); | 407 b->add32(dfTexEffect.getFlags()); |
| 408 b->add32(local.fInputColorType); |
373 } | 409 } |
374 | 410 |
375 private: | 411 private: |
376 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 412 UniformHandle fColorUniform; |
377 SkISize fTextureSize; | 413 UniformHandle fTextureSizeUni; |
| 414 SkISize fTextureSize; |
378 | 415 |
379 typedef GrGLGeometryProcessor INHERITED; | 416 typedef GrGLGeometryProcessor INHERITED; |
380 }; | 417 }; |
381 | 418 |
382 /////////////////////////////////////////////////////////////////////////////// | 419 /////////////////////////////////////////////////////////////////////////////// |
383 | 420 |
384 GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect( | 421 GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect( |
385 GrColor color, | 422 GrColor color, |
386 GrTexture* texture, | 423 GrTexture* texture, |
387 const GrTextureParams& params, | 424 const GrTextureParams& params, |
(...skipping 29 matching lines...) Expand all Loading... |
417 const GrGLCaps& caps
, | 454 const GrGLCaps& caps
, |
418 GrProcessorKeyBuilde
r* b) const { | 455 GrProcessorKeyBuilde
r* b) const { |
419 GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b); | 456 GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b); |
420 } | 457 } |
421 | 458 |
422 GrGLGeometryProcessor* | 459 GrGLGeometryProcessor* |
423 GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt)
const { | 460 GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt)
const { |
424 return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt)); | 461 return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt)); |
425 } | 462 } |
426 | 463 |
| 464 void GrDistanceFieldNoGammaTextureEffect::initBatchTracker(GrBatchTracker* bt, |
| 465 const InitBT& init) c
onst { |
| 466 DistanceFieldNoGammaBatchTracker* local = bt->cast<DistanceFieldNoGammaBatch
Tracker>(); |
| 467 local->fColor = init.fColor; |
| 468 local->fInputColorType = GetColorInputType(init, SkToBool(fInColor)); |
| 469 } |
| 470 |
| 471 bool GrDistanceFieldNoGammaTextureEffect::onCanBatch(const GrBatchTracker& l, |
| 472 const GrBatchTracker& r) co
nst { |
| 473 const DistanceFieldNoGammaBatchTracker& left = l.cast<DistanceFieldNoGammaBa
tchTracker>(); |
| 474 const DistanceFieldNoGammaBatchTracker& right = r.cast<DistanceFieldNoGammaB
atchTracker>(); |
| 475 return CanCombineOutput(left.fInputColorType, left.fColor, |
| 476 right.fInputColorType, right.fColor); |
| 477 } |
| 478 |
427 /////////////////////////////////////////////////////////////////////////////// | 479 /////////////////////////////////////////////////////////////////////////////// |
428 | 480 |
429 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect); | 481 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect); |
430 | 482 |
431 GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r
andom, | 483 GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r
andom, |
432 GrContext*, | 484 GrContext*, |
433 const GrDra
wTargetCaps&, | 485 const GrDra
wTargetCaps&, |
434 GrTexture*
textures[]) { | 486 GrTexture*
textures[]) { |
435 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx | 487 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx |
436 : GrProcessorUnitTest::kAlphaTextureIdx; | 488 : GrProcessorUnitTest::kAlphaTextureIdx; |
437 static const SkShader::TileMode kTileModes[] = { | 489 static const SkShader::TileMode kTileModes[] = { |
438 SkShader::kClamp_TileMode, | 490 SkShader::kClamp_TileMode, |
439 SkShader::kRepeat_TileMode, | 491 SkShader::kRepeat_TileMode, |
440 SkShader::kMirror_TileMode, | 492 SkShader::kMirror_TileMode, |
441 }; | 493 }; |
442 SkShader::TileMode tileModes[] = { | 494 SkShader::TileMode tileModes[] = { |
443 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 495 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
444 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 496 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
445 }; | 497 }; |
446 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode | 498 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode |
447 : GrTextureParams::kNon
e_FilterMode); | 499 : GrTextureParams::kNon
e_FilterMode); |
448 | 500 |
449 return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), te
xtures[texIdx], | 501 return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), te
xtures[texIdx], |
450 params, | 502 params, |
451 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->ne
xtBool()); | 503 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->ne
xtBool()); |
452 } | 504 } |
453 | 505 |
454 /////////////////////////////////////////////////////////////////////////////// | 506 /////////////////////////////////////////////////////////////////////////////// |
455 | 507 |
| 508 struct DistanceFieldLCDBatchTracker { |
| 509 GPInput fInputColorType; |
| 510 GrColor fColor; |
| 511 }; |
| 512 |
456 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { | 513 class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { |
457 public: | 514 public: |
458 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&, | 515 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&, |
459 const GrBatchTracker&) | 516 const GrBatchTracker&) |
460 : fTextureSize(SkISize::Make(-1,-1)) | 517 : fTextureSize(SkISize::Make(-1,-1)) |
461 , fTextColor(GrColor_ILLEGAL) {} | 518 , fTextColor(GrColor_ILLEGAL) {} |
462 | 519 |
463 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | 520 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
464 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 521 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
465 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); | 522 args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); |
| 523 const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldL
CDBatchTracker>(); |
| 524 GrGLGPBuilder* pb = args.fPB; |
466 | 525 |
467 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 526 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
468 GrGLVertToFrag v(kVec2f_GrSLType); | 527 GrGLVertToFrag v(kVec2f_GrSLType); |
469 args.fPB->addVarying("TextureCoords", &v); | 528 args.fPB->addVarying("TextureCoords", &v); |
470 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); | 529 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoord
s()->fName); |
471 | 530 |
| 531 // setup pass through color |
| 532 this->setupColor(pb, local.fInputColorType, args.fOutputColor, NULL, &fC
olorUniform); |
| 533 |
472 // setup coord outputs | 534 // setup coord outputs |
473 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), | 535 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), |
474 dfTexEffect.inPosition()->fName); | 536 dfTexEffect.inPosition()->fName); |
475 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), | 537 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), |
476 dfTexEffect.inPosition()->fName); | 538 dfTexEffect.inPosition()->fName); |
477 | 539 |
478 // setup position varying | 540 // setup position varying |
479 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition()
, | 541 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition()
, |
480 vsBuilder->uViewM(), dfTexEffect.inPosition()->fN
ame); | 542 vsBuilder->uViewM(), dfTexEffect.inPosition()->fN
ame); |
481 | 543 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 fsBuilder->codeAppend("\tgammaColor = "); | 644 fsBuilder->codeAppend("\tgammaColor = "); |
583 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 645 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
584 fsBuilder->codeAppend(";\n"); | 646 fsBuilder->codeAppend(";\n"); |
585 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); | 647 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); |
586 | 648 |
587 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 649 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
588 } | 650 } |
589 | 651 |
590 virtual void setData(const GrGLProgramDataManager& pdman, | 652 virtual void setData(const GrGLProgramDataManager& pdman, |
591 const GrGeometryProcessor& processor, | 653 const GrGeometryProcessor& processor, |
592 const GrBatchTracker&) SK_OVERRIDE { | 654 const GrBatchTracker& bt) SK_OVERRIDE { |
593 SkASSERT(fTextureSizeUni.isValid()); | 655 SkASSERT(fTextureSizeUni.isValid()); |
594 SkASSERT(fTextColorUni.isValid()); | 656 SkASSERT(fTextColorUni.isValid()); |
595 | 657 |
596 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 658 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
597 processor.cast<GrDistanceFieldLCDTextureEffect>(); | 659 processor.cast<GrDistanceFieldLCDTextureEffect>(); |
598 GrTexture* texture = processor.texture(0); | 660 GrTexture* texture = processor.texture(0); |
599 if (texture->width() != fTextureSize.width() || | 661 if (texture->width() != fTextureSize.width() || |
600 texture->height() != fTextureSize.height()) { | 662 texture->height() != fTextureSize.height()) { |
601 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 663 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
602 float delta = 1.0f/(3.0f*texture->width()); | 664 float delta = 1.0f/(3.0f*texture->width()); |
603 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { | 665 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
604 delta = -delta; | 666 delta = -delta; |
605 } | 667 } |
606 pdman.set3f(fTextureSizeUni, | 668 pdman.set3f(fTextureSizeUni, |
607 SkIntToScalar(fTextureSize.width()), | 669 SkIntToScalar(fTextureSize.width()), |
608 SkIntToScalar(fTextureSize.height()), | 670 SkIntToScalar(fTextureSize.height()), |
609 delta); | 671 delta); |
610 } | 672 } |
611 | 673 |
612 GrColor textColor = dfTexEffect.getTextColor(); | 674 GrColor textColor = dfTexEffect.getTextColor(); |
613 if (textColor != fTextColor) { | 675 if (textColor != fTextColor) { |
614 static const float ONE_OVER_255 = 1.f / 255.f; | 676 static const float ONE_OVER_255 = 1.f / 255.f; |
615 pdman.set3f(fTextColorUni, | 677 pdman.set3f(fTextColorUni, |
616 GrColorUnpackR(textColor) * ONE_OVER_255, | 678 GrColorUnpackR(textColor) * ONE_OVER_255, |
617 GrColorUnpackG(textColor) * ONE_OVER_255, | 679 GrColorUnpackG(textColor) * ONE_OVER_255, |
618 GrColorUnpackB(textColor) * ONE_OVER_255); | 680 GrColorUnpackB(textColor) * ONE_OVER_255); |
619 fTextColor = textColor; | 681 fTextColor = textColor; |
620 } | 682 } |
| 683 |
| 684 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc
hTracker>(); |
| 685 this->setUniformColorIfRequired(pdman, local.fInputColorType, local.fCol
or, fColorUniform); |
621 } | 686 } |
622 | 687 |
623 static inline void GenKey(const GrGeometryProcessor& processor, | 688 static inline void GenKey(const GrGeometryProcessor& processor, |
624 const GrBatchTracker&, | 689 const GrBatchTracker& bt, |
625 const GrGLCaps&, | 690 const GrGLCaps&, |
626 GrProcessorKeyBuilder* b) { | 691 GrProcessorKeyBuilder* b) { |
627 const GrDistanceFieldLCDTextureEffect& dfTexEffect = | 692 const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
628 processor.cast<GrDistanceFieldLCDTextureEffect>(); | 693 processor.cast<GrDistanceFieldLCDTextureEffect>(); |
629 | 694 |
| 695 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc
hTracker>(); |
630 b->add32(dfTexEffect.getFlags()); | 696 b->add32(dfTexEffect.getFlags()); |
| 697 b->add32(local.fInputColorType); |
631 } | 698 } |
632 | 699 |
633 private: | 700 private: |
634 GrGLProgramDataManager::UniformHandle fTextureSizeUni; | 701 UniformHandle fColorUniform; |
635 SkISize fTextureSize; | 702 UniformHandle fTextureSizeUni; |
636 GrGLProgramDataManager::UniformHandle fTextColorUni; | 703 SkISize fTextureSize; |
637 SkColor fTextColor; | 704 UniformHandle fTextColorUni; |
| 705 SkColor fTextColor; |
638 | 706 |
639 typedef GrGLGeometryProcessor INHERITED; | 707 typedef GrGLGeometryProcessor INHERITED; |
640 }; | 708 }; |
641 | 709 |
642 /////////////////////////////////////////////////////////////////////////////// | 710 /////////////////////////////////////////////////////////////////////////////// |
643 | 711 |
644 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( | 712 GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( |
645 GrColor color, | 713 GrColor color, |
646 GrTexture* texture, const GrTe
xtureParams& params, | 714 GrTexture* texture, const GrTe
xtureParams& params, |
647 GrTexture* gamma, const GrText
ureParams& gParams, | 715 GrTexture* gamma, const GrText
ureParams& gParams, |
(...skipping 28 matching lines...) Expand all Loading... |
676 const GrGLCaps& caps, | 744 const GrGLCaps& caps, |
677 GrProcessorKeyBuilder* b
) const { | 745 GrProcessorKeyBuilder* b
) const { |
678 GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b); | 746 GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b); |
679 } | 747 } |
680 | 748 |
681 GrGLGeometryProcessor* | 749 GrGLGeometryProcessor* |
682 GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt) cons
t { | 750 GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt) cons
t { |
683 return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt)); | 751 return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt)); |
684 } | 752 } |
685 | 753 |
| 754 void GrDistanceFieldLCDTextureEffect::initBatchTracker(GrBatchTracker* bt, |
| 755 const InitBT& init) const
{ |
| 756 DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>
(); |
| 757 local->fColor = init.fColor; |
| 758 local->fInputColorType = GetColorInputType(init, false); |
| 759 } |
| 760 |
| 761 bool GrDistanceFieldLCDTextureEffect::onCanBatch(const GrBatchTracker& l, |
| 762 const GrBatchTracker& r) co
nst { |
| 763 const DistanceFieldLCDBatchTracker& left = l.cast<DistanceFieldLCDBatchTrack
er>(); |
| 764 const DistanceFieldLCDBatchTracker& right = r.cast<DistanceFieldLCDBatchTrac
ker>(); |
| 765 return CanCombineOutput(left.fInputColorType, left.fColor, |
| 766 right.fInputColorType, right.fColor); |
| 767 } |
| 768 |
686 /////////////////////////////////////////////////////////////////////////////// | 769 /////////////////////////////////////////////////////////////////////////////// |
687 | 770 |
688 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect); | 771 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect); |
689 | 772 |
690 GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
m, | 773 GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
m, |
691 GrContext*, | 774 GrContext*, |
692 const GrDrawTar
getCaps&, | 775 const GrDrawTar
getCaps&, |
693 GrTexture* text
ures[]) { | 776 GrTexture* text
ures[]) { |
694 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : | 777 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
695 GrProcessorUnitTest::kAlphaTextureIdx; | 778 GrProcessorUnitTest::kAlphaTextureIdx; |
(...skipping 17 matching lines...) Expand all Loading... |
713 random->nextULessThan(256), | 796 random->nextULessThan(256), |
714 random->nextULessThan(256)); | 797 random->nextULessThan(256)); |
715 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 798 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
716 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 799 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
717 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 800 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
718 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textur
es[texIdx], params, | 801 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textur
es[texIdx], params, |
719 textures[texIdx2], params2, | 802 textures[texIdx2], params2, |
720 textColor, | 803 textColor, |
721 flags); | 804 flags); |
722 } | 805 } |
OLD | NEW |