diff options
author | Mike Klein <mtklein@chromium.org> | 2016-10-12 11:05:05 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-10-12 17:24:17 +0000 |
commit | 96b333a9a1b6a367d6c542118638e3108d8ed23b (patch) | |
tree | ca3b80a0f659bc018094362e7d4221eb1992dafb /src/core/SkModeColorFilter.cpp | |
parent | c0708a40c723de3450f56194110da5aaf8bb053b (diff) |
Add SkRasterPipeline support to SkModeColorFilter.
The shader leaves its color in r,g,b,a, so to implement this color filter, we move {r,g,b,a} into {dr,dg,db,da}, then load the filter's color in {r,g,b,a}, then apply the xfermode as usual.
I've left a note about how we could sometimes cut a stage for some xfermodes. Similarly we really only need to move_src_dst instead of swap_src_dst, but it seemed handy and less error prone to do a full two way swap. As usual, we can always circle back and fine-tune these things if we want.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3243
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Change-Id: I928c0fb25236eb75cf238134c6bebb53af5ddf07
Reviewed-on: https://skia-review.googlesource.com/3243
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src/core/SkModeColorFilter.cpp')
-rw-r--r-- | src/core/SkModeColorFilter.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp index ba3b50d763..e165f69bcd 100644 --- a/src/core/SkModeColorFilter.cpp +++ b/src/core/SkModeColorFilter.cpp @@ -9,6 +9,7 @@ #include "SkColorFilter.h" #include "SkColorPriv.h" #include "SkModeColorFilter.h" +#include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkUtils.h" @@ -59,11 +60,10 @@ void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColo } void SkModeColorFilter::filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const { - SkPM4f color = SkPM4f::FromPMColor(fPMColor); SkXfermodeProc4f proc = SkXfermode::GetProc4f(fMode); for (int i = 0; i < count; i++) { - result[i] = proc(color, shader[i]); + result[i] = proc(fPM4f, shader[i]); } } @@ -75,6 +75,7 @@ void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const { void SkModeColorFilter::updateCache() { fPMColor = SkPreMultiplyColor(fColor); fProc = SkXfermode::GetProc(fMode); + fPM4f = SkPM4f::FromPMColor(fPMColor); } sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) { @@ -83,6 +84,20 @@ sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) { return SkColorFilter::MakeModeFilter(color, mode); } +bool SkModeColorFilter::onAppendStages(SkRasterPipeline* p) const { + // TODO: For some modes we can cut a stage by loading the fPM4f into dr,dg,db,da + // and applying the opposite xfermode, e.g. dst-in instead of src-in. + p->append(SkRasterPipeline::swap_src_dst); + p->append(SkRasterPipeline::constant_color, &fPM4f); + + // TODO: This is ugly. I think we want static SkXfermode::AppendStages(Mode). + if (auto xfermode = SkXfermode::Make(fMode)) { + return xfermode->appendStages(p); + } + p->append(SkRasterPipeline::srcover); + return true; +} + /////////////////////////////////////////////////////////////////////////////// #if SK_SUPPORT_GPU #include "GrBlend.h" |