Home | History | Annotate | Download | only in effects
      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