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 "GrTextureDomain.h" | 8 #include "GrTextureDomain.h" |
9 #include "GrSimpleTextureEffect.h" | 9 #include "GrSimpleTextureEffect.h" |
10 #include "GrTBackendEffectFactory.h" | 10 #include "GrTBackendEffectFactory.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder, | 43 void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder, |
44 const GrTextureDomain& textureDoma
in, | 44 const GrTextureDomain& textureDoma
in, |
45 const char* outColor, | 45 const char* outColor, |
46 const SkString& inCoords, | 46 const SkString& inCoords, |
47 const GrGLEffect::TextureSampler s
ampler, | 47 const GrGLEffect::TextureSampler s
ampler, |
48 const char* inModulateColor) { | 48 const char* inModulateColor) { |
49 SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode); | 49 SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode); |
50 SkDEBUGCODE(fMode = textureDomain.mode();) | 50 SkDEBUGCODE(fMode = textureDomain.mode();) |
51 | 51 |
52 if (kIgnore_Mode == textureDomain.mode()) { | 52 if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) { |
53 builder->fsCodeAppendf("\t%s = ", outColor); | |
54 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, | |
55 inCoords.c_str()); | |
56 builder->fsCodeAppend(";\n"); | |
57 return; | |
58 } | |
59 | |
60 if (!fDomainUni.isValid()) { | |
61 const char* name; | 53 const char* name; |
62 SkString uniName("TexDom"); | 54 SkString uniName("TexDom"); |
63 if (textureDomain.fIndex >= 0) { | 55 if (textureDomain.fIndex >= 0) { |
64 uniName.appendS32(textureDomain.fIndex); | 56 uniName.appendS32(textureDomain.fIndex); |
65 } | 57 } |
66 fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility
, | 58 fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility
, |
67 kVec4f_GrSLType, uniName.c_str(), &n
ame); | 59 kVec4f_GrSLType, uniName.c_str(), &name
); |
68 fDomainName = name; | 60 fDomainName = name; |
69 } | 61 } |
70 if (kClamp_Mode == textureDomain.mode()) { | |
71 SkString clampedCoords; | |
72 clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)", | |
73 inCoords.c_str(), fDomainName.c_str(), fDomainNa
me.c_str()); | |
74 | 62 |
75 builder->fsCodeAppendf("\t%s = ", outColor); | 63 switch (textureDomain.mode()) { |
76 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, clam
pedCoords.c_str()); | 64 case kIgnore_Mode: { |
77 builder->fsCodeAppend(";\n"); | 65 builder->fsCodeAppendf("\t%s = ", outColor); |
78 } else { | 66 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, |
79 SkASSERT(GrTextureDomain::kDecal_Mode == textureDomain.mode()); | 67 inCoords.c_str()); |
80 // Add a block since we're going to declare variables. | 68 builder->fsCodeAppend(";\n"); |
81 GrGLShaderBuilder::FSBlock block(builder); | 69 break; |
| 70 } |
| 71 case kClamp_Mode: { |
| 72 SkString clampedCoords; |
| 73 clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)", |
| 74 inCoords.c_str(), fDomainName.c_str(), fDomain
Name.c_str()); |
82 | 75 |
83 const char* domain = fDomainName.c_str(); | 76 builder->fsCodeAppendf("\t%s = ", outColor); |
84 if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) { | 77 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, |
85 // On the NexusS and GalaxyNexus, the other path (with the 'any' | 78 clampedCoords.c_str()); |
86 // call) causes the compilation error "Calls to any function that | |
87 // may require a gradient calculation inside a conditional block | |
88 // may return undefined results". This appears to be an issue with | |
89 // the 'any' call since even the simple "result=black; if (any()) | |
90 // result=white;" code fails to compile. | |
91 builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n"
); | |
92 builder->fsCodeAppend("\tvec4 inside = "); | |
93 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
inCoords.c_str()); | |
94 builder->fsCodeAppend(";\n"); | 79 builder->fsCodeAppend(";\n"); |
| 80 break; |
| 81 } |
| 82 case kDecal_Mode: { |
| 83 // Add a block since we're going to declare variables. |
| 84 GrGLShaderBuilder::FSBlock block(builder); |
95 | 85 |
96 builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s
.x) - 1.0);\n", | 86 const char* domain = fDomainName.c_str(); |
97 inCoords.c_str(), domain, domain, domain); | 87 if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) { |
98 builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s
.y) - 1.0);\n", | 88 // On the NexusS and GalaxyNexus, the other path (with the 'any' |
99 inCoords.c_str(), domain, domain, domain); | 89 // call) causes the compilation error "Calls to any function tha
t |
100 builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n"); | 90 // may require a gradient calculation inside a conditional block |
101 builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outC
olor); | 91 // may return undefined results". This appears to be an issue wi
th |
102 } else { | 92 // the 'any' call since even the simple "result=black; if (any()
) |
103 builder->fsCodeAppend("\tbvec4 outside;\n"); | 93 // result=white;" code fails to compile. |
104 builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCo
ords.c_str(), | 94 builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0)
;\n"); |
105 domain); | 95 builder->fsCodeAppend("\tvec4 inside = "); |
106 builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", i
nCoords.c_str(), | 96 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampl
er, |
107 domain); | 97 inCoords.c_str()); |
108 builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.
0) : ", outColor); | 98 builder->fsCodeAppend(";\n"); |
109 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
inCoords.c_str()); | 99 |
| 100 builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z
- %s.x) - 1.0);\n", |
| 101 inCoords.c_str(), domain, domain, domain
); |
| 102 builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w
- %s.y) - 1.0);\n", |
| 103 inCoords.c_str(), domain, domain, domain
); |
| 104 builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n")
; |
| 105 builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n",
outColor); |
| 106 } else { |
| 107 builder->fsCodeAppend("\tbvec4 outside;\n"); |
| 108 builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n",
inCoords.c_str(), |
| 109 domain); |
| 110 builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n
", inCoords.c_str(), |
| 111 domain); |
| 112 builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0
, 0.0) : ", |
| 113 outColor); |
| 114 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampl
er, |
| 115 inCoords.c_str()); |
| 116 builder->fsCodeAppend(";\n"); |
| 117 } |
| 118 break; |
| 119 } |
| 120 case kRepeat_Mode: { |
| 121 SkString clampedCoords; |
| 122 clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", |
| 123 inCoords.c_str(), fDomainName.c_str(), fDomainN
ame.c_str(), |
| 124 fDomainName.c_str(), fDomainName.c_str()); |
| 125 |
| 126 builder->fsCodeAppendf("\t%s = ", outColor); |
| 127 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, |
| 128 clampedCoords.c_str()); |
110 builder->fsCodeAppend(";\n"); | 129 builder->fsCodeAppend(";\n"); |
| 130 break; |
111 } | 131 } |
112 } | 132 } |
113 } | 133 } |
114 | 134 |
115 void GrTextureDomain::GLDomain::setData(const GrGLUniformManager& uman, | 135 void GrTextureDomain::GLDomain::setData(const GrGLUniformManager& uman, |
116 const GrTextureDomain& textureDomain, | 136 const GrTextureDomain& textureDomain, |
117 GrSurfaceOrigin textureOrigin) { | 137 GrSurfaceOrigin textureOrigin) { |
118 SkASSERT(textureDomain.mode() == fMode); | 138 SkASSERT(textureDomain.mode() == fMode); |
119 if (kIgnore_Mode != textureDomain.mode()) { | 139 if (kIgnore_Mode != textureDomain.mode()) { |
120 GrGLfloat values[4] = { | 140 GrGLfloat values[4] = { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 } | 239 } |
220 | 240 |
221 GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, | 241 GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, |
222 const SkMatrix& matrix, | 242 const SkMatrix& matrix, |
223 const SkRect& domain, | 243 const SkRect& domain, |
224 GrTextureDomain::Mode mode, | 244 GrTextureDomain::Mode mode, |
225 GrTextureParams::FilterMode filterM
ode, | 245 GrTextureParams::FilterMode filterM
ode, |
226 GrCoordSet coordSet) | 246 GrCoordSet coordSet) |
227 : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) | 247 : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) |
228 , fTextureDomain(domain, mode) { | 248 , fTextureDomain(domain, mode) { |
| 249 SkASSERT(mode != GrTextureDomain::kRepeat_Mode || |
| 250 filterMode == GrTextureParams::kNone_FilterMode); |
229 } | 251 } |
230 | 252 |
231 GrTextureDomainEffect::~GrTextureDomainEffect() { | 253 GrTextureDomainEffect::~GrTextureDomainEffect() { |
232 | 254 |
233 } | 255 } |
234 | 256 |
235 const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const { | 257 const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const { |
236 return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance(); | 258 return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance(); |
237 } | 259 } |
238 | 260 |
(...skipping 22 matching lines...) Expand all Loading... |
261 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : | 283 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : |
262 GrEffectUnitTest::kAlphaTextureIdx; | 284 GrEffectUnitTest::kAlphaTextureIdx; |
263 SkRect domain; | 285 SkRect domain; |
264 domain.fLeft = random->nextUScalar1(); | 286 domain.fLeft = random->nextUScalar1(); |
265 domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1); | 287 domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1); |
266 domain.fTop = random->nextUScalar1(); | 288 domain.fTop = random->nextUScalar1(); |
267 domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1); | 289 domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1); |
268 GrTextureDomain::Mode mode = | 290 GrTextureDomain::Mode mode = |
269 (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCoun
t); | 291 (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCoun
t); |
270 const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); | 292 const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); |
271 bool bilerp = random->nextBool(); | 293 bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : f
alse; |
272 GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoo
rdSet; | 294 GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoo
rdSet; |
273 return GrTextureDomainEffect::Create(textures[texIdx], | 295 return GrTextureDomainEffect::Create(textures[texIdx], |
274 matrix, | 296 matrix, |
275 domain, | 297 domain, |
276 mode, | 298 mode, |
277 bilerp ? GrTextureParams::kBilerp_Filte
rMode : GrTextureParams::kNone_FilterMode, | 299 bilerp ? GrTextureParams::kBilerp_Filte
rMode : GrTextureParams::kNone_FilterMode, |
278 coords); | 300 coords); |
279 } | 301 } |
OLD | NEW |