SkColorFilter.cpp revision dc812222a7488d2a0e39b4a09c81c9f000d4b869
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 "SkString.h"
11#include "SkWriteBuffer.h"
12
13bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
14    return false;
15}
16
17bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
18    return false;
19}
20
21bool SkColorFilter::asComponentTable(SkBitmap*) const {
22    return false;
23}
24
25void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) const {
26    SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
27    SkDEBUGFAIL("missing implementation of SkColorFilter::filterSpan16");
28
29    if (d != s) {
30        memcpy(d, s, count * sizeof(uint16_t));
31    }
32}
33
34SkColor SkColorFilter::filterColor(SkColor c) const {
35    SkPMColor dst, src = SkPreMultiplyColor(c);
36    this->filterSpan(&src, 1, &dst);
37    return SkUnPreMultiply::PMColorToColor(dst);
38}
39
40///////////////////////////////////////////////////////////////////////////////////////////////////
41
42/*
43 *  Since colorfilters may be used on the GPU backend, and in that case we may string together
44 *  many GrFragmentProcessors, we might exceed some internal instruction/resource limit.
45 *
46 *  Since we don't yet know *what* those limits might be when we construct the final shader,
47 *  we just set an arbitrary limit during construction. If later we find smarter ways to know what
48 *  the limnits are, we can change this constant (or remove it).
49 */
50#define SK_MAX_COMPOSE_COLORFILTER_COUNT    4
51
52class SkComposeColorFilter : public SkColorFilter {
53public:
54    uint32_t getFlags() const SK_OVERRIDE {
55        // Can only claim alphaunchanged and 16bit support if both our proxys do.
56        return fOuter->getFlags() & fInner->getFlags();
57    }
58
59    void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE {
60        fInner->filterSpan(shader, count, result);
61        fOuter->filterSpan(result, count, result);
62    }
63
64    void filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const SK_OVERRIDE {
65        SkASSERT(this->getFlags() & kHasFilter16_Flag);
66        fInner->filterSpan16(shader, count, result);
67        fOuter->filterSpan16(result, count, result);
68    }
69
70#ifndef SK_IGNORE_TO_STRING
71    void toString(SkString* str) const SK_OVERRIDE {
72        SkString outerS, innerS;
73        fOuter->toString(&outerS);
74        fInner->toString(&innerS);
75        str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str());
76    }
77#endif
78
79#if SK_SUPPORT_GPU
80    bool asFragmentProcessors(GrContext* context,
81                              SkTDArray<GrFragmentProcessor*>* array) const SK_OVERRIDE {
82        bool hasFrags = fInner->asFragmentProcessors(context, array);
83        hasFrags |= fOuter->asFragmentProcessors(context, array);
84        return hasFrags;
85    }
86#endif
87
88    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
89
90protected:
91    void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
92        buffer.writeFlattenable(fOuter);
93        buffer.writeFlattenable(fInner);
94    }
95
96private:
97    SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount)
98        : fOuter(SkRef(outer))
99        , fInner(SkRef(inner))
100        , fComposedFilterCount(composedFilterCount)
101    {
102        SkASSERT(composedFilterCount >= 2);
103        SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT);
104    }
105
106    int privateComposedFilterCount() const SK_OVERRIDE {
107        return fComposedFilterCount;
108    }
109
110    SkAutoTUnref<SkColorFilter> fOuter;
111    SkAutoTUnref<SkColorFilter> fInner;
112    const int                   fComposedFilterCount;
113
114    friend class SkColorFilter;
115
116    typedef SkColorFilter INHERITED;
117};
118
119SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
120    SkAutoTUnref<SkColorFilter> outer(buffer.readColorFilter());
121    SkAutoTUnref<SkColorFilter> inner(buffer.readColorFilter());
122    return CreateComposeFilter(outer, inner);
123}
124
125///////////////////////////////////////////////////////////////////////////////////////////////////
126
127SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
128    if (!outer) {
129        return SkSafeRef(inner);
130    }
131    if (!inner) {
132        return SkSafeRef(outer);
133    }
134
135    // Give the subclass a shot at a more optimal composition...
136    SkColorFilter* composition = outer->newComposed(inner);
137    if (composition) {
138        return composition;
139    }
140
141    int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount();
142    if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) {
143        return NULL;
144    }
145    return SkNEW_ARGS(SkComposeColorFilter, (outer, inner, count));
146}
147
148SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
149SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
150SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
151
152