b1b2ffd477898932ea1b514119c6480810aa43db
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / effects / SkLumaColorFilter.cpp
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/GrGLProcessor.h"
15 #include "gl/builders/GrGLProgramBuilder.h"
16 #include "GrContext.h"
17 #include "GrTBackendProcessorFactory.h"
18 #endif
19
20 void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
21                                    SkPMColor dst[]) const {
22     for (int i = 0; i < count; ++i) {
23         SkPMColor c = src[i];
24
25         /*
26          * While LuminanceToAlpha is defined to operate on un-premultiplied
27          * inputs, due to the final alpha scaling it can be computed based on
28          * premultipled components:
29          *
30          *   LumA = (k1 * r / a + k2 * g / a + k3 * b / a) * a
31          *   LumA = (k1 * r + k2 * g + k3 * b)
32          */
33         unsigned luma = SkComputeLuminance(SkGetPackedR32(c),
34                                            SkGetPackedG32(c),
35                                            SkGetPackedB32(c));
36         dst[i] = SkPackARGB32(luma, 0, 0, 0);
37     }
38 }
39
40 SkColorFilter* SkLumaColorFilter::Create() {
41     return SkNEW(SkLumaColorFilter);
42 }
43
44 SkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
45
46 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
47 SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
48 #endif
49
50 SkFlattenable* SkLumaColorFilter::CreateProc(SkReadBuffer&) {
51     return SkNEW(SkLumaColorFilter);
52 }
53
54 void SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
55
56 #ifndef SK_IGNORE_TO_STRING
57 void SkLumaColorFilter::toString(SkString* str) const {
58     str->append("SkLumaColorFilter ");
59 }
60 #endif
61
62 #if SK_SUPPORT_GPU
63 class LumaColorFilterEffect : public GrFragmentProcessor {
64 public:
65     static GrFragmentProcessor* Create() {
66         GR_CREATE_STATIC_PROCESSOR(gLumaEffect, LumaColorFilterEffect, ());
67         return SkRef(gLumaEffect);
68     }
69
70     static const char* Name() { return "Luminance-to-Alpha"; }
71
72     virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
73         return GrTBackendFragmentProcessorFactory<LumaColorFilterEffect>::getInstance();
74     }
75
76     class GLProcessor : public GrGLFragmentProcessor {
77     public:
78         GLProcessor(const GrBackendProcessorFactory& factory,
79                     const GrProcessor&)
80         : INHERITED(factory) {
81         }
82
83         static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {}
84
85         virtual void emitCode(GrGLFPBuilder* builder,
86                               const GrFragmentProcessor&,
87                               const GrProcessorKey&,
88                               const char* outputColor,
89                               const char* inputColor,
90                               const TransformedCoordsArray&,
91                               const TextureSamplerArray&) SK_OVERRIDE {
92             if (NULL == inputColor) {
93                 inputColor = "vec4(1)";
94             }
95
96             GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
97             fsBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
98                                    SK_ITU_BT709_LUM_COEFF_R,
99                                    SK_ITU_BT709_LUM_COEFF_G,
100                                    SK_ITU_BT709_LUM_COEFF_B,
101                                    inputColor);
102             fsBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
103                                    outputColor);
104
105         }
106
107     private:
108         typedef GrGLFragmentProcessor INHERITED;
109     };
110
111 private:
112     virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE { return true; }
113
114     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
115         // The output is always black. The alpha value for the color passed in is arbitrary.
116         inout->setToOther(kRGB_GrColorComponentFlags, GrColorPackRGBA(0, 0, 0, 0),
117                           InvariantOutput::kWill_ReadInput);
118     }
119 };
120
121 GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
122     return LumaColorFilterEffect::Create();
123 }
124 #endif