1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
8ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derby#include "SkArenaAlloc.h"
94e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkColorFilter.h"
104e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkColorSpaceXformer.h"
114e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkNx.h"
124e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkPM4f.h"
136dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein#include "SkRasterPipeline.h"
148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
15d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkRefCnt.h"
165bd055c0386499f2dc8c66173a7534b75af602bfreed#include "SkString.h"
17d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkTDArray.h"
18d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkUnPreMultiply.h"
19db873d8677a2d4ecfe38a794a5d868301bdeeabereed#include "SkWriteBuffer.h"
206dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein#include "../jumper/SkJumper.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
22e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#if SK_SUPPORT_GPU
23e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#include "GrFragmentProcessor.h"
24e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#endif
25d3ebb48320cf1b7e969974673e4bd7743816985ebungeman
26faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reedbool SkColorFilter::asColorMode(SkColor*, SkBlendMode*) const {
2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    return false;
2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
30bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.combool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
31e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org    return false;
32e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org}
33e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org
34b2ad101313cfba9c06a3a4dc06531766bcbec73bbsalomon@google.combool SkColorFilter::asComponentTable(SkBitmap*) const {
357191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com    return false;
367191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com}
377191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com
3806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#if SK_SUPPORT_GPU
39618d304eb394d64779be0ecdc5eff898242faa8fBrian Osmansk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
4006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return nullptr;
4106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman}
4206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#endif
4306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman
446dfcecad33c949e775a3fd0a58637721ab5e295eMike Kleinvoid SkColorFilter::appendStages(SkRasterPipeline* p,
456dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein                                 SkColorSpace* dstCS,
466dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein                                 SkArenaAlloc* alloc,
47744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein                                 bool shaderIsOpaque) const {
48fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein    this->onAppendStages(p, dstCS, alloc, shaderIsOpaque);
49fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein}
506dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein
51bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.comSkColor SkColorFilter::filterColor(SkColor c) const {
529c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed    const float inv255 = 1.0f / 255;
539c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed    SkColor4f c4 = this->filterColor4f({
549c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed        SkColorGetR(c) * inv255,
559c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed        SkColorGetG(c) * inv255,
569c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed        SkColorGetB(c) * inv255,
579c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed        SkColorGetA(c) * inv255,
589c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed    });
599c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed    return SkColorSetARGB(sk_float_round2int(c4.fA*255),
609c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed                          sk_float_round2int(c4.fR*255),
619c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed                          sk_float_round2int(c4.fG*255),
629c1d7802284bf5a0e6fcf1a43e9218e21ce1a9e0Mike Reed                          sk_float_round2int(c4.fB*255));
636b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com}
646b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com
6525f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed#include "SkRasterPipeline.h"
66f7cdb06d62bd732599c7ee407dfd76d32d671755reedSkColor4f SkColorFilter::filterColor4f(const SkColor4f& c) const {
67f7cdb06d62bd732599c7ee407dfd76d32d671755reed    SkPM4f dst, src = c.premul();
6825f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed
6925f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed    SkSTArenaAlloc<128> alloc;
7025f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed    SkRasterPipeline    pipeline(&alloc);
7125f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed
72c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed    pipeline.append_uniform_color(&alloc, src);
7325f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed    this->onAppendStages(&pipeline, nullptr, &alloc, c.fA == 1);
7425f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed    SkPM4f* dstPtr = &dst;
7525f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed    pipeline.append(SkRasterPipeline::store_f32, &dstPtr);
76761d27c4d76bbd553c10cfe835d572b6fa33cf26Mike Klein    pipeline.run(0,0, 1);
7725f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed
78f7cdb06d62bd732599c7ee407dfd76d32d671755reed    return dst.unpremul();
796d3cef930ad19b0f55543ca40f7a07030f4fe508reed}
806d3cef930ad19b0f55543ca40f7a07030f4fe508reed
81db873d8677a2d4ecfe38a794a5d868301bdeeabereed///////////////////////////////////////////////////////////////////////////////////////////////////
82db873d8677a2d4ecfe38a794a5d868301bdeeabereed
83dc812222a7488d2a0e39b4a09c81c9f000d4b869reed/*
84dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *  Since colorfilters may be used on the GPU backend, and in that case we may string together
85dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *  many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
86dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *
87dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *  Since we don't yet know *what* those limits might be when we construct the final shader,
88dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *  we just set an arbitrary limit during construction. If later we find smarter ways to know what
89dc812222a7488d2a0e39b4a09c81c9f000d4b869reed *  the limnits are, we can change this constant (or remove it).
90dc812222a7488d2a0e39b4a09c81c9f000d4b869reed */
91dc812222a7488d2a0e39b4a09c81c9f000d4b869reed#define SK_MAX_COMPOSE_COLORFILTER_COUNT    4
92dc812222a7488d2a0e39b4a09c81c9f000d4b869reed
93db873d8677a2d4ecfe38a794a5d868301bdeeabereedclass SkComposeColorFilter : public SkColorFilter {
94db873d8677a2d4ecfe38a794a5d868301bdeeabereedpublic:
9536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    uint32_t getFlags() const override {
96f7cdb06d62bd732599c7ee407dfd76d32d671755reed        // Can only claim alphaunchanged and SkPM4f support if both our proxys do.
97db873d8677a2d4ecfe38a794a5d868301bdeeabereed        return fOuter->getFlags() & fInner->getFlags();
98db873d8677a2d4ecfe38a794a5d868301bdeeabereed    }
999d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
100db873d8677a2d4ecfe38a794a5d868301bdeeabereed#ifndef SK_IGNORE_TO_STRING
10136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void toString(SkString* str) const override {
102db873d8677a2d4ecfe38a794a5d868301bdeeabereed        SkString outerS, innerS;
103db873d8677a2d4ecfe38a794a5d868301bdeeabereed        fOuter->toString(&outerS);
104db873d8677a2d4ecfe38a794a5d868301bdeeabereed        fInner->toString(&innerS);
10527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        // These strings can be long.  SkString::appendf has limitations.
10627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        str->append(SkStringPrintf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(),
10727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary                                   innerS.c_str()));
108db873d8677a2d4ecfe38a794a5d868301bdeeabereed    }
109db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif
110db873d8677a2d4ecfe38a794a5d868301bdeeabereed
111fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein    void onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkArenaAlloc* scratch,
1129444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed                        bool shaderIsOpaque) const override {
1139444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed        bool innerIsOpaque = shaderIsOpaque;
1149444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed        if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) {
1159444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed            innerIsOpaque = false;
1169444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed        }
1176dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein        fInner->appendStages(p, dst, scratch, shaderIsOpaque);
1186dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein        fOuter->appendStages(p, dst, scratch, innerIsOpaque);
1199444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed    }
1209444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed
121db873d8677a2d4ecfe38a794a5d868301bdeeabereed#if SK_SUPPORT_GPU
122618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman    sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* context,
123618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                                                   SkColorSpace* dstColorSpace) const override {
124618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman        sk_sp<GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, dstColorSpace));
125618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman        sk_sp<GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, dstColorSpace));
126e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon        if (!innerFP || !outerFP) {
127e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            return nullptr;
128e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon        }
12906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        sk_sp<GrFragmentProcessor> series[] = { std::move(innerFP), std::move(outerFP) };
130e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon        return GrFragmentProcessor::RunInSeries(series, 2);
131cff10b21a9934afc540d121b493b204335829589reed    }
132db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif
133db873d8677a2d4ecfe38a794a5d868301bdeeabereed
134db873d8677a2d4ecfe38a794a5d868301bdeeabereed    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
1359d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
136db873d8677a2d4ecfe38a794a5d868301bdeeabereedprotected:
13736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void flatten(SkWriteBuffer& buffer) const override {
138d053ce9c54d4e5937a142278359e5a4cde18095ereed        buffer.writeFlattenable(fOuter.get());
139d053ce9c54d4e5937a142278359e5a4cde18095ereed        buffer.writeFlattenable(fInner.get());
140db873d8677a2d4ecfe38a794a5d868301bdeeabereed    }
1419d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
142db873d8677a2d4ecfe38a794a5d868301bdeeabereedprivate:
143d053ce9c54d4e5937a142278359e5a4cde18095ereed    SkComposeColorFilter(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner,
144d053ce9c54d4e5937a142278359e5a4cde18095ereed                         int composedFilterCount)
145d053ce9c54d4e5937a142278359e5a4cde18095ereed        : fOuter(std::move(outer))
146d053ce9c54d4e5937a142278359e5a4cde18095ereed        , fInner(std::move(inner))
147dc812222a7488d2a0e39b4a09c81c9f000d4b869reed        , fComposedFilterCount(composedFilterCount)
148dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    {
149dc812222a7488d2a0e39b4a09c81c9f000d4b869reed        SkASSERT(composedFilterCount >= 2);
150dc812222a7488d2a0e39b4a09c81c9f000d4b869reed        SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
151dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    }
152dc812222a7488d2a0e39b4a09c81c9f000d4b869reed
15336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int privateComposedFilterCount() const override {
154dc812222a7488d2a0e39b4a09c81c9f000d4b869reed        return fComposedFilterCount;
155dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    }
156dc812222a7488d2a0e39b4a09c81c9f000d4b869reed
1574e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein    sk_sp<SkColorFilter> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
1586d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed        auto outer = xformer->apply(fOuter.get());
1596d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed        auto inner = xformer->apply(fInner.get());
1606d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed        if (outer != fOuter || inner != fInner) {
1616d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed            return SkColorFilter::MakeComposeFilter(outer, inner);
1626d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed        }
1636d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed        return this->INHERITED::onMakeColorSpace(xformer);
1644e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein    }
1654e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein
166d053ce9c54d4e5937a142278359e5a4cde18095ereed    sk_sp<SkColorFilter> fOuter;
167d053ce9c54d4e5937a142278359e5a4cde18095ereed    sk_sp<SkColorFilter> fInner;
168d053ce9c54d4e5937a142278359e5a4cde18095ereed    const int            fComposedFilterCount;
169db873d8677a2d4ecfe38a794a5d868301bdeeabereed
170db873d8677a2d4ecfe38a794a5d868301bdeeabereed    friend class SkColorFilter;
171db873d8677a2d4ecfe38a794a5d868301bdeeabereed
172db873d8677a2d4ecfe38a794a5d868301bdeeabereed    typedef SkColorFilter INHERITED;
173db873d8677a2d4ecfe38a794a5d868301bdeeabereed};
174db873d8677a2d4ecfe38a794a5d868301bdeeabereed
17560c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
176d053ce9c54d4e5937a142278359e5a4cde18095ereed    sk_sp<SkColorFilter> outer(buffer.readColorFilter());
177d053ce9c54d4e5937a142278359e5a4cde18095ereed    sk_sp<SkColorFilter> inner(buffer.readColorFilter());
17860c9b58b3214b0154c931656e91e39b230e987d8reed    return MakeComposeFilter(std::move(outer), std::move(inner));
179db873d8677a2d4ecfe38a794a5d868301bdeeabereed}
180db873d8677a2d4ecfe38a794a5d868301bdeeabereed
181d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer,
182d053ce9c54d4e5937a142278359e5a4cde18095ereed                                                      sk_sp<SkColorFilter> inner) {
183db873d8677a2d4ecfe38a794a5d868301bdeeabereed    if (!outer) {
184d053ce9c54d4e5937a142278359e5a4cde18095ereed        return inner;
185db873d8677a2d4ecfe38a794a5d868301bdeeabereed    }
186db873d8677a2d4ecfe38a794a5d868301bdeeabereed    if (!inner) {
187d053ce9c54d4e5937a142278359e5a4cde18095ereed        return outer;
188db873d8677a2d4ecfe38a794a5d868301bdeeabereed    }
1898a8d841d485ff36b64d838575eb3735c1ddcf929reed
1908a8d841d485ff36b64d838575eb3735c1ddcf929reed    // Give the subclass a shot at a more optimal composition...
191d053ce9c54d4e5937a142278359e5a4cde18095ereed    auto composition = outer->makeComposed(inner);
192dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    if (composition) {
193dc812222a7488d2a0e39b4a09c81c9f000d4b869reed        return composition;
194dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    }
195dc812222a7488d2a0e39b4a09c81c9f000d4b869reed
196dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
197dc812222a7488d2a0e39b4a09c81c9f000d4b869reed    if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
19896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
1998a8d841d485ff36b64d838575eb3735c1ddcf929reed    }
200d053ce9c54d4e5937a142278359e5a4cde18095ereed    return sk_sp<SkColorFilter>(new SkComposeColorFilter(std::move(outer), std::move(inner),count));
201db873d8677a2d4ecfe38a794a5d868301bdeeabereed}
202db873d8677a2d4ecfe38a794a5d868301bdeeabereed
203412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed///////////////////////////////////////////////////////////////////////////////////////////////////
204412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
205412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#if SK_SUPPORT_GPU
206412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#include "../gpu/effects/GrSRGBEffect.h"
207412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#endif
208412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
209412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedclass SkSRGBGammaColorFilter : public SkColorFilter {
210412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedpublic:
211412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    enum class Direction {
212412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        kLinearToSRGB,
213412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        kSRGBToLinear,
214412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    };
215412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    SkSRGBGammaColorFilter(Direction dir) : fDir(dir) {}
216412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
217412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#if SK_SUPPORT_GPU
218412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* x, SkColorSpace* cs) const override {
21998308fb081687970278dce2a7631005f9cb424a8Mike Reed        // wish our caller would let us know if our input was opaque...
22098308fb081687970278dce2a7631005f9cb424a8Mike Reed        GrSRGBEffect::Alpha alpha = GrSRGBEffect::Alpha::kPremul;
221412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        switch (fDir) {
222412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed            case Direction::kLinearToSRGB:
22398308fb081687970278dce2a7631005f9cb424a8Mike Reed                return GrSRGBEffect::Make(GrSRGBEffect::Mode::kLinearToSRGB, alpha);
224412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed            case Direction::kSRGBToLinear:
22598308fb081687970278dce2a7631005f9cb424a8Mike Reed                return GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear, alpha);
226412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        }
227412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        return nullptr;
228412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    }
229412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#endif
230412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
231412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    SK_TO_STRING_OVERRIDE()
232412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
233412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSRGBGammaColorFilter)
234412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
235412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    void onAppendStages(SkRasterPipeline* p, SkColorSpace*, SkArenaAlloc* alloc,
236412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed                        bool shaderIsOpaque) const override {
237bdf6c62a19c50822977387a1be084071f94768d4Mike Reed        if (!shaderIsOpaque) {
238bdf6c62a19c50822977387a1be084071f94768d4Mike Reed            p->append(SkRasterPipeline::unpremul);
239bdf6c62a19c50822977387a1be084071f94768d4Mike Reed        }
240412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        switch (fDir) {
241412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed            case Direction::kLinearToSRGB:
242412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed                p->append(SkRasterPipeline::to_srgb);
243412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed                break;
244412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed            case Direction::kSRGBToLinear:
245bdf6c62a19c50822977387a1be084071f94768d4Mike Reed                p->append_from_srgb(shaderIsOpaque ? kOpaque_SkAlphaType : kUnpremul_SkAlphaType);
246412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed                break;
247412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        }
248bdf6c62a19c50822977387a1be084071f94768d4Mike Reed        if (!shaderIsOpaque) {
249bdf6c62a19c50822977387a1be084071f94768d4Mike Reed            p->append(SkRasterPipeline::premul);
250bdf6c62a19c50822977387a1be084071f94768d4Mike Reed        }
251412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    }
252412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
253412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedprotected:
254412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    void flatten(SkWriteBuffer& buffer) const override {
255412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        buffer.write32(static_cast<uint32_t>(fDir));
256412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    }
257412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
258412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedprivate:
259412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    const Direction fDir;
260412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
261412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    friend class SkColorFilter;
262412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    typedef SkColorFilter INHERITED;
263412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed};
264412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
265412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedsk_sp<SkFlattenable> SkSRGBGammaColorFilter::CreateProc(SkReadBuffer& buffer) {
266412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    uint32_t dir = buffer.read32();
267412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    if (dir <= 1) {
268412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed        return sk_sp<SkFlattenable>(new SkSRGBGammaColorFilter(static_cast<Direction>(dir)));
269412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    }
270412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    buffer.validate(false);
271412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    return nullptr;
272412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed}
273412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
274412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#ifndef SK_IGNORE_TO_STRING
275412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedvoid SkSRGBGammaColorFilter::toString(SkString* str) const {
276412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed    str->append("srgbgamma");
277412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed}
278412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed#endif
279412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
280fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malitatemplate <SkSRGBGammaColorFilter::Direction dir>
281fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malitask_sp<SkColorFilter> MakeSRGBGammaCF() {
282fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita    static SkColorFilter* gSingleton = new SkSRGBGammaColorFilter(dir);
283fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita    return sk_ref_sp(gSingleton);
284fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita}
285fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita
286412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedsk_sp<SkColorFilter> SkColorFilter::MakeLinearToSRGBGamma() {
287fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita    return MakeSRGBGammaCF<SkSRGBGammaColorFilter::Direction::kLinearToSRGB>();
288412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed}
289412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
290412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reedsk_sp<SkColorFilter> SkColorFilter::MakeSRGBToLinearGamma() {
291fff3a40767df6d3a913c146d96b2b4284dffb4c5Florin Malita    return MakeSRGBGammaCF<SkSRGBGammaColorFilter::Direction::kSRGBToLinear>();
292412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed}
293412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
294412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed///////////////////////////////////////////////////////////////////////////////////////////////////
295412cda7379626ee3acfd1dbb1441adde81efddc3Mike Reed
296c7141eb8fba41f1e098499ef17d0bc79641d54c5reed#include "SkModeColorFilter.h"
297c7141eb8fba41f1e098499ef17d0bc79641d54c5reed
298db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
299db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
300c7141eb8fba41f1e098499ef17d0bc79641d54c5reedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
301412cda7379626ee3acfd1dbb1441adde81efddc3Mike ReedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSRGBGammaColorFilter)
302db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
303