use GrFPArgs for maskfilters

Bug: skia:
Change-Id: I8516a3b0f6d8301c51f0861c65b9fe8f692fc5e5
Reviewed-on: https://skia-review.googlesource.com/97260
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Mike Reed 2018-01-19 14:03:47 -05:00 committed by Skia Commit-Bot
parent c22e50bd31
commit a99b393995
6 changed files with 54 additions and 27 deletions

View File

@ -6,7 +6,6 @@
* found in the LICENSE file.
*/
#ifndef SkMaskFilter_DEFINED
#define SkMaskFilter_DEFINED
@ -18,6 +17,7 @@
class GrClip;
class GrContext;
struct GrFPArgs;
class GrRenderTargetContext;
class GrPaint;
class GrFragmentProcessor;
@ -69,16 +69,18 @@ public:
#if SK_SUPPORT_GPU
/**
* Returns true if the filter can be expressed a single-pass GrProcessor without requiring an
* explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as
* the input color and outputs the filtered covereage value. This means that each pixel's
* filtered coverage must only depend on the unfiltered mask value for that pixel and not on
* surrounding values.
*
* If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes
* ownership of the effect and must unref it.
* Returns a processor if the filter can be expressed a single-pass GrProcessor without
* requiring an explicit input mask. Per-pixel, the effect receives the incoming mask's
* coverage as the input color and outputs the filtered covereage value. This means that each
* pixel's filtered coverage must only depend on the unfiltered mask value for that pixel and
* not on surrounding values.
*/
virtual bool asFragmentProcessor(GrFragmentProcessor**) const { return false; }
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs& args) const;
/**
* Returns true iff asFragmentProcessor() will return a processor
*/
bool hasFragmentProcessor() const;
/**
* If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass
@ -179,6 +181,11 @@ public:
protected:
SkMaskFilter() {}
#if SK_SUPPORT_GPU
virtual std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs&) const;
virtual bool onHasFragmentProcessor() const;
#endif
enum FilterReturn {
kFalse_FilterReturn,
kTrue_FilterReturn,

View File

@ -17,6 +17,7 @@
#if SK_SUPPORT_GPU
#include "GrTextureProxy.h"
#include "GrFragmentProcessor.h"
#endif
SkMaskFilter::NinePatch::~NinePatch() {
@ -301,6 +302,24 @@ SkMaskFilter::filterRectsToNine(const SkRect[], int count, const SkMatrix&,
}
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkMaskFilter::asFragmentProcessor(const GrFPArgs& args) const {
auto fp = this->onAsFragmentProcessor(args);
if (fp) {
SkASSERT(this->hasFragmentProcessor());
} else {
SkASSERT(!this->hasFragmentProcessor());
}
return fp;
}
bool SkMaskFilter::hasFragmentProcessor() const {
return this->onHasFragmentProcessor();
}
std::unique_ptr<GrFragmentProcessor> SkMaskFilter::onAsFragmentProcessor(const GrFPArgs&) const {
return nullptr;
}
bool SkMaskFilter::onHasFragmentProcessor() const { return false; }
bool SkMaskFilter::canFilterMaskGPU(const SkRRect& devRRect,
const SkIRect& clipBounds,
const SkMatrix& ctm,

View File

@ -32,16 +32,17 @@ public:
bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
SkIPoint* margin) const override;
#if SK_SUPPORT_GPU
bool asFragmentProcessor(GrFragmentProcessor**) const override;
#endif
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRRectsGaussianEdgeMaskFilterImpl)
protected:
void flatten(SkWriteBuffer&) const override;
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override;
bool onHasFragmentProcessor() const override { return true; }
#endif
private:
SkRRect fFirst;
SkRRect fSecond;
@ -509,12 +510,10 @@ private:
};
////////////////////////////////////////////////////////////////////////////
bool SkRRectsGaussianEdgeMaskFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp) const {
if (fp) {
*fp = RRectsGaussianEdgeFP::Make(fFirst, fSecond, fRadius).release();
}
return true;
std::unique_ptr<GrFragmentProcessor>
SkRRectsGaussianEdgeMaskFilterImpl::onAsFragmentProcessor(const GrFPArgs& args) const {
return RRectsGaussianEdgeFP::Make(fFirst, fSecond, fRadius);
}
#endif

View File

@ -298,7 +298,7 @@ void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
}
GrAA aa = GrAA(paint.isAntiAlias());
SkMaskFilter* mf = paint.getMaskFilter();
if (mf && !mf->asFragmentProcessor(nullptr)) {
if (mf && !mf->hasFragmentProcessor()) {
// The MaskFilter wasn't already handled in SkPaintToGrPaint
draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(grPaint), aa,
viewMatrix, mf, style, path, pathIsMutable);

View File

@ -403,8 +403,10 @@ void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
}
SkMaskFilter* mf = paint.getMaskFilter();
if (mf && mf->asFragmentProcessor(nullptr)) {
mf = nullptr; // already handled in SkPaintToGrPaint
if (mf) {
if (mf->hasFragmentProcessor()) {
mf = nullptr; // already handled in SkPaintToGrPaint
}
}
GrStyle style(paint);

View File

@ -375,6 +375,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
// Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), colorSpaceInfo);
const GrFPArgs fpArgs(context, &viewM, nullptr, skPaint.getFilterQuality(), &colorSpaceInfo);
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
// of per-vertex colors.
std::unique_ptr<GrFragmentProcessor> shaderFP;
@ -382,8 +384,7 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
if (shaderProcessor) {
shaderFP = std::move(*shaderProcessor);
} else if (const auto* shader = as_SB(skPaint.getShader())) {
shaderFP = shader->asFragmentProcessor(GrFPArgs(
context, &viewM, nullptr, skPaint.getFilterQuality(), &colorSpaceInfo));
shaderFP = shader->asFragmentProcessor(fpArgs);
}
}
@ -478,9 +479,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
SkMaskFilter* maskFilter = skPaint.getMaskFilter();
if (maskFilter) {
GrFragmentProcessor* mfFP;
if (maskFilter->asFragmentProcessor(&mfFP)) {
grPaint->addCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor>(mfFP));
if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
grPaint->addCoverageFragmentProcessor(std::move(mfFP));
}
}