Remove GrDeviceSpaceTextureDecalFragmentProcessor.

It was used to sample clip masks using device coords.

Replace with a more generic GrDeviceSpaceEffect that simply calls a
child FP with sk_FragCoord.

Also fix issue in GrQuadPerEdgeAA GP. It wouldn't setup coord transforms
at all if they are all applied in the FS (explicit coords). Moreover,
the GrGLSLGeometryProcessor::emitTransforms() helper required a valid VS
var for local coords even when all FPs use explicit coords and wouldn't
use a local coords var.

Make CPP SkSL code gen for clone copy the explicit coord status of
children.

Change-Id: Ib8bb36028354405c8012f6e91e9eb46db75d16a6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271658
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Salomon 2020-02-20 14:21:38 -05:00 committed by Skia Commit-Bot
parent 7fba244ea9
commit af5f9f008d
10 changed files with 168 additions and 174 deletions

View File

@ -33,6 +33,7 @@
#include "src/gpu/GrFixedClip.h"
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrPaint.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrReducedClip.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
@ -40,6 +41,7 @@
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/GrUserStencilSettings.h"
#include "src/gpu/effects/GrTextureDomain.h"
#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h"
#include "tools/ToolUtils.h"
#include <utility>
@ -177,10 +179,17 @@ public:
AlphaOnlyClip(GrSurfaceProxyView mask, int x, int y) : fMask(std::move(mask)), fX(x), fY(y) {}
private:
bool apply(GrRecordingContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
bool apply(GrRecordingContext* ctx, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
SkRect* bounds) const override {
out->addCoverageFP(GrDeviceSpaceTextureDecalFragmentProcessor::Make(
fMask, SkIRect::MakeSize(fMask.proxy()->dimensions()), {fX, fY}));
GrSamplerState samplerState(GrSamplerState::WrapMode::kClampToBorder,
GrSamplerState::Filter::kNearest);
auto m = SkMatrix::MakeTrans(-fX, -fY);
auto subset = SkRect::Make(fMask.dimensions());
auto domain = bounds->makeOffset(-fX, -fY).makeInset(0.5, 0.5);
auto fp = GrTextureEffect::MakeSubset(fMask, kPremul_SkAlphaType, m, samplerState, subset,
domain, *ctx->priv().caps());
fp = GrDeviceSpaceEffect::Make(std::move(fp));
out->addCoverageFP(std::move(fp));
return true;
}
GrSurfaceProxyView fMask;

View File

@ -374,6 +374,8 @@ skia_gpu_sources = [
"$_src/gpu/effects/generated/GrConstColorProcessor.h",
"$_src/gpu/effects/generated/GrEllipseEffect.cpp",
"$_src/gpu/effects/generated/GrEllipseEffect.h",
"$_src/gpu/effects/generated/GrDeviceSpaceEffect.cpp",
"$_src/gpu/effects/generated/GrDeviceSpaceEffect.h",
"$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.cpp",
"$_src/gpu/effects/generated/GrHSLToRGBFilterEffect.h",
"$_src/gpu/effects/generated/GrLumaColorFilterEffect.cpp",

View File

@ -47,6 +47,7 @@ skia_gpu_processor_sources = [
"$_src/gpu/effects/GrConfigConversionEffect.fp",
"$_src/gpu/effects/GrConstColorProcessor.fp",
"$_src/gpu/effects/GrColorMatrixFragmentProcessor.fp",
"$_src/gpu/effects/GrDeviceSpaceEffect.fp",
"$_src/gpu/effects/GrEllipseEffect.fp",
"$_src/gpu/effects/GrHSLToRGBFilterEffect.fp",
"$_src/gpu/effects/GrLumaColorFilterEffect.fp",

View File

@ -5,12 +5,13 @@
* found in the LICENSE file.
*/
#include "src/gpu/GrClipStackClip.h"
#include "include/private/SkTo.h"
#include "src/core/SkClipOpPriv.h"
#include "src/core/SkTaskGroup.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/GrAppliedClip.h"
#include "src/gpu/GrClipStackClip.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrDeferredProxyUploader.h"
#include "src/gpu/GrDrawingManager.h"
@ -26,6 +27,7 @@
#include "src/gpu/effects/GrConvexPolyEffect.h"
#include "src/gpu/effects/GrRRectEffect.h"
#include "src/gpu/effects/GrTextureDomain.h"
#include "src/gpu/effects/generated/GrDeviceSpaceEffect.h"
#include "src/gpu/geometry/GrShape.h"
typedef SkClipStack::Element Element;
@ -78,11 +80,18 @@ void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devR
////////////////////////////////////////////////////////////////////////////////
// set up the draw state to enable the aa clipping mask.
static std::unique_ptr<GrFragmentProcessor> create_fp_for_mask(GrSurfaceProxyView mask,
const SkIRect& devBound) {
SkASSERT(mask.asTextureProxy());
SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(mask), domainTexels,
{devBound.fLeft, devBound.fTop});
const SkIRect& devBound,
const GrCaps& caps) {
GrSamplerState samplerState(GrSamplerState::WrapMode::kClampToBorder,
GrSamplerState::Filter::kNearest);
auto m = SkMatrix::MakeTrans(-devBound.fLeft, -devBound.fTop);
auto subset = SkRect::Make(devBound.size());
// We scissor to devBounds. The mask's texel centers are aligned to device space
// pixel centers. Hence this domain of texture coordinates.
auto domain = subset.makeInset(0.5, 0.5);
auto fp = GrTextureEffect::MakeSubset(std::move(mask), kPremul_SkAlphaType, m, samplerState,
subset, domain, caps);
return GrDeviceSpaceEffect::Make(std::move(fp));
}
// Does the path in 'element' require SW rendering? If so, return true (and,
@ -283,7 +292,8 @@ bool GrClipStackClip::applyClipMask(GrRecordingContext* context,
if (result) {
// The mask's top left coord should be pinned to the rounded-out top left corner of
// the clip's device space bounds.
out->addCoverageFP(create_fp_for_mask(std::move(result), reducedClip.scissor()));
out->addCoverageFP(create_fp_for_mask(std::move(result), reducedClip.scissor(),
*context->priv().caps()));
return true;
}

View File

@ -101,7 +101,7 @@ public:
kGrConicEffect_ClassID,
kGrConstColorProcessor_ClassID,
kGrConvexPolyEffect_ClassID,
kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
kGrDeviceSpaceEffect_ClassID,
kGrDiffuseLightingEffect_ClassID,
kGrDisplacementMapEffect_ClassID,
kGrDistanceFieldA8TextGeoProc_ClassID,

View File

@ -0,0 +1,22 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
in fragmentProcessor fp;
void main() {
sk_OutColor = sample(fp, sk_InColor, sk_FragCoord.xy);
}
@test(d) {
std::unique_ptr<GrFragmentProcessor> fp;
// We have a restriction that explicit coords only work for FPs with exactly one
// coord transform.
do {
fp = GrProcessorUnitTest::MakeChildFP(d);
} while (fp->numCoordTransforms() != 1);
return GrDeviceSpaceEffect::Make(std::move(fp));
}

View File

@ -314,123 +314,3 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
std::copy_n(decalFilterWeights, 3, fPrevDeclFilterWeights);
}
}
///////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(
GrSurfaceProxyView view, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) {
return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceTextureDecalFragmentProcessor(
std::move(view), subset, deviceSpaceOffset));
}
GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
GrSurfaceProxyView view, const SkIRect& subset, const SkIPoint& deviceSpaceOffset)
: INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fTextureDomain(view.proxy(),
GrTextureDomain::MakeTexelDomain(subset, GrTextureDomain::kDecal_Mode),
GrTextureDomain::kDecal_Mode, GrTextureDomain::kDecal_Mode)
, fTextureSampler(std::move(view), GrSamplerState::Filter::kNearest) {
this->setTextureSamplerCnt(1);
fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
}
GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
const GrDeviceSpaceTextureDecalFragmentProcessor& that)
: INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fTextureDomain(that.fTextureDomain)
, fTextureSampler(that.fTextureSampler)
, fDeviceSpaceOffset(that.fDeviceSpaceOffset) {
this->setTextureSamplerCnt(1);
}
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::clone() const {
return std::unique_ptr<GrFragmentProcessor>(
new GrDeviceSpaceTextureDecalFragmentProcessor(*this));
}
GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const {
class GLSLProcessor : public GrGLSLFragmentProcessor {
public:
void emitCode(EmitArgs& args) override {
const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
args.fFp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
const char* scaleAndTranslateName;
fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
kHalf4_GrSLType,
"scaleAndTranslate",
&scaleAndTranslateName);
args.fFragBuilder->codeAppendf("half2 coords = half2(sk_FragCoord.xy * %s.xy + %s.zw);",
scaleAndTranslateName, scaleAndTranslateName);
fGLDomain.sampleTexture(args.fFragBuilder,
args.fUniformHandler,
args.fShaderCaps,
dstdfp.fTextureDomain,
args.fOutputColor,
SkString("coords"),
args.fTexSamplers[0],
args.fInputColor);
}
protected:
void onSetData(const GrGLSLProgramDataManager& pdman,
const GrFragmentProcessor& fp) override {
const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
const auto& view = dstdfp.textureSampler(0).view();
SkISize textureDims = view.proxy()->backingStoreDimensions();
fGLDomain.setData(pdman, dstdfp.fTextureDomain, view,
dstdfp.textureSampler(0).samplerState());
float iw = 1.f / textureDims.width();
float ih = 1.f / textureDims.height();
float scaleAndTransData[4] = {
iw, ih,
-dstdfp.fDeviceSpaceOffset.fX * iw, -dstdfp.fDeviceSpaceOffset.fY * ih
};
if (view.origin() == kBottomLeft_GrSurfaceOrigin) {
scaleAndTransData[1] = -scaleAndTransData[1];
scaleAndTransData[3] = 1 - scaleAndTransData[3];
}
pdman.set4fv(fScaleAndTranslateUni, 1, scaleAndTransData);
}
private:
GrTextureDomain::GLDomain fGLDomain;
UniformHandle fScaleAndTranslateUni;
};
return new GLSLProcessor;
}
bool GrDeviceSpaceTextureDecalFragmentProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
return dstdfp.fTextureSampler.view().proxy()->underlyingUniqueID() ==
fTextureSampler.view().proxy()->underlyingUniqueID() &&
dstdfp.fDeviceSpaceOffset == fDeviceSpaceOffset &&
dstdfp.fTextureDomain == fTextureDomain;
}
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceTextureDecalFragmentProcessor);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::TestCreate(
GrProcessorTestData* d) {
auto [view, at, ct] = d->randomView();
SkIRect subset;
subset.fLeft = d->fRandom->nextULessThan(view.width() - 1);
subset.fRight = d->fRandom->nextRangeU(subset.fLeft, view.width());
subset.fTop = d->fRandom->nextULessThan(view.height() - 1);
subset.fBottom = d->fRandom->nextRangeU(subset.fTop, view.height());
SkIPoint pt;
pt.fX = d->fRandom->nextULessThan(2048);
pt.fY = d->fRandom->nextULessThan(2048);
return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(view), subset, pt);
}
#endif

