2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkLumaColorFilter.h"
10 #include "SkColorPriv.h"
14 #include "gl/GrGLProcessor.h"
15 #include "gl/builders/GrGLProgramBuilder.h"
16 #include "GrContext.h"
17 #include "GrTBackendProcessorFactory.h"
20 void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
21 SkPMColor dst[]) const {
22 for (int i = 0; i < count; ++i) {
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:
30 * LumA = (k1 * r / a + k2 * g / a + k3 * b / a) * a
31 * LumA = (k1 * r + k2 * g + k3 * b)
33 unsigned luma = SkComputeLuminance(SkGetPackedR32(c),
36 dst[i] = SkPackARGB32(luma, 0, 0, 0);
40 SkColorFilter* SkLumaColorFilter::Create() {
41 return SkNEW(SkLumaColorFilter);
44 SkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
46 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
47 SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
50 SkFlattenable* SkLumaColorFilter::CreateProc(SkReadBuffer&) {
51 return SkNEW(SkLumaColorFilter);
54 void SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
56 #ifndef SK_IGNORE_TO_STRING
57 void SkLumaColorFilter::toString(SkString* str) const {
58 str->append("SkLumaColorFilter ");
63 class LumaColorFilterEffect : public GrFragmentProcessor {
65 static GrFragmentProcessor* Create() {
66 GR_CREATE_STATIC_PROCESSOR(gLumaEffect, LumaColorFilterEffect, ());
67 return SkRef(gLumaEffect);
70 static const char* Name() { return "Luminance-to-Alpha"; }
72 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
73 return GrTBackendFragmentProcessorFactory<LumaColorFilterEffect>::getInstance();
76 class GLProcessor : public GrGLFragmentProcessor {
78 GLProcessor(const GrBackendProcessorFactory& factory,
80 : INHERITED(factory) {
83 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b) {}
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)";
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,
102 fsBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
108 typedef GrGLFragmentProcessor INHERITED;
112 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE { return true; }
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);
121 GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
122 return LumaColorFilterEffect::Create();