| 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 "GrConfigConversionEffect.h" | 8 #include "GrConfigConversionEffect.h" | 
| 9 #include "GrContext.h" | 9 #include "GrContext.h" | 
| 10 #include "GrTBackendEffectFactory.h" | 10 #include "GrTBackendEffectFactory.h" | 
| 11 #include "GrSimpleTextureEffect.h" | 11 #include "GrSimpleTextureEffect.h" | 
| 12 #include "gl/GrGLEffect.h" | 12 #include "gl/GrGLEffect.h" | 
| 13 #include "gl/GrGLShaderBuilder.h" | 13 #include "gl/builders/GrGLProgramBuilder.h" | 
| 14 #include "SkMatrix.h" | 14 #include "SkMatrix.h" | 
| 15 | 15 | 
| 16 class GrGLConfigConversionEffect : public GrGLEffect { | 16 class GrGLConfigConversionEffect : public GrGLEffect { | 
| 17 public: | 17 public: | 
| 18     GrGLConfigConversionEffect(const GrBackendEffectFactory& factory, | 18     GrGLConfigConversionEffect(const GrBackendEffectFactory& factory, | 
| 19                                const GrDrawEffect& drawEffect) | 19                                const GrDrawEffect& drawEffect) | 
| 20     : INHERITED (factory) { | 20     : INHERITED (factory) { | 
| 21         const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigC
     onversionEffect>(); | 21         const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigC
     onversionEffect>(); | 
| 22         fSwapRedAndBlue = effect.swapsRedAndBlue(); | 22         fSwapRedAndBlue = effect.swapsRedAndBlue(); | 
| 23         fPMConversion = effect.pmConversion(); | 23         fPMConversion = effect.pmConversion(); | 
| 24     } | 24     } | 
| 25 | 25 | 
| 26     virtual void emitCode(GrGLShaderBuilder* builder, | 26     virtual void emitCode(GrGLProgramBuilder* builder, | 
| 27                           const GrDrawEffect&, | 27                           const GrDrawEffect&, | 
| 28                           const GrEffectKey& key, | 28                           const GrEffectKey& key, | 
| 29                           const char* outputColor, | 29                           const char* outputColor, | 
| 30                           const char* inputColor, | 30                           const char* inputColor, | 
| 31                           const TransformedCoordsArray& coords, | 31                           const TransformedCoordsArray& coords, | 
| 32                           const TextureSamplerArray& samplers) SK_OVERRIDE { | 32                           const TextureSamplerArray& samplers) SK_OVERRIDE { | 
| 33         // Using highp for GLES here in order to avoid some precision issues on 
     specific GPUs. | 33         // Using highp for GLES here in order to avoid some precision issues on 
     specific GPUs. | 
| 34         GrGLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, GrGLShaderVar::kHig
     h_Precision); | 34         GrGLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, GrGLShaderVar::kHig
     h_Precision); | 
| 35         SkString tmpDecl; | 35         SkString tmpDecl; | 
| 36         tmpVar.appendDecl(builder->ctxInfo(), &tmpDecl); | 36         tmpVar.appendDecl(builder->ctxInfo(), &tmpDecl); | 
| 37         builder->fsCodeAppendf("%s;", tmpDecl.c_str()); |  | 
| 38 | 37 | 
| 39         builder->fsCodeAppendf("%s = ", tmpVar.c_str()); | 38         GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder
     (); | 
| 40         builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0]
     .type()); | 39 | 
| 41         builder->fsCodeAppend(";"); | 40         fsBuilder->codeAppendf("%s;", tmpDecl.c_str()); | 
|  | 41 | 
|  | 42         fsBuilder->codeAppendf("%s = ", tmpVar.c_str()); | 
|  | 43         fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0]
     .type()); | 
|  | 44         fsBuilder->codeAppend(";"); | 
| 42 | 45 | 
| 43         if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) { | 46         if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) { | 
| 44             SkASSERT(fSwapRedAndBlue); | 47             SkASSERT(fSwapRedAndBlue); | 
| 45             builder->fsCodeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str())
     ; | 48             fsBuilder->codeAppendf("%s = %s.bgra;", outputColor, tmpVar.c_str())
     ; | 
