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