diff options
author | Mike Reed <reed@google.com> | 2017-07-05 15:43:15 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-05 20:16:27 +0000 |
commit | 412cda7379626ee3acfd1dbb1441adde81efddc3 (patch) | |
tree | 2e57666502214c97a1b48d11ce7c2bfc1f20d0f9 | |
parent | 2d171397f863699eb7804b814994d4c2fcb00cb7 (diff) |
add srgb gamma colorfilters
... faster and more accurate than using SkTableColorFilter
todo: update blink after this lands
Bug:737981
Change-Id: I55b5c60dd23b9d2cbe9d60f83c74be1a8f3dcfcf
Reviewed-on: https://skia-review.googlesource.com/21368
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
-rw-r--r-- | include/core/SkColorFilter.h | 8 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 2 | ||||
-rw-r--r-- | src/core/SkColorFilter.cpp | 84 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 10 | ||||
-rw-r--r-- | tests/ApplyGammaTest.cpp | 5 | ||||
-rw-r--r-- | tools/sk_tool_utils.cpp | 42 | ||||
-rw-r--r-- | tools/sk_tool_utils.h | 5 |
7 files changed, 93 insertions, 63 deletions
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h index 1033a7268e..68142a29de 100644 --- a/include/core/SkColorFilter.h +++ b/include/core/SkColorFilter.h @@ -113,6 +113,14 @@ public: */ static sk_sp<SkColorFilter> MakeMatrixFilterRowMajor255(const SkScalar array[20]); + /** Construct a colorfilter that applies the srgb gamma curve to the RGB channels */ + static sk_sp<SkColorFilter> MakeLinearToSRGBGamma(); + + /** Construct a colorfilter that applies the inverse of the srgb gamma curve to the + * RGB channels + */ + static sk_sp<SkColorFilter> MakeSRGBToLinearGamma(); + #if SK_SUPPORT_GPU /** * A subclass may implement this factory function to work with the GPU backend. It returns diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index dde939bc66..1676fc3b13 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -370,7 +370,7 @@ public: SkPaint gammaPaint; gammaPaint.setBlendMode(SkBlendMode::kSrc); if (doGamma) { - gammaPaint.setColorFilter(sk_tool_utils::MakeLinearToSRGBColorFilter()); + gammaPaint.setColorFilter(SkColorFilter::MakeLinearToSRGBGamma()); } gpuCanvas->drawImage(offscreenImage, 0, 0, &gammaPaint); diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index a107a06e8c..3da812a293 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -174,8 +174,6 @@ sk_sp<SkFlattenable> SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) { return MakeComposeFilter(std::move(outer), std::move(inner)); } -/////////////////////////////////////////////////////////////////////////////////////////////////// - sk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner) { if (!outer) { @@ -198,9 +196,91 @@ sk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer return sk_sp<SkColorFilter>(new SkComposeColorFilter(std::move(outer), std::move(inner),count)); } +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#if SK_SUPPORT_GPU +#include "../gpu/effects/GrSRGBEffect.h" +#endif + +class SkSRGBGammaColorFilter : public SkColorFilter { +public: + enum class Direction { + kLinearToSRGB, + kSRGBToLinear, + }; + SkSRGBGammaColorFilter(Direction dir) : fDir(dir) {} + +#if SK_SUPPORT_GPU + sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* x, SkColorSpace* cs) const override { + switch (fDir) { + case Direction::kLinearToSRGB: + return GrSRGBEffect::Make(GrSRGBEffect::Mode::kLinearToSRGB); + case Direction::kSRGBToLinear: + return GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear); + } + return nullptr; + } +#endif + + SK_TO_STRING_OVERRIDE() + + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSRGBGammaColorFilter) + + void onAppendStages(SkRasterPipeline* p, SkColorSpace*, SkArenaAlloc* alloc, + bool shaderIsOpaque) const override { + switch (fDir) { + case Direction::kLinearToSRGB: + p->append(SkRasterPipeline::to_srgb); + break; + case Direction::kSRGBToLinear: + p->append_from_srgb(shaderIsOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + break; + } + } + +protected: + void flatten(SkWriteBuffer& buffer) const override { + buffer.write32(static_cast<uint32_t>(fDir)); + } + +private: + const Direction fDir; + + friend class SkColorFilter; + typedef SkColorFilter INHERITED; +}; + +sk_sp<SkFlattenable> SkSRGBGammaColorFilter::CreateProc(SkReadBuffer& buffer) { + uint32_t dir = buffer.read32(); + if (dir <= 1) { + return sk_sp<SkFlattenable>(new SkSRGBGammaColorFilter(static_cast<Direction>(dir))); + } + buffer.validate(false); + return nullptr; +} + +#ifndef SK_IGNORE_TO_STRING +void SkSRGBGammaColorFilter::toString(SkString* str) const { + str->append("srgbgamma"); +} +#endif + +sk_sp<SkColorFilter> SkColorFilter::MakeLinearToSRGBGamma() { + return sk_sp<SkColorFilter>(new SkSRGBGammaColorFilter( + SkSRGBGammaColorFilter::Direction::kLinearToSRGB)); +} + +sk_sp<SkColorFilter> SkColorFilter::MakeSRGBToLinearGamma() { + return sk_sp<SkColorFilter>(new SkSRGBGammaColorFilter( + SkSRGBGammaColorFilter::Direction::kSRGBToLinear)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + #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_ENTRY(SkSRGBGammaColorFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index d44c8bd6b6..da0071d84a 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -546,16 +546,6 @@ sk_sp<GrFragmentProcessor> SkTable_ColorFilter::asFragmentProcessor(GrContext* c /////////////////////////////////////////////////////////////////////////////// -#ifdef SK_CPU_BENDIAN -#else - #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3)) - #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3)) - #define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3)) - #define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3)) -#endif - -/////////////////////////////////////////////////////////////////////////////// - sk_sp<SkColorFilter> SkTableColorFilter::Make(const uint8_t table[256]) { return sk_make_sp<SkTable_ColorFilter>(table, table, table, table); } diff --git a/tests/ApplyGammaTest.cpp b/tests/ApplyGammaTest.cpp index dbb7210c1a..79dbfc7cd9 100644 --- a/tests/ApplyGammaTest.cpp +++ b/tests/ApplyGammaTest.cpp @@ -15,7 +15,6 @@ #include "SkColorFilter.h" #include "SkSurface.h" #include "SkUtils.h" -#include "sk_tool_utils.h" /** convert 0..1 linear value to 0..1 srgb */ static float linear_to_srgb(float linear) { @@ -112,8 +111,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ApplyGamma, reporter, ctxInfo) { SkPaint gammaPaint; gammaPaint.setBlendMode(SkBlendMode::kSrc); - gammaPaint.setColorFilter(toSRGB ? sk_tool_utils::MakeLinearToSRGBColorFilter() - : sk_tool_utils::MakeSRGBToLinearColorFilter()); + gammaPaint.setColorFilter(toSRGB ? SkColorFilter::MakeLinearToSRGBGamma() + : SkColorFilter::MakeSRGBToLinearGamma()); dstCanvas->drawBitmap(bm, 0, 0, &gammaPaint); dstCanvas->flush(); diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp index f4257f00aa..dff5d70150 100644 --- a/tools/sk_tool_utils.cpp +++ b/tools/sk_tool_utils.cpp @@ -22,38 +22,6 @@ DEFINE_bool(portableFonts, false, "Use portable fonts"); -#if SK_SUPPORT_GPU -#include "effects/GrSRGBEffect.h" -#include "SkColorFilter.h" - -// Color filter that just wraps GrSRGBEffect -class SkSRGBColorFilter : public SkColorFilter { -public: - static sk_sp<SkColorFilter> Make(GrSRGBEffect::Mode mode) { - return sk_sp<SkColorFilter>(new SkSRGBColorFilter(mode)); - } - - sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override { - return GrSRGBEffect::Make(fMode); - } - - void onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const override { - SK_ABORT("SkSRGBColorFilter is only implemented for GPU"); - } - Factory getFactory() const override { return nullptr; } - -#ifndef SK_IGNORE_TO_STRING - void toString(SkString* str) const override {} -#endif - -private: - SkSRGBColorFilter(GrSRGBEffect::Mode mode) : fMode(mode) {} - - GrSRGBEffect::Mode fMode; - typedef SkColorFilter INHERITED; -}; -#endif - namespace sk_tool_utils { /* these are the default fonts chosen by Chrome for serif, sans-serif, and monospace */ @@ -655,14 +623,4 @@ void copy_to_g8(SkBitmap* dst, const SkBitmap& src) { } } -#if SK_SUPPORT_GPU -sk_sp<SkColorFilter> MakeLinearToSRGBColorFilter() { - return SkSRGBColorFilter::Make(GrSRGBEffect::Mode::kLinearToSRGB); -} - -sk_sp<SkColorFilter> MakeSRGBToLinearColorFilter() { - return SkSRGBColorFilter::Make(GrSRGBEffect::Mode::kSRGBToLinear); -} -#endif - } // namespace sk_tool_utils diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index 111f966983..6283225c7f 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -256,11 +256,6 @@ namespace sk_tool_utils { bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src); void copy_to_g8(SkBitmap* dst, const SkBitmap& src); -#if SK_SUPPORT_GPU - sk_sp<SkColorFilter> MakeLinearToSRGBColorFilter(); - sk_sp<SkColorFilter> MakeSRGBToLinearColorFilter(); -#endif - } // namespace sk_tool_utils #endif // sk_tool_utils_DEFINED |