/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkColorFilter.h" #include "SkReadBuffer.h" #include "SkString.h" #include "SkWriteBuffer.h" bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const { return false; } bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const { return false; } bool SkColorFilter::asComponentTable(SkBitmap*) const { return false; } SkColor SkColorFilter::filterColor(SkColor c) const { SkPMColor dst, src = SkPreMultiplyColor(c); this->filterSpan(&src, 1, &dst); return SkUnPreMultiply::PMColorToColor(dst); } /////////////////////////////////////////////////////////////////////////////////////////////////// /* * Since colorfilters may be used on the GPU backend, and in that case we may string together * many GrFragmentProcessors, we might exceed some internal instruction/resource limit. * * Since we don't yet know *what* those limits might be when we construct the final shader, * we just set an arbitrary limit during construction. If later we find smarter ways to know what * the limnits are, we can change this constant (or remove it). */ #define SK_MAX_COMPOSE_COLORFILTER_COUNT 4 class SkComposeColorFilter : public SkColorFilter { public: uint32_t getFlags() const override { // Can only claim alphaunchanged and 16bit support if both our proxys do. return fOuter->getFlags() & fInner->getFlags(); } void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override { fInner->filterSpan(shader, count, result); fOuter->filterSpan(result, count, result); } #ifndef SK_IGNORE_TO_STRING void toString(SkString* str) const override { SkString outerS, innerS; fOuter->toString(&outerS); fInner->toString(&innerS); str->appendf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), innerS.c_str()); } #endif #if SK_SUPPORT_GPU bool asFragmentProcessors(GrContext* context, SkTDArray* array) const override { bool hasFrags = fInner->asFragmentProcessors(context, array); hasFrags |= fOuter->asFragmentProcessors(context, array); return hasFrags; } #endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter) protected: void flatten(SkWriteBuffer& buffer) const override { buffer.writeFlattenable(fOuter); buffer.writeFlattenable(fInner); } private: SkComposeColorFilter(SkColorFilter* outer, SkColorFilter* inner, int composedFilterCount) : fOuter(SkRef(outer)) , fInner(SkRef(inner)) , fComposedFilterCount(composedFilterCount) { SkASSERT(composedFilterCount >= 2); SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT); } int privateComposedFilterCount() const override { return fComposedFilterCount; } SkAutoTUnref fOuter; SkAutoTUnref fInner; const int fComposedFilterCount; friend class SkColorFilter; typedef SkColorFilter INHERITED; }; SkFlattenable* SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) { SkAutoTUnref outer(buffer.readColorFilter()); SkAutoTUnref inner(buffer.readColorFilter()); return CreateComposeFilter(outer, inner); } /////////////////////////////////////////////////////////////////////////////////////////////////// SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) { if (!outer) { return SkSafeRef(inner); } if (!inner) { return SkSafeRef(outer); } // Give the subclass a shot at a more optimal composition... SkColorFilter* composition = outer->newComposed(inner); if (composition) { return composition; } int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount(); if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) { return NULL; } return SkNEW_ARGS(SkComposeColorFilter, (outer, inner, count)); } SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END