blob: 25e6b2ea7389e7392823ca54cc034e30853cb46d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2006 The Android Open Source Project
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkColorFilter.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +00009#include "SkReadBuffer.h"
bungemand3ebb482015-08-05 13:57:49 -070010#include "SkRefCnt.h"
reed5bd055c2015-03-01 19:16:38 -080011#include "SkString.h"
bungemand3ebb482015-08-05 13:57:49 -070012#include "SkTDArray.h"
13#include "SkUnPreMultiply.h"
reeddb873d82015-03-01 19:53:47 -080014#include "SkWriteBuffer.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015
bsalomone25eea42015-09-29 06:38:55 -070016#if SK_SUPPORT_GPU
17#include "GrFragmentProcessor.h"
18#endif
bungemand3ebb482015-08-05 13:57:49 -070019
reed@google.combada6442012-12-17 20:21:44 +000020bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
reed@google.com43c50c82011-04-14 15:50:52 +000021 return false;
22}
23
reed@google.combada6442012-12-17 20:21:44 +000024bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
senorblanco@chromium.orge5ff3ce2011-12-20 20:58:18 +000025 return false;
26}
27
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000028bool SkColorFilter::asComponentTable(SkBitmap*) const {
reed@google.com71918402012-01-05 17:24:35 +000029 return false;
30}
31
reed@google.combada6442012-12-17 20:21:44 +000032SkColor SkColorFilter::filterColor(SkColor c) const {
reed@google.com6b7aee32011-04-19 18:36:09 +000033 SkPMColor dst, src = SkPreMultiplyColor(c);
34 this->filterSpan(&src, 1, &dst);
35 return SkUnPreMultiply::PMColorToColor(dst);
36}
37
reeddb873d82015-03-01 19:53:47 -080038///////////////////////////////////////////////////////////////////////////////////////////////////
39
reeddc812222015-03-05 07:21:02 -080040/*
41 * Since colorfilters may be used on the GPU backend, and in that case we may string together
42 * many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
43 *
44 * Since we don't yet know *what* those limits might be when we construct the final shader,
45 * we just set an arbitrary limit during construction. If later we find smarter ways to know what
46 * the limnits are, we can change this constant (or remove it).
47 */
48#define SK_MAX_COMPOSE_COLORFILTER_COUNT 4
49
reeddb873d82015-03-01 19:53:47 -080050class SkComposeColorFilter : public SkColorFilter {
51public:
mtklein36352bf2015-03-25 18:17:31 -070052 uint32_t getFlags() const override {
reeddb873d82015-03-01 19:53:47 -080053 // Can only claim alphaunchanged and 16bit support if both our proxys do.
54 return fOuter->getFlags() & fInner->getFlags();
55 }
56
mtklein36352bf2015-03-25 18:17:31 -070057 void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
reeddb873d82015-03-01 19:53:47 -080058 fInner->filterSpan(shader, count, result);
59 fOuter->filterSpan(result, count, result);
60 }
61
reeddb873d82015-03-01 19:53:47 -080062#ifndef SK_IGNORE_TO_STRING
mtklein36352bf2015-03-25 18:17:31 -070063 void toString(SkString* str) const override {
reeddb873d82015-03-01 19:53:47 -080064 SkString outerS, innerS;
65 fOuter->toString(&outerS);
66 fInner->toString(&innerS);
67 str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
68 }
69#endif
70
reeddb873d82015-03-01 19:53:47 -080071#if SK_SUPPORT_GPU
bsalomone25eea42015-09-29 06:38:55 -070072 const GrFragmentProcessor* asFragmentProcessor(GrContext* context,
73 GrProcessorDataManager* pdm) const override {
74 SkAutoTUnref<const GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, pdm));
75 SkAutoTUnref<const GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, pdm));
76 if (!innerFP || !outerFP) {
77 return nullptr;
78 }
79 const GrFragmentProcessor* series[] = { innerFP, outerFP };
80 return GrFragmentProcessor::RunInSeries(series, 2);
reedcff10b22015-03-03 06:41:45 -080081 }
reeddb873d82015-03-01 19:53:47 -080082#endif
83
84 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
85
86protected:
mtklein36352bf2015-03-25 18:17:31 -070087 void flatten(SkWriteBuffer& buffer) const override {
reeddb873d82015-03-01 19:53:47 -080088 buffer.writeFlattenable(fOuter);
89 buffer.writeFlattenable(fInner);
90 }
91
92private:
reeddc812222015-03-05 07:21:02 -080093 SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount)
94 : fOuter(SkRef(outer))
95 , fInner(SkRef(inner))
96 , fComposedFilterCount(composedFilterCount)
97 {
98 SkASSERT(composedFilterCount >= 2);
99 SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
100 }
101
mtklein36352bf2015-03-25 18:17:31 -0700102 int privateComposedFilterCount() const override {
reeddc812222015-03-05 07:21:02 -0800103 return fComposedFilterCount;
104 }
105
reeddb873d82015-03-01 19:53:47 -0800106 SkAutoTUnref<SkColorFilter> fOuter;
107 SkAutoTUnref<SkColorFilter> fInner;
reeddc812222015-03-05 07:21:02 -0800108 const int fComposedFilterCount;
reeddb873d82015-03-01 19:53:47 -0800109
110 friend class SkColorFilter;
111
112 typedef SkColorFilter INHERITED;
113};
114
115SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
116 SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
117 SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
118 return CreateComposeFilter(outer, inner);
119}
120
reed8a8d8412015-03-02 13:46:03 -0800121///////////////////////////////////////////////////////////////////////////////////////////////////
122
reeddb873d82015-03-01 19:53:47 -0800123SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
124 if (!outer) {
125 return SkSafeRef(inner);
126 }
127 if (!inner) {
128 return SkSafeRef(outer);
129 }
reed8a8d8412015-03-02 13:46:03 -0800130
131 // Give the subclass a shot at a more optimal composition...
132 SkColorFilter* composition = outer->newComposed(inner);
reeddc812222015-03-05 07:21:02 -0800133 if (composition) {
134 return composition;
reed8a8d8412015-03-02 13:46:03 -0800135 }
reeddc812222015-03-05 07:21:02 -0800136
137 int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
138 if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
halcanary96fcdcc2015-08-27 07:41:13 -0700139 return nullptr;
reeddc812222015-03-05 07:21:02 -0800140 }
halcanary385fe4d2015-08-26 13:07:48 -0700141 return new SkComposeColorFilter(outer, inner, count);
reeddb873d82015-03-01 19:53:47 -0800142}
143
144SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
145SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
146SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
147