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