blob: 4bfacfe544de8904a609e4e550894449dbdc6e81 [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
reed6d3cef92016-01-22 01:04:29 -080038void SkColorFilter::filterSpan4f(const SkPM4f[], int count, SkPM4f[]) const {
39 SkASSERT(false && "filterSpan4f called but not implemented");
40}
41
reeddb873d82015-03-01 19:53:47 -080042///////////////////////////////////////////////////////////////////////////////////////////////////
43
reeddc812222015-03-05 07:21:02 -080044/*
45 * Since colorfilters may be used on the GPU backend, and in that case we may string together
46 * many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
47 *
48 * Since we don't yet know *what* those limits might be when we construct the final shader,
49 * we just set an arbitrary limit during construction. If later we find smarter ways to know what
50 * the limnits are, we can change this constant (or remove it).
51 */
52#define SK_MAX_COMPOSE_COLORFILTER_COUNT 4
53
reeddb873d82015-03-01 19:53:47 -080054class SkComposeColorFilter : public SkColorFilter {
55public:
mtklein36352bf2015-03-25 18:17:31 -070056 uint32_t getFlags() const override {
reeddb873d82015-03-01 19:53:47 -080057 // Can only claim alphaunchanged and 16bit support if both our proxys do.
58 return fOuter->getFlags() & fInner->getFlags();
59 }
60
mtklein36352bf2015-03-25 18:17:31 -070061 void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
reeddb873d82015-03-01 19:53:47 -080062 fInner->filterSpan(shader, count, result);
63 fOuter->filterSpan(result, count, result);
64 }
65
reeddb873d82015-03-01 19:53:47 -080066#ifndef SK_IGNORE_TO_STRING
mtklein36352bf2015-03-25 18:17:31 -070067 void toString(SkString* str) const override {
reeddb873d82015-03-01 19:53:47 -080068 SkString outerS, innerS;
69 fOuter->toString(&outerS);
70 fInner->toString(&innerS);
71 str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
72 }
73#endif
74
reeddb873d82015-03-01 19:53:47 -080075#if SK_SUPPORT_GPU
bsalomon4a339522015-10-06 08:40:50 -070076 const GrFragmentProcessor* asFragmentProcessor(GrContext* context) const override {
77 SkAutoTUnref<const GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context));
78 SkAutoTUnref<const GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context));
bsalomone25eea42015-09-29 06:38:55 -070079 if (!innerFP || !outerFP) {
80 return nullptr;
81 }
82 const GrFragmentProcessor* series[] = { innerFP, outerFP };
83 return GrFragmentProcessor::RunInSeries(series, 2);
reedcff10b22015-03-03 06:41:45 -080084 }
reeddb873d82015-03-01 19:53:47 -080085#endif
86
87 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
88
89protected:
mtklein36352bf2015-03-25 18:17:31 -070090 void flatten(SkWriteBuffer& buffer) const override {
reeddb873d82015-03-01 19:53:47 -080091 buffer.writeFlattenable(fOuter);
92 buffer.writeFlattenable(fInner);
93 }
94
95private:
reeddc812222015-03-05 07:21:02 -080096 SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount)
97 : fOuter(SkRef(outer))
98 , fInner(SkRef(inner))
99 , fComposedFilterCount(composedFilterCount)
100 {
101 SkASSERT(composedFilterCount >= 2);
102 SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
103 }
104
mtklein36352bf2015-03-25 18:17:31 -0700105 int privateComposedFilterCount() const override {
reeddc812222015-03-05 07:21:02 -0800106 return fComposedFilterCount;
107 }
108
reeddb873d82015-03-01 19:53:47 -0800109 SkAutoTUnref<SkColorFilter> fOuter;
110 SkAutoTUnref<SkColorFilter> fInner;
reeddc812222015-03-05 07:21:02 -0800111 const int fComposedFilterCount;
reeddb873d82015-03-01 19:53:47 -0800112
113 friend class SkColorFilter;
114
115 typedef SkColorFilter INHERITED;
116};
117
118SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
119 SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
120 SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
121 return CreateComposeFilter(outer, inner);
122}
123
reed8a8d8412015-03-02 13:46:03 -0800124///////////////////////////////////////////////////////////////////////////////////////////////////
125
reeddb873d82015-03-01 19:53:47 -0800126SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
127 if (!outer) {
128 return SkSafeRef(inner);
129 }
130 if (!inner) {
131 return SkSafeRef(outer);
132 }
reed8a8d8412015-03-02 13:46:03 -0800133
134 // Give the subclass a shot at a more optimal composition...
135 SkColorFilter* composition = outer->newComposed(inner);
reeddc812222015-03-05 07:21:02 -0800136 if (composition) {
137 return composition;
reed8a8d8412015-03-02 13:46:03 -0800138 }
reeddc812222015-03-05 07:21:02 -0800139
140 int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
141 if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
halcanary96fcdcc2015-08-27 07:41:13 -0700142 return nullptr;
reeddc812222015-03-05 07:21:02 -0800143 }
halcanary385fe4d2015-08-26 13:07:48 -0700144 return new SkComposeColorFilter(outer, inner, count);
reeddb873d82015-03-01 19:53:47 -0800145}
146
reedc7141eb2016-01-11 13:08:59 -0800147#include "SkModeColorFilter.h"
148
reeddb873d82015-03-01 19:53:47 -0800149SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
150SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
reedc7141eb2016-01-11 13:08:59 -0800151SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
reeddb873d82015-03-01 19:53:47 -0800152SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
153