onProgram for SkGaussianColorFilter, plus gm and bench

iMac Pro bench:
- RP:          167
- VM exp:      195
- VM quartics: 135

Change-Id: Ie8deb38f246b9ae7bbd35e59c3e7e66fc7c42de5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/279918
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-03-27 15:11:10 -04:00 committed by Skia Commit-Bot
parent 07e5b8f0ed
commit f36b37f828
4 changed files with 75 additions and 9 deletions

View File

@ -13,6 +13,7 @@
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkOverdrawColorFilter.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/core/SkColorFilterPriv.h"
#include "tools/Resources.h"
// Just need an interesting filter, nothing to special about colormatrix
@ -196,6 +197,9 @@ DEF_BENCH( return new ColorFilterBench("overdraw", []() {
};
return SkOverdrawColorFilter::MakeWithSkColors(colors);
}); )
DEF_BENCH( return new ColorFilterBench("gaussian", []() {
return SkColorFilterPriv::MakeGaussian();
}); )
#ifdef SK_SUPPORT_GPU
DEF_BENCH( return new ColorFilterBench("src_runtime", []() {

View File

@ -235,3 +235,28 @@ DEF_SIMPLE_GM(shadow_utils_occl, canvas, kW, kH) {
DEF_SIMPLE_GM(shadow_utils_gray, canvas, kW, kH) {
draw_paths(canvas, kGrayscale);
}
#include "include/effects/SkGradientShader.h"
#include "src/core/SkColorFilterPriv.h"
DEF_SIMPLE_GM(shadow_utils_gaussian_colorfilter, canvas, 512, 256) {
const SkRect r = SkRect::MakeWH(256, 256);
const SkColor colors[] = { 0, 0xFF000000 };
auto sh = SkGradientShader::MakeRadial({r.centerX(), r.centerY()}, r.width(),
colors, nullptr, SK_ARRAY_COUNT(colors),
SkTileMode::kClamp);
SkPaint redPaint;
redPaint.setColor(SK_ColorRED);
SkPaint paint;
paint.setShader(sh);
canvas->drawRect(r, redPaint);
canvas->drawRect(r, paint);
canvas->translate(256, 0);
paint.setColorFilter(SkColorFilterPriv::MakeGaussian());
canvas->drawRect(r, redPaint);
canvas->drawRect(r, paint);
}

View File

@ -0,0 +1,18 @@
/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorFilterPriv_DEFINED
#define SkColorFilterPriv_DEFINED
#include "include/core/SkColorFilter.h"
class SkColorFilterPriv {
public:
static sk_sp<SkColorFilter> MakeGaussian();
};
#endif

View File

@ -17,6 +17,7 @@
#include "include/private/SkIDChangeListener.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkBlurMask.h"
#include "src/core/SkColorFilterPriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkEffectPriv.h"
@ -24,6 +25,7 @@
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkResourceCache.h"
#include "src/core/SkTLazy.h"
#include "src/core/SkVM.h"
#include "src/core/SkVerticesPriv.h"
#include "src/utils/SkShadowTessellator.h"
#include <new>
@ -40,9 +42,7 @@
*/
class SkGaussianColorFilter : public SkColorFilter {
public:
static sk_sp<SkColorFilter> Make() {
return sk_sp<SkColorFilter>(new SkGaussianColorFilter);
}
SkGaussianColorFilter() : INHERITED() {}
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
@ -55,16 +55,31 @@ protected:
rec.fPipeline->append(SkRasterPipeline::gauss_a_to_rgba);
return true;
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace* dstCS, skvm::Uniforms*,
SkArenaAlloc*) const override {
// x = 1 - x;
// exp(-x * x * 4) - 0.018f;
// ... now approximate with quartic
//
skvm::F32 c4 = p->splat(-2.26661229133605957031f);
skvm::F32 c3 = p->splat( 2.89795351028442382812f);
skvm::F32 c2 = p->splat( 0.21345567703247070312f);
skvm::F32 c1 = p->splat( 0.15489584207534790039f);
skvm::F32 c0 = p->splat( 0.00030726194381713867f);
skvm::F32 x = c.a;
x = p->mad(x, p->mad(x, p->mad(x, p->mad(x, c4, c3), c2), c1), c0);
return {x, x, x, x};
}
private:
SK_FLATTENABLE_HOOKS(SkGaussianColorFilter)
SkGaussianColorFilter() : INHERITED() {}
typedef SkColorFilter INHERITED;
};
sk_sp<SkFlattenable> SkGaussianColorFilter::CreateProc(SkReadBuffer&) {
return Make();
return SkColorFilterPriv::MakeGaussian();
}
#if SK_SUPPORT_GPU
@ -75,6 +90,10 @@ std::unique_ptr<GrFragmentProcessor> SkGaussianColorFilter::asFragmentProcessor(
}
#endif
sk_sp<SkColorFilter> SkColorFilterPriv::MakeGaussian() {
return sk_sp<SkColorFilter>(new SkGaussianColorFilter);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace {
@ -465,7 +484,7 @@ bool draw_shadow(const FACTORY& factory,
// that against our 'color' param.
paint.setColorFilter(
SkColorFilters::Blend(color, SkBlendMode::kModulate)->makeComposed(
SkGaussianColorFilter::Make()));
SkColorFilterPriv::MakeGaussian()));
drawProc(vertices.get(), SkBlendMode::kModulate, paint,
context.fTranslate.fX, context.fTranslate.fY, path.viewMatrix().hasPerspective());
@ -613,7 +632,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
paint.setColorFilter(
SkColorFilters::Blend(rec.fAmbientColor,
SkBlendMode::kModulate)->makeComposed(
SkGaussianColorFilter::Make()));
SkColorFilterPriv::MakeGaussian()));
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
success = true;
}
@ -694,7 +713,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
paint.setColorFilter(
SkColorFilters::Blend(rec.fSpotColor,
SkBlendMode::kModulate)->makeComposed(
SkGaussianColorFilter::Make()));
SkColorFilterPriv::MakeGaussian()));
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
success = true;
}