SkLumaColorFilter.cpp revision 4ca2e6034365ad280ec64473f7f1d72ebd8335e4
16c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/*
26c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Copyright 2013 Google Inc.
36c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org *
46c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
56c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * found in the LICENSE file.
66c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org */
76c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
86c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "SkLumaColorFilter.h"
96c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
106c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "SkColorPriv.h"
116c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "SkString.h"
126c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
136c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#if SK_SUPPORT_GPU
146c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "GrContext.h"
15605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
1664c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
172d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
182d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLProgramBuilder.h"
196c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#endif
206c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
216c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgvoid SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
226c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org                                   SkPMColor dst[]) const {
236c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    for (int i = 0; i < count; ++i) {
246c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org        SkPMColor c = src[i];
256c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
26d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org        /*
27d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         * While LuminanceToAlpha is defined to operate on un-premultiplied
28d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         * inputs, due to the final alpha scaling it can be computed based on
29d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         * premultipled components:
30d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         *
31d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         *   LumA = (k1 * r / a + k2 * g / a + k3 * b / a) * a
32d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         *   LumA = (k1 * r + k2 * g + k3 * b)
33d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org         */
34d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org        unsigned luma = SkComputeLuminance(SkGetPackedR32(c),
35d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org                                           SkGetPackedG32(c),
36d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org                                           SkGetPackedB32(c));
37d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org        dst[i] = SkPackARGB32(luma, 0, 0, 0);
386c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    }
396c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org}
406c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
41385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanarySkColorFilter* SkLumaColorFilter::Create() { return new SkLumaColorFilter; }
426c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
446c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
45385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanarySkFlattenable* SkLumaColorFilter::CreateProc(SkReadBuffer&) { return new SkLumaColorFilter; }
466c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
479fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedvoid SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
490f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
506c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgvoid SkLumaColorFilter::toString(SkString* str) const {
516c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    str->append("SkLumaColorFilter ");
526c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org}
536c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#endif
546c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
556c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#if SK_SUPPORT_GPU
56b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass LumaColorFilterEffect : public GrFragmentProcessor {
576c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgpublic:
58e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon    static const GrFragmentProcessor* Create() {
5902141734f2f89fa4e89ba804bc06fa80ed0fc316bsalomon        return new LumaColorFilterEffect;
606c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    }
616c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
6236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Luminance-to-Alpha"; }
636c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
6457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    class GLSLProcessor : public GrGLSLFragmentProcessor {
656c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    public:
6657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        GLSLProcessor(const GrProcessor&) {}
676c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
68cfc18867d982119d9dc2888bf09f1093012daaddjvanverth        static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b) {}
696c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
707c157a988845fb00f9024d6db6dda142c3458033wangyix        virtual void emitCode(EmitArgs& args) override {
7196fcdcc219d2a0d3579719b84b28bede76efba64halcanary            if (nullptr == args.fInputColor) {
727c157a988845fb00f9024d6db6dda142c3458033wangyix                args.fInputColor = "vec4(1)";
736c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org            }
746c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
754ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
764ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            fragBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
774ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_R,
784ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_G,
794ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_B,
804ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     args.fInputColor);
814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            fragBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
824ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     args.fOutputColor);
836c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
846c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org        }
856c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
866c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    private:
8764c4728c70001ed074fecf5c4e083781987b12e9egdaniel        typedef GrGLSLFragmentProcessor INHERITED;
886c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    };
896c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
906c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgprivate:
91eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    LumaColorFilterEffect() {
92eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<LumaColorFilterEffect>();
93eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
94eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
9557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
9657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        return new GLSLProcessor(*this);
9757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    }
98b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
9957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
10057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                       GrProcessorKeyBuilder* b) const override {
10157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        GLSLProcessor::GenKey(*this, caps, b);
1024b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix    }
1034b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
10436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
1051a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel
10636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
107ccb2e384a036f29d989d3c1468f879324e81a678egdaniel        // The output is always black. The alpha value for the color passed in is arbitrary.
1089e4d6d180fcfbbe2ea242196cc0affd45b7ed7aeegdaniel        inout->setToOther(kRGB_GrColorComponentFlags, GrColorPackRGBA(0, 0, 0, 0),
109605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel                          GrInvariantOutput::kWill_ReadInput);
1101a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel    }
1116c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org};
1126c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
1134a339529612a43871d021877e58698e067d6c4cdbsalomonconst GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
114cff10b21a9934afc540d121b493b204335829589reed
115e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon    return LumaColorFilterEffect::Create();
1166c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org}
1176c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#endif
118