| 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 "gl/builders/GrGLProgramBuilder.h" |
| 8 #include "GrTextureDomain.h" | 9 #include "GrTextureDomain.h" |
| 9 #include "GrSimpleTextureEffect.h" | 10 #include "GrSimpleTextureEffect.h" |
| 10 #include "GrTBackendEffectFactory.h" | 11 #include "GrTBackendEffectFactory.h" |
| 11 #include "gl/GrGLEffect.h" | 12 #include "gl/GrGLEffect.h" |
| 12 #include "gl/GrGLShaderBuilder.h" | |
| 13 #include "SkFloatingPoint.h" | 13 #include "SkFloatingPoint.h" |
| 14 | 14 |
| 15 | 15 |
| 16 GrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index) | 16 GrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index) |
| 17 : fIndex(index) { | 17 : fIndex(index) { |
| 18 | 18 |
| 19 static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; | 19 static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; |
| 20 if (domain.contains(kFullRect) && kClamp_Mode == mode) { | 20 if (domain.contains(kFullRect) && kClamp_Mode == mode) { |
| 21 fMode = kIgnore_Mode; | 21 fMode = kIgnore_Mode; |
| 22 } else { | 22 } else { |
| (...skipping 19 matching lines...) Expand all 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 GrGLProgramBuilder* program = builder->getProgramBuilder(); |
| 53 |
| 52 if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) { | 54 if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) { |
| 53 const char* name; | 55 const char* name; |
| 54 SkString uniName("TexDom"); | 56 SkString uniName("TexDom"); |
| 55 if (textureDomain.fIndex >= 0) { | 57 if (textureDomain.fIndex >= 0) { |
| 56 uniName.appendS32(textureDomain.fIndex); | 58 uniName.appendS32(textureDomain.fIndex); |
| 57 } | 59 } |
| 58 fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility
, | 60 fDomainUni = program->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, kVec4f_GrSLType, |
| 59 kVec4f_GrSLType, uniName.c_str(), &name
); | 61 uniName.c_str(), &name); |
| 60 fDomainName = name; | 62 fDomainName = name; |
| 61 } | 63 } |
| 62 | 64 |
| 63 switch (textureDomain.mode()) { | 65 switch (textureDomain.mode()) { |
| 64 case kIgnore_Mode: { | 66 case kIgnore_Mode: { |
| 65 builder->fsCodeAppendf("\t%s = ", outColor); | 67 builder->codeAppendf("\t%s = ", outColor); |
| 66 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, | 68 builder->appendTextureLookupAndModulate(inModulateColor, sampler, |
| 67 inCoords.c_str()); | 69 inCoords.c_str()); |
| 68 builder->fsCodeAppend(";\n"); | 70 builder->codeAppend(";\n"); |
| 69 break; | 71 break; |
| 70 } | 72 } |
| 71 case kClamp_Mode: { | 73 case kClamp_Mode: { |
| 72 SkString clampedCoords; | 74 SkString clampedCoords; |
| 73 clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)", | 75 clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)", |
| 74 inCoords.c_str(), fDomainName.c_str(), fDomain
Name.c_str()); | 76 inCoords.c_str(), fDomainName.c_str(), fDomain
Name.c_str()); |
| 75 | 77 |
| 76 builder->fsCodeAppendf("\t%s = ", outColor); | 78 builder->codeAppendf("\t%s = ", outColor); |
| 77 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, | 79 builder->appendTextureLookupAndModulate(inModulateColor, sampler, |
| 78 clampedCoords.c_str()); | 80 clampedCoords.c_str()); |
| 79 builder->fsCodeAppend(";\n"); | 81 builder->codeAppend(";\n"); |
| 80 break; | 82 break; |
| 81 } | 83 } |
| 82 case kDecal_Mode: { | 84 case kDecal_Mode: { |
| 83 // Add a block since we're going to declare variables. | 85 // Add a block since we're going to declare variables. |
| 84 GrGLShaderBuilder::FSBlock block(builder); | 86 GrGLShaderBuilder::ShaderBlock block(builder); |
| 85 | 87 |
| 86 const char* domain = fDomainName.c_str(); | 88 const char* domain = fDomainName.c_str(); |
| 87 if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) { | 89 if (kImagination_GrGLVendor == program->ctxInfo().vendor()) { |
| 88 // On the NexusS and GalaxyNexus, the other path (with the 'any' | 90 // On the NexusS and GalaxyNexus, the other path (with the 'any' |
| 89 // call) causes the compilation error "Calls to any function tha
t | 91 // call) causes the compilation error "Calls to any function tha
t |
| 90 // may require a gradient calculation inside a conditional block | 92 // may require a gradient calculation inside a conditional block |
| 91 // may return undefined results". This appears to be an issue wi
th | 93 // may return undefined results". This appears to be an issue wi
th |
| 92 // the 'any' call since even the simple "result=black; if (any()
) | 94 // the 'any' call since even the simple "result=black; if (any()
) |
| 93 // result=white;" code fails to compile. | 95 // result=white;" code fails to compile. |
| 94 builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0)
;\n"); | 96 builder->codeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\
n"); |
| 95 builder->fsCodeAppend("\tvec4 inside = "); | 97 builder->codeAppend("\tvec4 inside = "); |
| 96 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampl
er, | 98 builder->appendTextureLookupAndModulate(inModulateColor, sampler
, |
| 97 inCoords.c_str()); | 99 inCoords.c_str()); |
| 98 builder->fsCodeAppend(";\n"); | 100 builder->codeAppend(";\n"); |
| 99 builder->fsCodeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str()
); | 101 builder->codeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str()); |
| 100 builder->fsCodeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str()
); | 102 builder->codeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str()); |
| 101 | 103 |
| 102 builder->fsCodeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) -
1.0);\n", | 104 builder->codeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1
.0);\n", |
| 103 domain, domain, domain); | 105 domain, domain, domain); |
| 104 builder->fsCodeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) -
1.0);\n", | 106 builder->codeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1
.0);\n", |
| 105 domain, domain, domain); | 107 domain, domain, domain); |
| 106 builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n")
; | 108 builder->codeAppend("\tfloat blend = step(1.0, max(x, y));\n"); |
| 107 builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n",
outColor); | 109 builder->codeAppendf("\t%s = mix(inside, outside, blend);\n", ou
tColor); |
| 108 } else { | 110 } else { |
| 109 builder->fsCodeAppend("\tbvec4 outside;\n"); | 111 builder->codeAppend("\tbvec4 outside;\n"); |
| 110 builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n",
inCoords.c_str(), | 112 builder->codeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", in
Coords.c_str(), |
| 111 domain); | 113 domain); |
| 112 builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n
", inCoords.c_str(), | 114 builder->codeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n",
inCoords.c_str(), |
| 113 domain); | 115 domain); |
| 114 builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0
, 0.0) : ", | 116 builder->codeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0,
0.0) : ", |
| 115 outColor); | 117 outColor); |
| 116 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampl
er, | 118 builder->appendTextureLookupAndModulate(inModulateColor, sampler
, |
| 117 inCoords.c_str()); | 119 inCoords.c_str()); |
| 118 builder->fsCodeAppend(";\n"); | 120 builder->codeAppend(";\n"); |
| 119 } | 121 } |
| 120 break; | 122 break; |
| 121 } | 123 } |
| 122 case kRepeat_Mode: { | 124 case kRepeat_Mode: { |
| 123 SkString clampedCoords; | 125 SkString clampedCoords; |
| 124 clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", | 126 clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", |
| 125 inCoords.c_str(), fDomainName.c_str(), fDomainN
ame.c_str(), | 127 inCoords.c_str(), fDomainName.c_str(), fDomainN
ame.c_str(), |
| 126 fDomainName.c_str(), fDomainName.c_str()); | 128 fDomainName.c_str(), fDomainName.c_str()); |
| 127 | 129 |
| 128 builder->fsCodeAppendf("\t%s = ", outColor); | 130 builder->codeAppendf("\t%s = ", outColor); |
| 129 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, | 131 builder->appendTextureLookupAndModulate(inModulateColor, sampler, |
| 130 clampedCoords.c_str()); | 132 clampedCoords.c_str()); |
| 131 builder->fsCodeAppend(";\n"); | 133 builder->codeAppend(";\n"); |
| 132 break; | 134 break; |
| 133 } | 135 } |
| 134 } | 136 } |
| 135 } | 137 } |
| 136 | 138 |
| 137 void GrTextureDomain::GLDomain::setData(const GrGLProgramDataManager& pdman, | 139 void GrTextureDomain::GLDomain::setData(const GrGLProgramDataManager& pdman, |
| 138 const GrTextureDomain& textureDomain, | 140 const GrTextureDomain& textureDomain, |
| 139 GrSurfaceOrigin textureOrigin) { | 141 GrSurfaceOrigin textureOrigin) { |
| 140 SkASSERT(textureDomain.mode() == fMode); | 142 SkASSERT(textureDomain.mode() == fMode); |
| 141 if (kIgnore_Mode != textureDomain.mode()) { | 143 if (kIgnore_Mode != textureDomain.mode()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 160 } | 162 } |
| 161 } | 163 } |
| 162 | 164 |
| 163 | 165 |
| 164 ////////////////////////////////////////////////////////////////////////////// | 166 ////////////////////////////////////////////////////////////////////////////// |
| 165 | 167 |
| 166 class GrGLTextureDomainEffect : public GrGLEffect { | 168 class GrGLTextureDomainEffect : public GrGLEffect { |
| 167 public: | 169 public: |
| 168 GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 170 GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| 169 | 171 |
| 170 virtual void emitCode(GrGLShaderBuilder*, | 172 virtual void emitCode(GrGLProgramBuilder*, |
| 171 const GrDrawEffect&, | 173 const GrDrawEffect&, |
| 172 const GrEffectKey&, | 174 const GrEffectKey&, |
| 173 const char* outputColor, | 175 const char* outputColor, |
| 174 const char* inputColor, | 176 const char* inputColor, |
| 175 const TransformedCoordsArray&, | 177 const TransformedCoordsArray&, |
| 176 const TextureSamplerArray&) SK_OVERRIDE; | 178 const TextureSamplerArray&) SK_OVERRIDE; |
| 177 | 179 |
| 178 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_
OVERRIDE; | 180 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_
OVERRIDE; |
| 179 | 181 |
| 180 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB
uilder*); | 182 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB
uilder*); |
| 181 | 183 |
| 182 private: | 184 private: |
| 183 GrTextureDomain::GLDomain fGLDomain; | 185 GrTextureDomain::GLDomain fGLDomain; |
| 184 typedef GrGLEffect INHERITED; | 186 typedef GrGLEffect INHERITED; |
| 185 }; | 187 }; |
| 186 | 188 |
| 187 GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& f
actory, | 189 GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& f
actory, |
| 188 const GrDrawEffect&) | 190 const GrDrawEffect&) |
| 189 : INHERITED(factory) { | 191 : INHERITED(factory) { |
| 190 } | 192 } |
| 191 | 193 |
| 192 void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder, | 194 void GrGLTextureDomainEffect::emitCode(GrGLProgramBuilder* builder, |
| 193 const GrDrawEffect& drawEffect, | 195 const GrDrawEffect& drawEffect, |
| 194 const GrEffectKey& key, | 196 const GrEffectKey& key, |
| 195 const char* outputColor, | 197 const char* outputColor, |
| 196 const char* inputColor, | 198 const char* inputColor, |
| 197 const TransformedCoordsArray& coords, | 199 const TransformedCoordsArray& coords, |
| 198 const TextureSamplerArray& samplers) { | 200 const TextureSamplerArray& samplers) { |
| 199 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainE
ffect>(); | 201 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainE
ffect>(); |
| 200 const GrTextureDomain& domain = effect.textureDomain(); | 202 const GrTextureDomain& domain = effect.textureDomain(); |
| 201 | 203 |
| 202 SkString coords2D = builder->ensureFSCoords2D(coords, 0); | 204 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| 203 fGLDomain.sampleTexture(builder, domain, outputColor, coords2D, samplers[0],
inputColor); | 205 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); |
| 206 fGLDomain.sampleTexture(fsBuilder, domain, outputColor, coords2D, samplers[0
], inputColor); |
| 204 } | 207 } |
| 205 | 208 |
| 206 void GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman, | 209 void GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman, |
| 207 const GrDrawEffect& drawEffect) { | 210 const GrDrawEffect& drawEffect) { |
| 208 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainE
ffect>(); | 211 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainE
ffect>(); |
| 209 const GrTextureDomain& domain = effect.textureDomain(); | 212 const GrTextureDomain& domain = effect.textureDomain(); |
| 210 fGLDomain.setData(pdman, domain, effect.texture(0)->origin()); | 213 fGLDomain.setData(pdman, domain, effect.texture(0)->origin()); |
| 211 } | 214 } |
| 212 | 215 |
| 213 void GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLC
aps&, | 216 void GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLC
aps&, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); | 297 const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); |
| 295 bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : f
alse; | 298 bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : f
alse; |
| 296 GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoo
rdSet; | 299 GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoo
rdSet; |
| 297 return GrTextureDomainEffect::Create(textures[texIdx], | 300 return GrTextureDomainEffect::Create(textures[texIdx], |
| 298 matrix, | 301 matrix, |
| 299 domain, | 302 domain, |
| 300 mode, | 303 mode, |
| 301 bilerp ? GrTextureParams::kBilerp_Filte
rMode : GrTextureParams::kNone_FilterMode, | 304 bilerp ? GrTextureParams::kBilerp_Filte
rMode : GrTextureParams::kNone_FilterMode, |
| 302 coords); | 305 coords); |
| 303 } | 306 } |
| OLD | NEW |