• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "SkColorFilter.h"
9 #include "SkReadBuffer.h"
10 #include "SkRefCnt.h"
11 #include "SkString.h"
12 #include "SkTDArray.h"
13 #include "SkUnPreMultiply.h"
14 #include "SkWriteBuffer.h"
15 #include "SkPM4f.h"
16 #include "SkNx.h"
17 
18 #if SK_SUPPORT_GPU
19 #include "GrFragmentProcessor.h"
20 #endif
21 
asColorMode(SkColor * color,SkXfermode::Mode * mode) const22 bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
23     return false;
24 }
25 
asColorMatrix(SkScalar matrix[20]) const26 bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
27     return false;
28 }
29 
asComponentTable(SkBitmap *) const30 bool SkColorFilter::asComponentTable(SkBitmap*) const {
31     return false;
32 }
33 
filterSpan4f(const SkPM4f[],int count,SkPM4f span[]) const34 void SkColorFilter::filterSpan4f(const SkPM4f[], int count, SkPM4f span[]) const {
35     const int N = 128;
36     SkPMColor tmp[N];
37     while (count > 0) {
38         int n = SkTMin(count, N);
39         for (int i = 0; i < n; ++i) {
40             SkNx_cast<uint8_t>(Sk4f::Load(span[i].fVec) * Sk4f(255) + Sk4f(0.5f)).store(&tmp[i]);
41         }
42         this->filterSpan(tmp, n, tmp);
43         for (int i = 0; i < n; ++i) {
44             span[i] = SkPM4f::FromPMColor(tmp[i]);
45         }
46         span += n;
47         count -= n;
48     }
49 }
50 
filterColor(SkColor c) const51 SkColor SkColorFilter::filterColor(SkColor c) const {
52     SkPMColor dst, src = SkPreMultiplyColor(c);
53     this->filterSpan(&src, 1, &dst);
54     return SkUnPreMultiply::PMColorToColor(dst);
55 }
56 
filterColor4f(const SkColor4f & c) const57 SkColor4f SkColorFilter::filterColor4f(const SkColor4f& c) const {
58     SkPM4f dst, src = c.premul();
59     this->filterSpan4f(&src, 1, &dst);
60     return dst.unpremul();
61 }
62 
63 ///////////////////////////////////////////////////////////////////////////////////////////////////
64 
65 /*
66  *  Since colorfilters may be used on the GPU backend, and in that case we may string together
67  *  many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
68  *
69  *  Since we don't yet know *what* those limits might be when we construct the final shader,
70  *  we just set an arbitrary limit during construction. If later we find smarter ways to know what
71  *  the limnits are, we can change this constant (or remove it).
72  */
73 #define SK_MAX_COMPOSE_COLORFILTER_COUNT    4
74 
75 class SkComposeColorFilter : public SkColorFilter {
76 public:
getFlags() const77     uint32_t getFlags() const override {
78         // Can only claim alphaunchanged and SkPM4f support if both our proxys do.
79         return fOuter->getFlags() & fInner->getFlags();
80     }
81 
filterSpan(const SkPMColor shader[],int count,SkPMColor result[]) const82     void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
83         fInner->filterSpan(shader, count, result);
84         fOuter->filterSpan(result, count, result);
85     }
86 
filterSpan4f(const SkPM4f shader[],int count,SkPM4f result[]) const87     void filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const override {
88         fInner->filterSpan4f(shader, count, result);
89         fOuter->filterSpan4f(result, count, result);
90     }
91 
92 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const93     void toString(SkString* str) const override {
94         SkString outerS, innerS;
95         fOuter->toString(&outerS);
96         fInner->toString(&innerS);
97         str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
98     }
99 #endif
100 
101 #if SK_SUPPORT_GPU
asFragmentProcessor(GrContext * context) const102     const GrFragmentProcessor* asFragmentProcessor(GrContext* context) const override {
103         SkAutoTUnref<const GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context));
104         SkAutoTUnref<const GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context));
105         if (!innerFP || !outerFP) {
106             return nullptr;
107         }
108         const GrFragmentProcessor* series[] = { innerFP, outerFP };
109         return GrFragmentProcessor::RunInSeries(series, 2);
110     }
111 #endif
112 
113     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
114 
115 protected:
flatten(SkWriteBuffer & buffer) const116     void flatten(SkWriteBuffer& buffer) const override {
117         buffer.writeFlattenable(fOuter);
118         buffer.writeFlattenable(fInner);
119     }
120 
121 private:
SkComposeColorFilter(SkColorFilter * outer,SkColorFilter * inner,int composedFilterCount)122     SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount)
123         : fOuter(SkRef(outer))
124         , fInner(SkRef(inner))
125         , fComposedFilterCount(composedFilterCount)
126     {
127         SkASSERT(composedFilterCount >= 2);
128         SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
129     }
130 
privateComposedFilterCount() const131     int privateComposedFilterCount() const override {
132         return fComposedFilterCount;
133     }
134 
135     SkAutoTUnref<SkColorFilter> fOuter;
136     SkAutoTUnref<SkColorFilter> fInner;
137     const int                   fComposedFilterCount;
138 
139     friend class SkColorFilter;
140 
141     typedef SkColorFilter INHERITED;
142 };
143 
CreateProc(SkReadBuffer & buffer)144 SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
145     SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
146     SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
147     return CreateComposeFilter(outer, inner);
148 }
149 
150 ///////////////////////////////////////////////////////////////////////////////////////////////////
151 
CreateComposeFilter(SkColorFilter * outer,SkColorFilter * inner)152 SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
153     if (!outer) {
154         return SkSafeRef(inner);
155     }
156     if (!inner) {
157         return SkSafeRef(outer);
158     }
159 
160     // Give the subclass a shot at a more optimal composition...
161     SkColorFilter* composition = outer->newComposed(inner);
162     if (composition) {
163         return composition;
164     }
165 
166     int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
167     if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
168         return nullptr;
169     }
170     return new SkComposeColorFilter(outer, inner, count);
171 }
172 
173 #include "SkModeColorFilter.h"
174 
175 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
176 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
177 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
178 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
179 
180