SkLumaColorFilter.cpp revision ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50
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"
111f49f26353997195030aeab41c8665e1860d2958Mike Klein#include "SkRasterPipeline.h"
126c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "SkString.h"
136c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
146c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#if SK_SUPPORT_GPU
156c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "GrContext.h"
16605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
1764c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
182d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.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
41744908e5e81f81f34288a1b5547aa4ea990ad13dMike Kleinbool SkLumaColorFilter::onAppendStages(SkRasterPipeline* p,
42744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein                                       SkColorSpace* dst,
43ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derby                                       SkArenaAlloc* scratch,
44744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein                                       bool shaderIsOpaque) const {
451f49f26353997195030aeab41c8665e1860d2958Mike Klein    p->append(SkRasterPipeline::luminance_to_alpha);
461f49f26353997195030aeab41c8665e1860d2958Mike Klein    return true;
471f49f26353997195030aeab41c8665e1860d2958Mike Klein}
481f49f26353997195030aeab41c8665e1860d2958Mike Klein
49d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkColorFilter> SkLumaColorFilter::Make() {
50d053ce9c54d4e5937a142278359e5a4cde18095ereed    return sk_sp<SkColorFilter>(new SkLumaColorFilter);
51d053ce9c54d4e5937a142278359e5a4cde18095ereed}
526c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
546c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
5560c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkLumaColorFilter::CreateProc(SkReadBuffer&) {
5660c9b58b3214b0154c931656e91e39b230e987d8reed    return Make();
5760c9b58b3214b0154c931656e91e39b230e987d8reed}
586c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedvoid SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
610f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
626c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgvoid SkLumaColorFilter::toString(SkString* str) const {
636c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    str->append("SkLumaColorFilter ");
646c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org}
656c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#endif
666c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
676c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#if SK_SUPPORT_GPU
68b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass LumaColorFilterEffect : public GrFragmentProcessor {
696c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgpublic:
7006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    static sk_sp<GrFragmentProcessor> Make() {
7106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return sk_sp<GrFragmentProcessor>(new LumaColorFilterEffect);
726c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    }
736c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
7436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Luminance-to-Alpha"; }
756c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
7657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    class GLSLProcessor : public GrGLSLFragmentProcessor {
776c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    public:
7894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {}
796c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
809cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips        void emitCode(EmitArgs& args) override {
8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary            if (nullptr == args.fInputColor) {
827c157a988845fb00f9024d6db6dda142c3458033wangyix                args.fInputColor = "vec4(1)";
836c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org            }
846c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
858528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton            GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
864ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            fragBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
874ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_R,
884ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_G,
894ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     SK_ITU_BT709_LUM_COEFF_B,
904ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     args.fInputColor);
914ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            fragBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
924ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     args.fOutputColor);
936c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
946c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org        }
956c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
966c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    private:
9764c4728c70001ed074fecf5c4e083781987b12e9egdaniel        typedef GrGLSLFragmentProcessor INHERITED;
986c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org    };
996c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
1006c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgprivate:
101eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    LumaColorFilterEffect() {
102eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<LumaColorFilterEffect>();
103eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
104eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
10557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
1069cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips        return new GLSLProcessor;
10757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    }
108b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
10994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
11057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                       GrProcessorKeyBuilder* b) const override {
11157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        GLSLProcessor::GenKey(*this, caps, b);
1124b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix    }
1134b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
11436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
1151a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel
11636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
117ccb2e384a036f29d989d3c1468f879324e81a678egdaniel        // The output is always black. The alpha value for the color passed in is arbitrary.
1189e4d6d180fcfbbe2ea242196cc0affd45b7ed7aeegdaniel        inout->setToOther(kRGB_GrColorComponentFlags, GrColorPackRGBA(0, 0, 0, 0),
119605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel                          GrInvariantOutput::kWill_ReadInput);
1201a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel    }
1216c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org};
1226c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org
123618d304eb394d64779be0ecdc5eff898242faa8fBrian Osmansk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
12406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return LumaColorFilterEffect::Make();
1256c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org}
1266c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#endif
127