View File

@ -231,47 +231,4 @@ protected:
int fIndex;
};
class GrDeviceSpaceTextureDecalFragmentProcessor : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView,
const SkIRect& subset,
const SkIPoint& deviceSpaceOffset);
const char* name() const override { return "GrDeviceSpaceTextureDecalFragmentProcessor"; }
#ifdef SK_DEBUG
SkString dumpInfo() const override {
SkString str;
str.appendf("Domain: [L: %.2f, T: %.2f, R: %.2f, B: %.2f] Offset: [%d %d]",
fTextureDomain.domain().fLeft, fTextureDomain.domain().fTop,
fTextureDomain.domain().fRight, fTextureDomain.domain().fBottom,
fDeviceSpaceOffset.fX, fDeviceSpaceOffset.fY);
str.append(INHERITED::dumpInfo());
return str;
}
#endif
std::unique_ptr<GrFragmentProcessor> clone() const override;
private:
GrTextureDomain fTextureDomain;
TextureSampler fTextureSampler;
SkIPoint fDeviceSpaceOffset;
GrDeviceSpaceTextureDecalFragmentProcessor(GrSurfaceProxyView, const SkIRect&, const SkIPoint&);
GrDeviceSpaceTextureDecalFragmentProcessor(const GrDeviceSpaceTextureDecalFragmentProcessor&);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
// Since we always use decal mode, there is no need for key data.
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bool onIsEqual(const GrFragmentProcessor& fp) const override;
const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; }
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
typedef GrFragmentProcessor INHERITED;
};
#endif

