SkColorFilter.cpp revision ae4738f677c70f4ec7687422e1510ee3d80d810e
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
16class GrFragmentProcessor;
17
18bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
19    return false;
20}
21
22bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
23    return false;
24}
25
26bool SkColorFilter::asComponentTable(SkBitmap*) const {
27    return false;
28}
29
30SkColor SkColorFilter::filterColor(SkColor c) const {
31    SkPMColor dst, src = SkPreMultiplyColor(c);
32    this->filterSpan(&src, 1, &dst);
33    return SkUnPreMultiply::PMColorToColor(dst);
34}
35
36///////////////////////////////////////////////////////////////////////////////////////////////////
37
38/*
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
48class SkComposeColorFilter : public SkColorFilter {
49public:
50    uint32_t getFlags() const override {
51        // Can only claim alphaunchanged and 16bit support if both our proxys do.
52        return fOuter->getFlags() & fInner->getFlags();
53    }
54
55    void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
56        fInner->filterSpan(shader, count, result);
57        fOuter->filterSpan(result, count, result);
58    }
59
60#ifndef SK_IGNORE_TO_STRING
61    void toString(SkString* str) const override {
62        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
69#if SK_SUPPORT_GPU
70    bool asFragmentProcessors(GrContext* context, GrProcessorDataManager* procDataManager,
71                              SkTDArray<const GrFragmentProcessor*>* array) const override {
72        bool hasFrags = fInner->asFragmentProcessors(context, procDataManager, array);
73        hasFrags |= fOuter->asFragmentProcessors(context, procDataManager, array);
74        return hasFrags;
75    }
76#endif
77
78    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
79
80protected:
81    void flatten(SkWriteBuffer& buffer) const override {
82        buffer.writeFlattenable(fOuter);
83        buffer.writeFlattenable(fInner);
84    }
85
86private:
87    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
96    int privateComposedFilterCount() const override {
97        return fComposedFilterCount;
98    }
99
100    SkAutoTUnref<SkColorFilter> fOuter;
101    SkAutoTUnref<SkColorFilter> fInner;
102    const int                   fComposedFilterCount;
103
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
115///////////////////////////////////////////////////////////////////////////////////////////////////
116
117SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
118    if (!outer) {
119        return SkSafeRef(inner);
120    }
121    if (!inner) {
122        return SkSafeRef(outer);
123    }
124
125    // Give the subclass a shot at a more optimal composition...
126    SkColorFilter* composition = outer->newComposed(inner);
127    if (composition) {
128        return composition;
129    }
130
131    int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
132    if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
133        return nullptr;
134    }
135    return new SkComposeColorFilter(outer, inner, count);
136}
137
138SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
139SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
140SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
141
142