aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkModeColorFilter.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2016-10-12 11:05:05 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-10-12 17:24:17 +0000
commit96b333a9a1b6a367d6c542118638e3108d8ed23b (patch)
treeca3b80a0f659bc018094362e7d4221eb1992dafb /src/core/SkModeColorFilter.cpp
parentc0708a40c723de3450f56194110da5aaf8bb053b (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.cpp19
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"