View File

@ -0,0 +1,71 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrDeviceSpaceEffect.fp; do not modify.
**************************************************************************************************/
#include "GrDeviceSpaceEffect.h"
#include "include/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"
class GrGLSLDeviceSpaceEffect : public GrGLSLFragmentProcessor {
public:
GrGLSLDeviceSpaceEffect() {}
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrDeviceSpaceEffect& _outer = args.fFp.cast<GrDeviceSpaceEffect>();
(void)_outer;
SkString _input204 = SkStringPrintf("%s", args.fInputColor);
SkString _sample204;
SkString _coords204("sk_FragCoord.xy");
_sample204 =
this->invokeChild(_outer.fp_index, _input204.c_str(), args, _coords204.c_str());
fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, _sample204.c_str());
}
private:
void onSetData(const GrGLSLProgramDataManager& pdman,
const GrFragmentProcessor& _proc) override {}
};
GrGLSLFragmentProcessor* GrDeviceSpaceEffect::onCreateGLSLInstance() const {
return new GrGLSLDeviceSpaceEffect();
}
void GrDeviceSpaceEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {}
bool GrDeviceSpaceEffect::onIsEqual(const GrFragmentProcessor& other) const {
const GrDeviceSpaceEffect& that = other.cast<GrDeviceSpaceEffect>();
(void)that;
return true;
}
GrDeviceSpaceEffect::GrDeviceSpaceEffect(const GrDeviceSpaceEffect& src)
: INHERITED(kGrDeviceSpaceEffect_ClassID, src.optimizationFlags()), fp_index(src.fp_index) {
{
auto clone = src.childProcessor(fp_index).clone();
clone->setSampledWithExplicitCoords(
src.childProcessor(fp_index).isSampledWithExplicitCoords());
this->registerChildProcessor(std::move(clone));
}
}
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceEffect::clone() const {
return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceEffect(*this));
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceEffect);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceEffect::TestCreate(GrProcessorTestData* d) {
std::unique_ptr<GrFragmentProcessor> fp;
// We have a restriction that explicit coords only work for FPs with exactly one
// coord transform.
do {
fp = GrProcessorUnitTest::MakeChildFP(d);
} while (fp->numCoordTransforms() != 1);
return GrDeviceSpaceEffect::Make(std::move(fp));
}
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrDeviceSpaceEffect.fp; do not modify.
**************************************************************************************************/
#ifndef GrDeviceSpaceEffect_DEFINED
#define GrDeviceSpaceEffect_DEFINED
#include "include/core/SkTypes.h"
#include "include/private/SkM44.h"
#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrFragmentProcessor.h"
class GrDeviceSpaceEffect : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceEffect(std::move(fp)));
}
GrDeviceSpaceEffect(const GrDeviceSpaceEffect& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "DeviceSpaceEffect"; }
int fp_index = -1;
private:
GrDeviceSpaceEffect(std::unique_ptr<GrFragmentProcessor> fp)
: INHERITED(kGrDeviceSpaceEffect_ClassID, kNone_OptimizationFlags) {
SkASSERT(fp);
fp_index = this->numChildProcessors();
fp->setSampledWithExplicitCoords(true);
this->registerChildProcessor(std::move(fp));
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
typedef GrFragmentProcessor INHERITED;
};
#endif