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 "SkColorFilter.h"
|
||||||
#include "SkColorPriv.h"
|
#include "SkColorPriv.h"
|
||||||
#include "SkModeColorFilter.h"
|
#include "SkModeColorFilter.h"
|
||||||
|
#include "SkRasterPipeline.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
#include "SkUtils.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 {
|
void SkModeColorFilter::filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const {
|
||||||
SkPM4f color = SkPM4f::FromPMColor(fPMColor);
|
|
||||||
SkXfermodeProc4f proc = SkXfermode::GetProc4f(fMode);
|
SkXfermodeProc4f proc = SkXfermode::GetProc4f(fMode);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
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() {
|
void SkModeColorFilter::updateCache() {
|
||||||
fPMColor = SkPreMultiplyColor(fColor);
|
fPMColor = SkPreMultiplyColor(fColor);
|
||||||
fProc = SkXfermode::GetProc(fMode);
|
fProc = SkXfermode::GetProc(fMode);
|
||||||
|
fPM4f = SkPM4f::FromPMColor(fPMColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
||||||
@ -83,6 +84,20 @@ sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
|||||||
return SkColorFilter::MakeModeFilter(color, mode);
|
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
|
#if SK_SUPPORT_GPU
|
||||||
#include "GrBlend.h"
|
#include "GrBlend.h"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SkColorFilter.h"
|
#include "SkColorFilter.h"
|
||||||
|
#include "SkPM4f.h"
|
||||||
#include "SkXfermode.h"
|
#include "SkXfermode.h"
|
||||||
|
|
||||||
#ifndef SkModeColorFilter_DEFINED
|
#ifndef SkModeColorFilter_DEFINED
|
||||||
@ -49,12 +50,15 @@ protected:
|
|||||||
|
|
||||||
void flatten(SkWriteBuffer&) const override;
|
void flatten(SkWriteBuffer&) const override;
|
||||||
|
|
||||||
|
bool onAppendStages(SkRasterPipeline*) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkColor fColor;
|
SkColor fColor;
|
||||||
SkXfermode::Mode fMode;
|
SkXfermode::Mode fMode;
|
||||||
// cache
|
// cache
|
||||||
SkPMColor fPMColor;
|
SkPMColor fPMColor;
|
||||||
SkXfermodeProc fProc;
|
SkXfermodeProc fProc;
|
||||||
|
SkPM4f fPM4f;
|
||||||
|
|
||||||
void updateCache();
|
void updateCache();
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ namespace SkOpts {
|
|||||||
|
|
||||||
SkOpts::VoidFn body[] = {
|
SkOpts::VoidFn body[] = {
|
||||||
(SkOpts::VoidFn)SK_OPTS_NS::just_return,
|
(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_565,
|
||||||
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb,
|
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb,
|
||||||
@ -144,6 +145,7 @@ namespace SkOpts {
|
|||||||
|
|
||||||
SkOpts::VoidFn tail[] = {
|
SkOpts::VoidFn tail[] = {
|
||||||
(SkOpts::VoidFn)SK_OPTS_NS::just_return,
|
(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_565_tail,
|
||||||
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb_tail,
|
(SkOpts::VoidFn)SK_OPTS_NS::store_srgb_tail,
|
||||||
|
@ -91,6 +91,7 @@ public:
|
|||||||
|
|
||||||
enum StockStage {
|
enum StockStage {
|
||||||
just_return,
|
just_return,
|
||||||
|
swap_src_dst,
|
||||||
|
|
||||||
store_565,
|
store_565,
|
||||||
store_srgb,
|
store_srgb,
|
||||||
|
@ -152,6 +152,13 @@ namespace SK_OPTS_NS {
|
|||||||
|
|
||||||
STAGE(just_return, false) { }
|
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).
|
// The default shader produces a constant color (from the SkPaint).
|
||||||
STAGE(constant_color, true) {
|
STAGE(constant_color, true) {
|
||||||
auto color = (const SkPM4f*)ctx;
|
auto color = (const SkPM4f*)ctx;
|
||||||
|
Loading…
Reference in New Issue
Block a user