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>
This commit is contained in:
parent
c0708a40c7
commit
96b333a9a1
@ -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"
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkPM4f.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
#ifndef SkModeColorFilter_DEFINED
|
||||
@ -49,12 +50,15 @@ protected:
|
||||
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
bool onAppendStages(SkRasterPipeline*) const override;
|
||||
|
||||
private:
|
||||
SkColor fColor;
|
||||
SkXfermode::Mode fMode;
|
||||
// cache
|
||||
SkPMColor fPMColor;
|
||||
SkXfermodeProc fProc;
|
||||
SkPM4f fPM4f;
|
||||
|
||||
void updateCache();
|
||||
|
||||
|
@ -94,6 +94,7 @@ namespace SkOpts {
|
||||
|
||||
SkOpts::VoidFn body[] = {
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::just_return,
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::swap_src_dst,
|
||||
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::store_565,
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb,
|
||||
@ -144,6 +145,7 @@ namespace SkOpts {
|
||||
|
||||
SkOpts::VoidFn tail[] = {
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::just_return,
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::swap_src_dst,
|
||||
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::store_565_tail,
|
||||
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb_tail,
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
|
||||
enum StockStage {
|
||||
just_return,
|
||||
swap_src_dst,
|
||||
|
||||
store_565,
|
||||
store_srgb,
|
||||
|
@ -152,6 +152,13 @@ namespace SK_OPTS_NS {
|
||||
|
||||
STAGE(just_return, false) { }
|
||||
|
||||
STAGE(swap_src_dst, true) {
|
||||
SkTSwap(r,dr);
|
||||
SkTSwap(g,dg);
|
||||
SkTSwap(b,db);
|
||||
SkTSwap(a,da);
|
||||
}
|
||||
|
||||
// The default shader produces a constant color (from the SkPaint).
|
||||
STAGE(constant_color, true) {
|
||||
auto color = (const SkPM4f*)ctx;
|
||||
|
Loading…
Reference in New Issue
Block a user