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