blob: 9cbcc6401798feebe4e5967890ad44af08187399 [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
bungemand3ebb482015-08-05 13:57:49 -070016class GrFragmentProcessor;
17
reed@google.combada6442012-12-17 20:21:44 +000018bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
reed@google.com43c50c82011-04-14 15:50:52 +000019 return false;
20}
21
reed@google.combada6442012-12-17 20:21:44 +000022bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
senorblanco@chromium.orge5ff3ce2011-12-20 20:58:18 +000023 return false;
24}
25
bsalomon@google.comb2ad1012012-10-17 15:00:32 +000026bool SkColorFilter::asComponentTable(SkBitmap*) const {
reed@google.com71918402012-01-05 17:24:35 +000027 return false;
28}
29
reed@google.combada6442012-12-17 20:21:44 +000030SkColor SkColorFilter::filterColor(SkColor c) const {
reed@google.com6b7aee32011-04-19 18:36:09 +000031 SkPMColor dst, src = SkPreMultiplyColor(c);
32 this->filterSpan(&src, 1, &dst);
33 return SkUnPreMultiply::PMColorToColor(dst);
34}
35
reeddb873d82015-03-01 19:53:47 -080036///////////////////////////////////////////////////////////////////////////////////////////////////
37
reeddc812222015-03-05 07:21:02 -080038/*
39 * Since colorfilters may be used on the GPU backend, and in that case we may string together
40 * many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
41 *
42 * Since we don't yet know *what* those limits might be when we construct the final shader,
43 * we just set an arbitrary limit during construction. If later we find smarter ways to know what
44 * the limnits are, we can change this constant (or remove it).
45 */
46#define SK_MAX_COMPOSE_COLORFILTER_COUNT 4
47
reeddb873d82015-03-01 19:53:47 -080048class SkComposeColorFilter : public SkColorFilter {
49public:
mtklein36352bf2015-03-25 18:17:31 -070050 uint32_t getFlags() const override {
reeddb873d82015-03-01 19:53:47 -080051 // Can only claim alphaunchanged and 16bit support if both our proxys do.
52 return fOuter->getFlags() & fInner->getFlags();
53 }
54
mtklein36352bf2015-03-25 18:17:31 -070055 void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
reeddb873d82015-03-01 19:53:47 -080056 fInner->filterSpan(shader, count, result);
57 fOuter->filterSpan(result, count, result);
58 }
59
reeddb873d82015-03-01 19:53:47 -080060#ifndef SK_IGNORE_TO_STRING
mtklein36352bf2015-03-25 18:17:31 -070061 void toString(SkString* str) const override {
reeddb873d82015-03-01 19:53:47 -080062 SkString outerS, innerS;
63 fOuter->toString(&outerS);
64 fInner->toString(&innerS);
65 str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
66 }
67#endif
68
reeddb873d82015-03-01 19:53:47 -080069#if SK_SUPPORT_GPU
joshualitt9cc17752015-07-09 06:28:14 -070070 bool asFragmentProcessors(GrContext* context, GrProcessorDataManager* procDataManager,
mtklein36352bf2015-03-25 18:17:31 -070071 SkTDArray<GrFragmentProcessor*>* array) const override {
joshualitt9cc17752015-07-09 06:28:14 -070072 bool hasFrags = fInner->asFragmentProcessors(context, procDataManager, array);
73 hasFrags |= fOuter->asFragmentProcessors(context, procDataManager, array);
reedcff10b22015-03-03 06:41:45 -080074 return hasFrags;
75 }
reeddb873d82015-03-01 19:53:47 -080076#endif
77
78 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
79
80protected:
mtklein36352bf2015-03-25 18:17:31 -070081 void flatten(SkWriteBuffer& buffer) const override {
reeddb873d82015-03-01 19:53:47 -080082 buffer.writeFlattenable(fOuter);
83 buffer.writeFlattenable(fInner);
84 }
85
86private:
reeddc812222015-03-05 07:21:02 -080087 SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount)
88 : fOuter(SkRef(outer))
89 , fInner(SkRef(inner))
90 , fComposedFilterCount(composedFilterCount)
91 {
92 SkASSERT(composedFilterCount >= 2);
93 SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
94 }
95
mtklein36352bf2015-03-25 18:17:31 -070096 int privateComposedFilterCount() const override {
reeddc812222015-03-05 07:21:02 -080097 return fComposedFilterCount;
98 }
99
reeddb873d82015-03-01 19:53:47 -0800100 SkAutoTUnref<SkColorFilter> fOuter;
101 SkAutoTUnref<SkColorFilter> fInner;
reeddc812222015-03-05 07:21:02 -0800102 const int fComposedFilterCount;
reeddb873d82015-03-01 19:53:47 -0800103
104 friend class SkColorFilter;
105
106 typedef SkColorFilter INHERITED;
107};
108
109SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
110 SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
111 SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
112 return CreateComposeFilter(outer, inner);
113}
114
reed8a8d8412015-03-02 13:46:03 -0800115///////////////////////////////////////////////////////////////////////////////////////////////////
116
reeddb873d82015-03-01 19:53:47 -0800117SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
118 if (!outer) {
119 return SkSafeRef(inner);
120 }
121 if (!inner) {
122 return SkSafeRef(outer);
123 }
reed8a8d8412015-03-02 13:46:03 -0800124
125 // Give the subclass a shot at a more optimal composition...
126 SkColorFilter* composition = outer->newComposed(inner);
reeddc812222015-03-05 07:21:02 -0800127 if (composition) {
128 return composition;
reed8a8d8412015-03-02 13:46:03 -0800129 }
reeddc812222015-03-05 07:21:02 -0800130
131 int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
132 if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
133 return NULL;
134 }
135 return SkNEW_ARGS(SkComposeColorFilter, (outer, inner, count));
reeddb873d82015-03-01 19:53:47 -0800136}
137
138SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
139SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
140SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
141