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 19void 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 39SkColorFilter* SkLumaColorFilter::Create() { 40 return SkNEW(SkLumaColorFilter); 41} 42 43SkLumaColorFilter::SkLumaColorFilter() 44 : INHERITED() { 45} 46 47SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) 48 : INHERITED(buffer) { 49} 50 51void SkLumaColorFilter::flatten(SkWriteBuffer&) const { 52} 53 54#ifndef SK_IGNORE_TO_STRING 55void SkLumaColorFilter::toString(SkString* str) const { 56 str->append("SkLumaColorFilter "); 57} 58#endif 59 60#if SK_SUPPORT_GPU 61class LumaColorFilterEffect : public GrEffect { 62public: 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 118private: 119 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { 120 return true; 121 } 122}; 123 124GrEffectRef* SkLumaColorFilter::asNewEffect(GrContext*) const { 125 return LumaColorFilterEffect::Create(); 126} 127#endif 128