1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkLumaColorFilter.h" 9 10 #include "SkColorPriv.h" 11 #include "SkString.h" 12 13 #if SK_SUPPORT_GPU 14 #include "gl/GrGLEffect.h" 15 #include "GrContext.h" 16 #include "GrTBackendEffectFactory.h" 17 #endif 18 19 void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count, 20 SkPMColor dst[]) const { 21 for (int i = 0; i < count; ++i) { 22 SkPMColor c = src[i]; 23 24 /* 25 * While LuminanceToAlpha is defined to operate on un-premultiplied 26 * inputs, due to the final alpha scaling it can be computed based on 27 * premultipled components: 28 * 29 * LumA = (k1 * r / a + k2 * g / a + k3 * b / a) * a 30 * LumA = (k1 * r + k2 * g + k3 * b) 31 */ 32 unsigned luma = SkComputeLuminance(SkGetPackedR32(c), 33 SkGetPackedG32(c), 34 SkGetPackedB32(c)); 35 dst[i] = SkPackARGB32(luma, 0, 0, 0); 36 } 37 } 38 39 SkColorFilter* SkLumaColorFilter::Create() { 40 return SkNEW(SkLumaColorFilter); 41 } 42 43 SkLumaColorFilter::SkLumaColorFilter() 44 : INHERITED() { 45 } 46 47 SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) 48 : INHERITED(buffer) { 49 } 50 51 void SkLumaColorFilter::flatten(SkWriteBuffer&) const { 52 } 53 54 #ifndef SK_IGNORE_TO_STRING 55 void SkLumaColorFilter::toString(SkString* str) const { 56 str->append("SkLumaColorFilter "); 57 } 58 #endif 59 60 #if SK_SUPPORT_GPU 61 class LumaColorFilterEffect : public GrEffect { 62 public: 63 static GrEffectRef* Create() { 64 AutoEffectUnref effect(SkNEW(LumaColorFilterEffect)); 65 return CreateEffectRef(effect); 66 } 67 68 static const char* Name() { return "Luminance-to-Alpha"; } 69 70 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 71 return GrTBackendEffectFactory<LumaColorFilterEffect>::getInstance(); 72 } 73 74 virtual void getConstantColorComponents(GrColor* color, 75 uint32_t* validFlags) const SK_OVERRIDE { 76 // The output is always black. 77 *color = GrColorPackRGBA(0, 0, 0, GrColorUnpackA(*color)); 78 *validFlags = kRGB_GrColorComponentFlags; 79 } 80 81 class GLEffect : public GrGLEffect { 82 public: 83 GLEffect(const GrBackendEffectFactory& factory, 84 const GrDrawEffect&) 85 : INHERITED(factory) { 86 } 87 88 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { 89 // this class always generates the same code. 90 return 0; 91 } 92 93 virtual void emitCode(GrGLShaderBuilder* builder, 94 const GrDrawEffect&, 95 EffectKey, 96 const char* outputColor, 97 const char* inputColor, 98 const TransformedCoordsArray&, 99 const TextureSamplerArray&) SK_OVERRIDE { 100 if (NULL == inputColor) { 101 inputColor = "vec4(1)"; 102 } 103 104 builder->fsCodeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n", 105 SK_ITU_BT709_LUM_COEFF_R, 106 SK_ITU_BT709_LUM_COEFF_G, 107 SK_ITU_BT709_LUM_COEFF_B, 108 inputColor); 109 builder->fsCodeAppendf("\t%s = vec4(0, 0, 0, luma);\n", 110 outputColor); 111 112 } 113 114 private: 115 typedef GrGLEffect INHERITED; 116 }; 117 118 private: 119 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { 120 return true; 121 } 122 }; 123 124 GrEffectRef* SkLumaColorFilter::asNewEffect(GrContext*) const { 125 return LumaColorFilterEffect::Create(); 126 } 127 #endif 128