From c7141eb8fba41f1e098499ef17d0bc79641d54c5 Mon Sep 17 00:00:00 2001 From: reed Date: Mon, 11 Jan 2016 13:08:59 -0800 Subject: remove external header for SkModeColorFilter BUG=skia:4791 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1577073002 Review URL: https://codereview.chromium.org/1577073002 --- src/core/SkColorFilter.cpp | 3 + src/core/SkModeColorFilter.cpp | 181 +++++++++++++++++++++++++++++++++++++++++ src/core/SkModeColorFilter.h | 60 ++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 src/core/SkModeColorFilter.cpp create mode 100644 src/core/SkModeColorFilter.h (limited to 'src/core') diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index 031f376eee..747e5ee107 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -140,7 +140,10 @@ SkColorFilter* SkColorFilter::CreateComposeFilter(SkColorFilter* outer, SkColorF return new SkComposeColorFilter(outer, inner, count); } +#include "SkModeColorFilter.h" + SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter) +SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp new file mode 100644 index 0000000000..df1051abb0 --- /dev/null +++ b/src/core/SkModeColorFilter.cpp @@ -0,0 +1,181 @@ +/* + * 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 "SkBlitRow.h" +#include "SkColorFilter.h" +#include "SkColorPriv.h" +#include "SkModeColorFilter.h" +#include "SkReadBuffer.h" +#include "SkWriteBuffer.h" +#include "SkUtils.h" +#include "SkString.h" +#include "SkValidationUtils.h" + +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef SK_IGNORE_TO_STRING +void SkModeColorFilter::toString(SkString* str) const { + str->append("SkModeColorFilter: color: 0x"); + str->appendHex(fColor); + str->append(" mode: "); + str->append(SkXfermode::ModeName(fMode)); +} +#endif + +bool SkModeColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const { + if (color) { + *color = fColor; + } + if (mode) { + *mode = fMode; + } + return true; +} + +uint32_t SkModeColorFilter::getFlags() const { + switch (fMode) { + case SkXfermode::kDst_Mode: //!< [Da, Dc] + case SkXfermode::kSrcATop_Mode: //!< [Da, Sc * Da + (1 - Sa) * Dc] + return kAlphaUnchanged_Flag; + default: + break; + } + return 0; +} + +void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const { + SkPMColor color = fPMColor; + SkXfermodeProc proc = fProc; + + for (int i = 0; i < count; i++) { + result[i] = proc(color, shader[i]); + } +} + +void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const { + buffer.writeColor(fColor); + buffer.writeUInt(fMode); +} + +void SkModeColorFilter::updateCache() { + fPMColor = SkPreMultiplyColor(fColor); + fProc = SkXfermode::GetProc(fMode); +} + +SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) { + SkColor color = buffer.readColor(); + SkXfermode::Mode mode = (SkXfermode::Mode)buffer.readUInt(); + return SkColorFilter::CreateModeFilter(color, mode); +} + +/////////////////////////////////////////////////////////////////////////////// +#if SK_SUPPORT_GPU +#include "GrBlend.h" +#include "GrInvariantOutput.h" +#include "effects/GrXfermodeFragmentProcessor.h" +#include "effects/GrConstColorProcessor.h" +#include "SkGr.h" + +const GrFragmentProcessor* SkModeColorFilter::asFragmentProcessor(GrContext*) const { + if (SkXfermode::kDst_Mode == fMode) { + return nullptr; + } + + SkAutoTUnref constFP( + GrConstColorProcessor::Create(SkColorToPremulGrColor(fColor), + GrConstColorProcessor::kIgnore_InputMode)); + const GrFragmentProcessor* fp = + GrXfermodeFragmentProcessor::CreateFromSrcProcessor(constFP, fMode); + if (!fp) { + return nullptr; + } +#ifdef SK_DEBUG + // With a solid color input this should always be able to compute the blended color + // (at least for coeff modes) + if (fMode <= SkXfermode::kLastCoeffMode) { + static SkRandom gRand; + GrInvariantOutput io(GrPremulColor(gRand.nextU()), kRGBA_GrColorComponentFlags, + false); + fp->computeInvariantOutput(&io); + SkASSERT(io.validFlags() == kRGBA_GrColorComponentFlags); + } +#endif + return fp; +} + +#endif + +/////////////////////////////////////////////////////////////////////////////// + +class Src_SkModeColorFilter final : public SkModeColorFilter { +public: + Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} + + void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override { + sk_memset32(result, this->getPMColor(), count); + } + +private: + typedef SkModeColorFilter INHERITED; +}; + +class SrcOver_SkModeColorFilter final : public SkModeColorFilter { +public: + SrcOver_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrcOver_Mode) { } + + void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override { + SkBlitRow::Color32(result, shader, count, this->getPMColor()); + } + +private: + typedef SkModeColorFilter INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, SkXfermode::Mode mode) { + if (!SkIsValidMode(mode)) { + return nullptr; + } + + unsigned alpha = SkColorGetA(color); + + // first collaps some modes if possible + + if (SkXfermode::kClear_Mode == mode) { + color = 0; + mode = SkXfermode::kSrc_Mode; + } else if (SkXfermode::kSrcOver_Mode == mode) { + if (0 == alpha) { + mode = SkXfermode::kDst_Mode; + } else if (255 == alpha) { + mode = SkXfermode::kSrc_Mode; + } + // else just stay srcover + } + + // weed out combinations that are noops, and just return null + if (SkXfermode::kDst_Mode == mode || + (0 == alpha && (SkXfermode::kSrcOver_Mode == mode || + SkXfermode::kDstOver_Mode == mode || + SkXfermode::kDstOut_Mode == mode || + SkXfermode::kSrcATop_Mode == mode || + SkXfermode::kXor_Mode == mode || + SkXfermode::kDarken_Mode == mode)) || + (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) { + return nullptr; + } + + switch (mode) { + case SkXfermode::kSrc_Mode: + return new Src_SkModeColorFilter(color); + case SkXfermode::kSrcOver_Mode: + return new SrcOver_SkModeColorFilter(color); + default: + return SkModeColorFilter::Create(color, mode); + } +} diff --git a/src/core/SkModeColorFilter.h b/src/core/SkModeColorFilter.h new file mode 100644 index 0000000000..9fa7717b84 --- /dev/null +++ b/src/core/SkModeColorFilter.h @@ -0,0 +1,60 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkColorFilter.h" +#include "SkXfermode.h" + +#ifndef SkModeColorFilter_DEFINED +#define SkModeColorFilter_DEFINED + +class SkModeColorFilter : public SkColorFilter { +public: + static SkColorFilter* Create(SkColor color, SkXfermode::Mode mode) { + return new SkModeColorFilter(color, mode); + } + + SkColor getColor() const { return fColor; } + SkXfermode::Mode getMode() const { return fMode; } + SkPMColor getPMColor() const { return fPMColor; } + + bool asColorMode(SkColor*, SkXfermode::Mode*) const override; + uint32_t getFlags() const override; + void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override; + +#ifndef SK_IGNORE_TO_STRING + void toString(SkString* str) const override; +#endif + +#if SK_SUPPORT_GPU + const GrFragmentProcessor* asFragmentProcessor(GrContext*) const override; +#endif + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) + +protected: + SkModeColorFilter(SkColor color, SkXfermode::Mode mode) { + fColor = color; + fMode = mode; + this->updateCache(); + }; + + void flatten(SkWriteBuffer&) const override; + +private: + SkColor fColor; + SkXfermode::Mode fMode; + // cache + SkPMColor fPMColor; + SkXfermodeProc fProc; + + void updateCache(); + + friend class SkColorFilter; + + typedef SkColorFilter INHERITED; +}; + +#endif -- cgit v1.2.3