| 46         } else { | 49         } else { | 
| 47             const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb"; | 50             const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb"; | 
| 48             switch (fPMConversion) { | 51             switch (fPMConversion) { | 
| 49                 case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: | 52                 case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: | 
| 50                     builder->fsCodeAppendf( | 53                     fsBuilder->codeAppendf( | 
| 51                         "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);", | 54                         "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);", | 
| 52                         tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm
     pVar.c_str()); | 55                         tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm
     pVar.c_str()); | 
| 53                     break; | 56                     break; | 
| 54                 case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversio
     n: | 57                 case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversio
     n: | 
| 55                     // Add a compensation(0.001) here to avoid the side effect o
     f the floor operation. | 58                     // Add a compensation(0.001) here to avoid the side effect o
     f the floor operation. | 
| 56                     // In Intel GPUs, the integer value converted from floor(%s.
     r * 255.0) / 255.0 | 59                     // In Intel GPUs, the integer value converted from floor(%s.
     r * 255.0) / 255.0 | 
| 57                     // is less than the integer value converted from  %s.r by 1 
     when the %s.r is | 60                     // is less than the integer value converted from  %s.r by 1 
     when the %s.r is | 
| 58                     // converted from the integer value 2^n, such as 1, 2, 4, 8,
      etc. | 61                     // converted from the integer value 2^n, such as 1, 2, 4, 8,
      etc. | 
| 59                     builder->fsCodeAppendf( | 62                     fsBuilder->codeAppendf( | 
| 60                         "%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, 
     %s.a);", | 63                         "%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, 
     %s.a);", | 
| 61                         tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm
     pVar.c_str()); | 64                         tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm
     pVar.c_str()); | 
| 62                     break; | 65                     break; | 
| 63                 case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: | 66                 case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: | 
| 64                     builder->fsCodeAppendf( | 67                     fsBuilder->codeAppendf( | 
| 65                         "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s
     .a * 255.0) / 255.0, %s.a);", | 68                         "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s
     .a * 255.0) / 255.0, %s.a);", | 
| 66                         tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm
     pVar.c_str(), tmpVar.c_str()); | 69                         tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm
     pVar.c_str(), tmpVar.c_str()); | 
| 67                     break; | 70                     break; | 
| 68                 case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversio
     n: | 71                 case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversio
     n: | 
| 69                     builder->fsCodeAppendf( | 72                     fsBuilder->codeAppendf( | 
| 70                         "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %
     s.a * 255.0) / 255.0, %s.a);", | 73                         "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %
     s.a * 255.0) / 255.0, %s.a);", | 
| 71                         tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm
     pVar.c_str(), tmpVar.c_str()); | 74                         tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm
     pVar.c_str(), tmpVar.c_str()); | 
| 72                     break; | 75                     break; | 
| 73                 default: | 76                 default: | 
| 74                     SkFAIL("Unknown conversion op."); | 77                     SkFAIL("Unknown conversion op."); | 
| 75                     break; | 78                     break; | 
| 76             } | 79             } | 
| 77             builder->fsCodeAppendf("%s = %s;", outputColor, tmpVar.c_str()); | 80             fsBuilder->codeAppendf("%s = %s;", outputColor, tmpVar.c_str()); | 
| 78         } | 81         } | 
| 79         SkString modulate; | 82         SkString modulate; | 
| 80         GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); | 83         GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); | 
| 81         builder->fsCodeAppend(modulate.c_str()); | 84         fsBuilder->codeAppend(modulate.c_str()); | 
| 82     } | 85     } | 
| 83 | 86 | 
| 84     static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, | 87     static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, | 
| 85                               GrEffectKeyBuilder* b) { | 88                               GrEffectKeyBuilder* b) { | 
| 86         const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigCon
     versionEffect>(); | 89         const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigCon
     versionEffect>(); | 
| 87         uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() <
     < 1); | 90         uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() <
     < 1); | 
| 88         b->add32(key); | 91         b->add32(key); | 
| 89     } | 92     } | 
| 90 | 93 | 
| 91 private: | 94 private: | 
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 275             kNone_PMConversion != pmConversion) { | 278             kNone_PMConversion != pmConversion) { | 
| 276             // The PM conversions assume colors are 0..255 | 279             // The PM conversions assume colors are 0..255 | 
| 277             return NULL; | 280             return NULL; | 
| 278         } | 281         } | 
| 279         return SkNEW_ARGS(GrConfigConversionEffect, (texture, | 282         return SkNEW_ARGS(GrConfigConversionEffect, (texture, | 
| 280                                                      swapRedAndBlue, | 283                                                      swapRedAndBlue, | 
| 281                                                      pmConversion, | 284                                                      pmConversion, | 
| 282                                                      matrix)); | 285                                                      matrix)); | 
| 283     } | 286     } | 
| 284 } | 287 } | 
| OLD | NEW | 
|---|