aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrDrawOpTest.cpp3
-rw-r--r--src/gpu/GrGpu.h2
-rw-r--r--src/gpu/GrPLSGeometryProcessor.h35
-rw-r--r--src/gpu/GrPathRendererChain.cpp6
-rw-r--r--src/gpu/GrPrimitiveProcessor.h14
-rw-r--r--src/gpu/GrProcessorSet.cpp7
-rw-r--r--src/gpu/GrProcessorSet.h9
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp12
-rw-r--r--src/gpu/GrShaderCaps.cpp3
-rw-r--r--src/gpu/GrXferProcessor.cpp10
-rw-r--r--src/gpu/GrXferProcessor.h7
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.cpp91
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.h2
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp21
-rw-r--r--src/gpu/effects/GrDisableColorXP.cpp1
-rw-r--r--src/gpu/effects/GrDisableColorXP.h2
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp10
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.h2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp11
-rw-r--r--src/gpu/gl/GrGLGpu.cpp229
-rw-r--r--src/gpu/gl/GrGLGpu.h16
-rw-r--r--src/gpu/gl/GrGLProgram.cpp15
-rw-r--r--src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp7
-rw-r--r--src/gpu/glsl/GrGLSLFragmentShaderBuilder.h1
-rw-r--r--src/gpu/glsl/GrGLSLPLSPathRendering.h12
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp15
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h3
-rw-r--r--src/gpu/glsl/GrGLSLXferProcessor.h27
-rw-r--r--src/gpu/ops/GrDrawOp.h8
-rw-r--r--src/gpu/ops/GrPLSPathRenderer.cpp946
-rw-r--r--src/gpu/ops/GrPLSPathRenderer.h48
31 files changed, 41 insertions, 1534 deletions
diff --git a/src/gpu/GrDrawOpTest.cpp b/src/gpu/GrDrawOpTest.cpp
index 5d0aa56ee9..fcf70e0d7b 100644
--- a/src/gpu/GrDrawOpTest.cpp
+++ b/src/gpu/GrDrawOpTest.cpp
@@ -32,7 +32,6 @@ DRAW_OP_TEST_EXTERN(DIEllipseOp);
DRAW_OP_TEST_EXTERN(EllipseOp);
DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp);
-DRAW_OP_TEST_EXTERN(PLSPathOp);
DRAW_OP_TEST_EXTERN(RRectOp);
DRAW_OP_TEST_EXTERN(TesselatingPathOp);
DRAW_OP_TEST_EXTERN(TextBlobOp);
@@ -56,8 +55,6 @@ std::unique_ptr<GrDrawOp> GrRandomDrawOp(SkRandom* random, GrContext* context) {
DRAW_OP_TEST_ENTRY(EllipseOp),
DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp),
- // This currently hits an assert when the GrDisableColorXPFactory is randomly selected.
- // DRAW_OP_TEST_ENTRY(PLSPathOp),
DRAW_OP_TEST_ENTRY(RRectOp),
DRAW_OP_TEST_ENTRY(TesselatingPathOp),
DRAW_OP_TEST_ENTRY(TextBlobOp),
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 3abe8f8194..5b69ead462 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -376,7 +376,7 @@ public:
const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) = 0;
// Called by GrOpList when flushing.
- // Provides a hook for post-flush actions (e.g. PLS reset and Vulkan command buffer submits).
+ // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits).
virtual void finishOpList() {}
virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0;
diff --git a/src/gpu/GrPLSGeometryProcessor.h b/src/gpu/GrPLSGeometryProcessor.h
deleted file mode 100644
index 0640af63f0..0000000000
--- a/src/gpu/GrPLSGeometryProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrPLSGeometryProcessor_DEFINED
-#define GrPLSGeometryProcessor_DEFINED
-
-#include "GrGeometryProcessor.h"
-
-/**
- * A minor extension to GrGeometryProcessor that adds bounds tracking for pixel local storage
- * purposes.
- */
-class GrPLSGeometryProcessor : public GrGeometryProcessor {
-public:
- GrPixelLocalStorageState getPixelLocalStorageState() const override {
- return GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState;
- }
-
- const SkRect& getBounds() const {
- return fBounds;
- }
-
- void setBounds(SkRect& bounds) {
- fBounds = bounds;
- }
-
-private:
- SkRect fBounds;
-};
-
-#endif
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index b371c3ef75..6c8177f8e0 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -21,7 +21,6 @@
#include "ops/GrDashLinePathRenderer.h"
#include "ops/GrDefaultPathRenderer.h"
#include "ops/GrMSAAPathRenderer.h"
-#include "ops/GrPLSPathRenderer.h"
#include "ops/GrStencilAndCoverPathRenderer.h"
#include "ops/GrTessellatingPathRenderer.h"
@@ -54,11 +53,6 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti
if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) {
fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>());
}
- if (options.fGpuPathRenderers & GpuPathRenderers::kPLS) {
- if (caps.shaderCaps()->plsPathRenderingSupport()) {
- fChain.push_back(sk_make_sp<GrPLSPathRenderer>());
- }
- }
if (options.fGpuPathRenderers & GpuPathRenderers::kDistanceField) {
fChain.push_back(sk_make_sp<GrAADistanceFieldPathRenderer>());
}
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index b9fe7b2c8b..f5b8fe9cf0 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -35,16 +35,6 @@ class GrGLSLPrimitiveProcessor;
struct GrInitInvariantOutput;
-// Describes the state of pixel local storage with respect to the current draw.
-enum GrPixelLocalStorageState {
- // The draw is actively updating PLS.
- kDraw_GrPixelLocalStorageState,
- // The draw is a "finish" operation which is reading from PLS and writing color.
- kFinish_GrPixelLocalStorageState,
- // The draw does not use PLS.
- kDisabled_GrPixelLocalStorageState
-};
-
/*
* This class allows the GrPipeline to communicate information about the pipeline to a GrOp which
* inform its decisions for GrPrimitiveProcessor setup. These are not properly part of the pipeline
@@ -167,10 +157,6 @@ public:
virtual bool isPathRendering() const { return false; }
- virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
- return kDisabled_GrPixelLocalStorageState;
- }
-
/**
* If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
*/
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index c61fe8bc79..e5beca0382 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -38,11 +38,9 @@ GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
void GrProcessorSet::FragmentProcessorAnalysis::internalReset(const GrPipelineInput& colorInput,
const GrPipelineInput coverageInput,
const GrProcessorSet& processors,
- bool usesPLSDstRead,
const GrFragmentProcessor* clipFP,
const GrCaps& caps) {
GrProcOptInfo colorInfo(colorInput);
- fUsesPLSDstRead = usesPLSDstRead;
fCompatibleWithCoverageAsAlpha = !coverageInput.isLCDCoverage();
const GrFragmentProcessor* const* fps = processors.fFragmentProcessors.get();
@@ -91,15 +89,14 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalReset(const GrPipelineIn
void GrProcessorSet::FragmentProcessorAnalysis::reset(const GrPipelineInput& colorInput,
const GrPipelineInput coverageInput,
const GrProcessorSet& processors,
- bool usesPLSDstRead,
const GrAppliedClip& appliedClip,
const GrCaps& caps) {
- this->internalReset(colorInput, coverageInput, processors, usesPLSDstRead,
+ this->internalReset(colorInput, coverageInput, processors,
appliedClip.clipCoverageFragmentProcessor(), caps);
}
GrProcessorSet::FragmentProcessorAnalysis::FragmentProcessorAnalysis(
const GrPipelineInput& colorInput, const GrPipelineInput coverageInput, const GrCaps& caps)
: FragmentProcessorAnalysis() {
- this->internalReset(colorInput, coverageInput, GrProcessorSet(GrPaint()), false, nullptr, caps);
+ this->internalReset(colorInput, coverageInput, GrProcessorSet(GrPaint()), nullptr, caps);
}
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 722bc048bd..de8bd6944b 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -56,12 +56,12 @@ public:
class FragmentProcessorAnalysis {
public:
FragmentProcessorAnalysis() = default;
- // This version is used by a unit test that assumes no clip, no processors, and no PLS.
+ // This version is used by a unit test that assumes no clip and no fragment processors.
FragmentProcessorAnalysis(const GrPipelineInput& colorInput,
const GrPipelineInput coverageInput, const GrCaps&);
void reset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput,
- const GrProcessorSet&, bool usesPLSDstRead, const GrAppliedClip&, const GrCaps&);
+ const GrProcessorSet&, const GrAppliedClip&, const GrCaps&);
int initialColorProcessorsToEliminate(GrColor* newInputColor) const {
if (fInitialColorProcessorsToEliminate > 0) {
@@ -70,7 +70,6 @@ public:
return fInitialColorProcessorsToEliminate;
}
- bool usesPLSDstRead() const { return fUsesPLSDstRead; }
bool usesLocalCoords() const { return fUsesLocalCoords; }
bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
bool isOutputColorOpaque() const {
@@ -89,13 +88,11 @@ public:
private:
void internalReset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput,
- const GrProcessorSet&, bool usesPLSDstRead,
- const GrFragmentProcessor* clipFP, const GrCaps&);
+ const GrProcessorSet&, const GrFragmentProcessor* clipFP, const GrCaps&);
enum class ColorType { kUnknown, kOpaqueConstant, kConstant, kOpaque };
enum class CoverageType { kNone, kSingleChannel, kLCD };
- bool fUsesPLSDstRead = false;
bool fCompatibleWithCoverageAsAlpha = true;
bool fUsesLocalCoords = false;
CoverageType fCoverageType = CoverageType::kNone;
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 6edab11beb..6a7f7573e0 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -298,18 +298,6 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
}
args.fCaps = this->caps();
args.fAnalysis = &analysis;
- if (analysis.usesPLSDstRead()) {
- int width = renderTargetContext->width();
- int height = renderTargetContext->height();
- SkIRect ibounds;
- ibounds.fLeft = SkTPin(SkScalarFloorToInt(op->bounds().fLeft), 0, width);
- ibounds.fTop = SkTPin(SkScalarFloorToInt(op->bounds().fTop), 0, height);
- ibounds.fRight = SkTPin(SkScalarCeilToInt(op->bounds().fRight), 0, width);
- ibounds.fBottom = SkTPin(SkScalarCeilToInt(op->bounds().fBottom), 0, height);
- if (!appliedClip.addScissor(ibounds)) {
- return;
- }
- }
if (!renderTargetContext->accessRenderTarget()) {
return;
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index 69af070bc7..e3e6b07361 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -47,7 +47,6 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fTexelBufferSupport = false;
fImageLoadStoreSupport = false;
fShaderPrecisionVaries = false;
- fPLSPathRenderingSupport = false;
fDropsTileOnZeroDivide = false;
fFBFetchSupport = false;
fFBFetchNeedsCustomOutput = false;
@@ -67,8 +66,6 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fExternalTextureSupport = false;
fTexelFetchSupport = false;
- fPixelLocalStorageSize = 0;
-
fVersionDeclString = nullptr;
fShaderDerivativeExtensionString = nullptr;
fFragCoordConventionsExtensionString = nullptr;
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index a926812818..3b8a2bfb87 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -188,7 +188,7 @@ bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& c
const GrProcessorSet::FragmentProcessorAnalysis& analysis) {
bool result;
if (factory) {
- result = !analysis.usesPLSDstRead() && !caps.shaderCaps()->dstReadInShaderSupport() &&
+ result = !caps.shaderCaps()->dstReadInShaderSupport() &&
factory->willReadDstInShader(caps, analysis);
} else {
result = GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(caps, analysis);
@@ -197,14 +197,6 @@ bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& c
return result;
}
-bool GrXPFactory::willReadDstInShader(const GrCaps& caps,
- const FragmentProcessorAnalysis& analysis) const {
- if (analysis.usesPLSDstRead()) {
- return true;
- }
- return this->onWillReadDstInShader(caps, analysis);
-}
-
GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis,
bool hasMixedSamples,
const DstTexture* dstTexture,
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index c00bcbeff2..d6d6fa33e3 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -325,14 +325,11 @@ private:
bool hasMixedSamples,
const DstTexture*) const = 0;
- bool willReadDstInShader(const GrCaps& caps, const FragmentProcessorAnalysis& analysis) const;
-
/**
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
- * shader. This will not be called for draws that read from PLS since the dst color is always
- * available in such draws.
+ * shader.
*/
- virtual bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const = 0;
+ virtual bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const = 0;
};
#if defined(__GNUC__) || defined(__clang)
#pragma GCC diagnostic pop
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index d86467e668..52ebaad309 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -142,94 +142,6 @@ void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) cons
///////////////////////////////////////////////////////////////////////////////
-class ShaderCSOXferProcessor : public GrXferProcessor {
-public:
- ShaderCSOXferProcessor(const DstTexture* dstTexture,
- bool hasMixedSamples,
- SkRegion::Op regionOp,
- bool invertCoverage)
- : INHERITED(dstTexture, true, hasMixedSamples)
- , fRegionOp(regionOp)
- , fInvertCoverage(invertCoverage) {
- this->initClassID<ShaderCSOXferProcessor>();
- }
-
- const char* name() const override { return "Coverage Set Op Shader"; }
-
- GrGLSLXferProcessor* createGLSLInstance() const override;
-
- SkRegion::Op regionOp() const { return fRegionOp; }
- bool invertCoverage() const { return fInvertCoverage; }
-
-private:
- GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override {
- // We never look at the color input
- return GrXferProcessor::kIgnoreColor_OptFlag;
- }
-
- void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
-
- bool onIsEqual(const GrXferProcessor& xpBase) const override {
- const ShaderCSOXferProcessor& xp = xpBase.cast<ShaderCSOXferProcessor>();
- return (fRegionOp == xp.fRegionOp &&
- fInvertCoverage == xp.fInvertCoverage);
- }
-
- SkRegion::Op fRegionOp;
- bool fInvertCoverage;
-
- typedef GrXferProcessor INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class GLShaderCSOXferProcessor : public GrGLSLXferProcessor {
-public:
- static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) {
- const ShaderCSOXferProcessor& xp = processor.cast<ShaderCSOXferProcessor>();
- b->add32(xp.regionOp());
- uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
- b->add32(key);
- }
-
-private:
- void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const char* srcColor,
- const char* srcCoverage,
- const char* dstColor,
- const char* outColor,
- const char* outColorSecondary,
- const GrXferProcessor& proc) override {
- const ShaderCSOXferProcessor& xp = proc.cast<ShaderCSOXferProcessor>();
-
- if (xp.invertCoverage()) {
- fragBuilder->codeAppendf("%s = 1.0 - %s;", outColor, srcCoverage);
- } else {
- fragBuilder->codeAppendf("%s = %s;", outColor, srcCoverage);
- }
-
- GrGLSLBlend::AppendRegionOp(fragBuilder, outColor, dstColor, outColor, xp.regionOp());
- }
-
- void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
-
- typedef GrGLSLXferProcessor INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-void ShaderCSOXferProcessor::onGetGLSLProcessorKey(const GrShaderCaps&,
- GrProcessorKeyBuilder* b) const {
- GLShaderCSOXferProcessor::GenKey(*this, b);
-}
-
-GrGLSLXferProcessor* ShaderCSOXferProcessor::createGLSLInstance() const {
- return new GLShaderCSOXferProcessor;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
constexpr GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp,
bool invertCoverage)
: fRegionOp(regionOp), fInvertCoverage(invertCoverage) {}
@@ -328,9 +240,6 @@ GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(
return nullptr;
}
- if (analysis.usesPLSDstRead()) {
- return new ShaderCSOXferProcessor(dst, hasMixedSamples, fRegionOp, fInvertCoverage);
- }
return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
}
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index ed6b9aa9f0..02db11b811 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -41,7 +41,7 @@ private:
bool hasMixedSamples,
const DstTexture*) const override;
- bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override {
+ bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override {
return false;
}
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index ccbab73f86..8895d7c02b 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -52,16 +52,11 @@ static constexpr GrBlendEquation hw_blend_equation(SkBlendMode mode) {
#undef EQ_OFFSET
}
-static bool can_use_hw_blend_equation(GrBlendEquation equation,
- bool usePLSRead,
- bool isLCDCoverage,
+static bool can_use_hw_blend_equation(GrBlendEquation equation, bool isLCDCoverage,
const GrCaps& caps) {
if (!caps.advancedBlendEquationSupport()) {
return false;
}
- if (usePLSRead) {
- return false;
- }
if (isLCDCoverage) {
return false; // LCD coverage must be applied after the blend equation.
}
@@ -334,7 +329,7 @@ private:
bool willReadsDst(const FragmentProcessorAnalysis&) const override { return true; }
- bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override;
+ bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override;
GR_DECLARE_XP_FACTORY_TEST;
@@ -352,20 +347,16 @@ GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
bool hasMixedSamples,
const DstTexture* dstTexture) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
- if (can_use_hw_blend_equation(fHWBlendEquation, analysis.usesPLSDstRead(),
- analysis.hasLCDCoverage(), caps)) {
+ if (can_use_hw_blend_equation(fHWBlendEquation, analysis.hasLCDCoverage(), caps)) {
SkASSERT(!dstTexture || !dstTexture->texture());
return new CustomXP(fMode, fHWBlendEquation);
}
return new CustomXP(dstTexture, hasMixedSamples, fMode);
}
-bool CustomXPFactory::onWillReadDstInShader(const GrCaps& caps,
- const FragmentProcessorAnalysis& analysis) const {
- // This should not be called if we're using PLS dst read.
- static constexpr bool kUsesPLSRead = false;
- return !can_use_hw_blend_equation(fHWBlendEquation, kUsesPLSRead, analysis.hasLCDCoverage(),
- caps);
+bool CustomXPFactory::willReadDstInShader(const GrCaps& caps,
+ const FragmentProcessorAnalysis& analysis) const {
+ return !can_use_hw_blend_equation(fHWBlendEquation, analysis.hasLCDCoverage(), caps);
}
GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory);
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 6bdf1885e9..f95cd9b81a 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -90,7 +90,6 @@ GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(
const FragmentProcessorAnalysis& analysis,
bool hasMixedSamples,
const DstTexture* dst) const {
- SkASSERT(!analysis.usesPLSDstRead());
return DisableColorXP::Create();
}
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index b4cd00a599..6a9f2add17 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -28,7 +28,7 @@ private:
constexpr GrDisableColorXPFactory() {}
- bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override {
+ bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override {
return false;
}
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 7378874da9..c7e61cace3 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -735,9 +735,6 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(
const FragmentProcessorAnalysis& analysis,
bool hasMixedSamples,
const DstTexture* dstTexture) const {
- if (analysis.usesPLSDstRead()) {
- return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode);
- }
BlendFormula blendFormula;
if (analysis.hasLCDCoverage()) {
if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() &&
@@ -768,8 +765,8 @@ bool GrPorterDuffXPFactory::willReadsDst(const FragmentProcessorAnalysis& analys
return (colorFormula.usesDstColor() || analysis.hasCoverage());
}
-bool GrPorterDuffXPFactory::onWillReadDstInShader(const GrCaps& caps,
- const FragmentProcessorAnalysis& analysis) const {
+bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps,
+ const FragmentProcessorAnalysis& analysis) const {
if (caps.shaderCaps()->dualSourceBlendingSupport()) {
return false;
}
@@ -830,9 +827,6 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
const FragmentProcessorAnalysis& analysis,
bool hasMixedSamples,
const GrXferProcessor::DstTexture* dstTexture) {
- if (analysis.usesPLSDstRead()) {
- return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
- }
// We want to not make an xfer processor if possible. Thus for the simple case where we are not
// doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index 6d7dc90fcf..b82c1068ff 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -52,7 +52,7 @@ private:
bool hasMixedSamples,
const DstTexture*) const override;
- bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override;
+ bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override;
GR_DECLARE_XP_FACTORY_TEST;
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 0bcb7e817b..d2e18995a3 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -290,17 +290,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
}
- if (ctxInfo.hasExtension("GL_EXT_shader_pixel_local_storage")) {
- #define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
- GR_GL_GetIntegerv(gli, GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT,
- &shaderCaps->fPixelLocalStorageSize);
- shaderCaps->fPLSPathRenderingSupport = shaderCaps->fFBFetchSupport;
- }
- else {
- shaderCaps->fPixelLocalStorageSize = 0;
- shaderCaps->fPLSPathRenderingSupport = false;
- }
-
// Protect ourselves against tracking huge amounts of texture state.
static const uint8_t kMaxSaneSamplers = 32;
GrGLint maxSamplers;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index cfbef9fd7a..bda1c16b59 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -16,7 +16,6 @@
#include "GrGLTextureRenderTarget.h"
#include "GrGpuResourcePriv.h"
#include "GrMesh.h"
-#include "GrPLSGeometryProcessor.h"
#include "GrPipeline.h"
#include "GrRenderTargetPriv.h"
#include "GrShaderCaps.h"
@@ -32,7 +31,6 @@
#include "SkTemplates.h"
#include "SkTypes.h"
#include "builders/GrGLShaderStringBuilder.h"
-#include "glsl/GrGLSLPLSPathRendering.h"
#include "instanced/GLInstancedRendering.h"
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
@@ -206,8 +204,6 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
, fTempDstFBOID(0)
, fStencilClearFBOID(0)
, fHWMaxUsedBufferTextureUnit(-1)
- , fHWPLSEnabled(false)
- , fPLSHasBeenUsed(false)
, fHWMinSampleShading(0.0) {
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
fCopyPrograms[i].fProgram = 0;
@@ -216,7 +212,6 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
fMipmapPrograms[i].fProgram = 0;
}
fWireRectProgram.fProgram = 0;
- fPLSSetupProgram.fProgram = 0;
SkASSERT(ctx);
fCaps.reset(SkRef(ctx->caps()));
@@ -274,7 +269,6 @@ GrGLGpu::~GrGLGpu() {
fCopyProgramArrayBuffer.reset();
fMipmapProgramArrayBuffer.reset();
fWireRectArrayBuffer.reset();
- fPLSSetupProgram.fArrayBuffer.reset();
if (0 != fHWProgramID) {
// detach the current program so there is no confusion on OpenGL's part
@@ -308,129 +302,9 @@ GrGLGpu::~GrGLGpu() {
GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
}
- if (0 != fPLSSetupProgram.fProgram) {
- GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
- }
-
delete fProgramCache;
}
-bool GrGLGpu::createPLSSetupProgram() {
- if (!fPLSSetupProgram.fArrayBuffer) {
- static const GrGLfloat vdata[] = {
- 0, 0,
- 0, 1,
- 1, 0,
- 1, 1
- };
- fPLSSetupProgram.fArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata),
- kVertex_GrBufferType,
- kStatic_GrAccessPattern, vdata));
- if (!fPLSSetupProgram.fArrayBuffer) {
- return false;
- }
- }
-
- SkASSERT(!fPLSSetupProgram.fProgram);
- GL_CALL_RET(fPLSSetupProgram.fProgram, CreateProgram());
- if (!fPLSSetupProgram.fProgram) {
- return false;
- }
-
- const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
- const char* version = shaderCaps->versionDeclString();
-
- GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
- GrShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
- GrShaderVar::kUniform_TypeModifier);
- GrShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
- GrShaderVar uTexture("u_texture", kTexture2DSampler_GrSLType,
- GrShaderVar::kUniform_TypeModifier);
- GrShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kOut_TypeModifier);
-
- SkString vshaderTxt(version);
- if (shaderCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
- vshaderTxt.appendf("#extension %s : require\n", extension);
- }
- vTexCoord.addModifier("noperspective");
- }
- aVertex.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uPosXform.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- vTexCoord.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
-
- vshaderTxt.append(
- "// PLS Setup Program VS\n"
- "void main() {"
- " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
- " gl_Position.zw = vec2(0, 1);"
- "}"
- );
-
- SkString fshaderTxt(version);
- if (shaderCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
- fshaderTxt.appendf("#extension %s : require\n", extension);
- }
- }
- fshaderTxt.append("#extension ");
- fshaderTxt.append(shaderCaps->fbFetchExtensionString());
- fshaderTxt.append(" : require\n");
- fshaderTxt.append("#extension GL_EXT_shader_pixel_local_storage : require\n");
- GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, &fshaderTxt);
- vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
- vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
- fshaderTxt.append(";");
- uTexture.appendDecl(shaderCaps, &fshaderTxt);
- fshaderTxt.append(";");
-
- fshaderTxt.appendf(
- "// PLS Setup Program FS\n"
- GR_GL_PLS_PATH_DATA_DECL
- "void main() {\n"
- " " GR_GL_PLS_DSTCOLOR_NAME " = gl_LastFragColorARM;\n"
- " pls.windings = ivec4(0, 0, 0, 0);\n"
- "}"
- );
-
- const char* str;
- GrGLint length;
-
- str = vshaderTxt.c_str();
- length = SkToInt(vshaderTxt.size());
- SkSL::Program::Settings settings;
- settings.fCaps = shaderCaps;
- SkSL::Program::Inputs inputs;
- GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fPLSSetupProgram.fProgram,
- GR_GL_VERTEX_SHADER, &str, &length, 1, &fStats,
- settings, &inputs);
- SkASSERT(inputs.isEmpty());
-
- str = fshaderTxt.c_str();
- length = SkToInt(fshaderTxt.size());
- GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fPLSSetupProgram.fProgram,
- GR_GL_FRAGMENT_SHADER, &str, &length, 1, &fStats,
- settings, &inputs);
- SkASSERT(inputs.isEmpty());
-
- GL_CALL(LinkProgram(fPLSSetupProgram.fProgram));
-
- GL_CALL_RET(fPLSSetupProgram.fPosXformUniform, GetUniformLocation(fPLSSetupProgram.fProgram,
- "u_posXform"));
-
- GL_CALL(BindAttribLocation(fPLSSetupProgram.fProgram, 0, "a_vertex"));
-
- GL_CALL(DeleteShader(vshader));
- GL_CALL(DeleteShader(fshader));
-
- return true;
-}
-
void GrGLGpu::disconnect(DisconnectType type) {
INHERITED::disconnect(type);
if (DisconnectType::kCleanup == type) {
@@ -459,9 +333,6 @@ void GrGLGpu::disconnect(DisconnectType type) {
if (fWireRectProgram.fProgram) {
GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
}
- if (fPLSSetupProgram.fProgram) {
- GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
- }
} else {
if (fProgramCache) {
fProgramCache->abandon();
@@ -485,8 +356,6 @@ void GrGLGpu::disconnect(DisconnectType type) {
}
fWireRectProgram.fProgram = 0;
fWireRectArrayBuffer.reset();
- fPLSSetupProgram.fProgram = 0;
- fPLSSetupProgram.fArrayBuffer.reset();
if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
this->glPathRendering()->disconnect(type);
}
@@ -2672,25 +2541,6 @@ GrGpuCommandBuffer* GrGLGpu::createCommandBuffer(
return new GrGLGpuCommandBuffer(this);
}
-void GrGLGpu::finishOpList() {
- if (fPLSHasBeenUsed) {
- /* There is an ARM driver bug where if we use PLS, and then draw a frame which does not
- * use PLS, it leaves garbage all over the place. As a workaround, we use PLS in a
- * trivial way every frame. And since we use it every frame, there's never a point at which
- * it becomes safe to stop using this workaround once we start.
- */
- this->disableScissor();
- this->disableWindowRectangles();
- // using PLS in the presence of MSAA results in GL_INVALID_OPERATION
- this->flushHWAAState(nullptr, false, false);
- SkASSERT(!fHWPLSEnabled);
- SkASSERT(fMSAAEnabled != kYes_TriState);
- GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
- this->stampPLSSetupRect(SkRect::MakeXYWH(-100.0f, -100.0f, 0.01f, 0.01f));
- GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
- }
-}
-
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, bool disableSRGB) {
SkASSERT(target);
@@ -2786,16 +2636,6 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
if (!this->flushGLState(pipeline, primProc, hasPoints)) {
return;
}
- GrPixelLocalStorageState plsState = primProc.getPixelLocalStorageState();
- if (!fHWPLSEnabled && plsState !=
- GrPixelLocalStorageState::kDisabled_GrPixelLocalStorageState) {
- GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
- this->setupPixelLocalStorage(pipeline, primProc);
- fHWPLSEnabled = true;
- }
- if (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
- this->disableStencil();
- }
for (int i = 0; i < meshCount; ++i) {
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
@@ -2840,16 +2680,6 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
} while ((nonInstMesh = iter.next()));
}
- if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
- // PLS draws always involve multiple draws, finishing up with a non-PLS
- // draw that writes to the color buffer. That draw ends up here; we wait
- // until after it is complete to actually disable PLS.
- GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
- fHWPLSEnabled = false;
- this->disableScissor();
- this->disableWindowRectangles();
- }
-
#if SWAP_PER_DRAW
glFlush();
#if defined(SK_BUILD_FOR_MAC)
@@ -2864,65 +2694,6 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
#endif
}
-void GrGLGpu::stampPLSSetupRect(const SkRect& bounds) {
- SkASSERT(this->caps()->shaderCaps()->plsPathRenderingSupport());
-
- if (!fPLSSetupProgram.fProgram) {
- if (!this->createPLSSetupProgram()) {
- SkDebugf("Failed to create PLS setup program.\n");
- return;
- }
- }
-
- GL_CALL(UseProgram(fPLSSetupProgram.fProgram));
- this->fHWVertexArrayState.setVertexArrayID(this, 0);
-
- GrGLAttribArrayState* attribs = this->fHWVertexArrayState.bindInternalVertexArray(this);
- attribs->set(this, 0, fPLSSetupProgram.fArrayBuffer.get(), kVec2f_GrVertexAttribType,
- 2 * sizeof(GrGLfloat), 0);
- attribs->disableUnusedArrays(this, 0x1);
-
- GL_CALL(Uniform4f(fPLSSetupProgram.fPosXformUniform, bounds.width(), bounds.height(),
- bounds.left(), bounds.top()));
-
- GrXferProcessor::BlendInfo blendInfo;
- blendInfo.reset();
- this->flushBlend(blendInfo, GrSwizzle());
- this->flushColorWrite(true);
- this->flushDrawFace(GrDrawFace::kBoth);
- if (!fHWStencilSettings.isDisabled()) {
- GL_CALL(Disable(GR_GL_STENCIL_TEST));
- }
- GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
- GL_CALL(UseProgram(fHWProgramID));
- if (!fHWStencilSettings.isDisabled()) {
- GL_CALL(Enable(GR_GL_STENCIL_TEST));
- }
-}
-
-void GrGLGpu::setupPixelLocalStorage(const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc) {
- fPLSHasBeenUsed = true;
- const SkRect& bounds =
- static_cast<const GrPLSGeometryProcessor&>(primProc).getBounds();
- // setup pixel local storage -- this means capturing and storing the current framebuffer color
- // and initializing the winding counts to zero
- GrRenderTarget* rt = pipeline.getRenderTarget();
- SkScalar width = SkIntToScalar(rt->width());
- SkScalar height = SkIntToScalar(rt->height());
- // dst rect edges in NDC (-1 to 1)
- // having some issues with rounding, just expand the bounds by 1 and trust the scissor to keep
- // it contained properly
- GrGLfloat dx0 = 2.0f * (bounds.left() - 1) / width - 1.0f;
- GrGLfloat dx1 = 2.0f * (bounds.right() + 1) / width - 1.0f;
- GrGLfloat dy0 = -2.0f * (bounds.top() - 1) / height + 1.0f;
- GrGLfloat dy1 = -2.0f * (bounds.bottom() + 1) / height + 1.0f;
- SkRect deviceBounds = SkRect::MakeXYWH(dx0, dy0, dx1 - dx0, dy1 - dy0);
-
- GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
- this->stampPLSSetupRect(deviceBounds);
-}
-
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 57068fb916..564ed7629a 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -144,8 +144,6 @@ public:
void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override;
- void finishOpList() override;
-
GrFence SK_WARN_UNUSED_RESULT insertFence() override;
bool waitFence(GrFence, uint64_t timeout) override;
void deleteFence(GrFence) const override;
@@ -273,10 +271,6 @@ private:
const SkIPoint& dstPoint);
bool generateMipmap(GrGLTexture* texture, bool gammaCorrect);
- void stampPLSSetupRect(const SkRect& bounds);
-
- void setupPixelLocalStorage(const GrPipeline&, const GrPrimitiveProcessor&);
-
static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
class ProgramCache : public ::SkNoncopyable {
@@ -404,7 +398,6 @@ private:
bool createCopyProgram(GrTexture* srcTexture);
bool createMipmapProgram(int progIdx);
bool createWireRectProgram();
- bool createPLSSetupProgram();
// GL program-related state
ProgramCache* fProgramCache;
@@ -647,15 +640,6 @@ private:
return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
}
- struct {
- GrGLuint fProgram;
- GrGLint fPosXformUniform;
- sk_sp<GrGLBuffer> fArrayBuffer;
- } fPLSSetupProgram;
-
- bool fHWPLSEnabled;
- bool fPLSHasBeenUsed;
-
float fHWMinSampleShading;
typedef GrGpu INHERITED;
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index f09b66869f..d9e73f04e4 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -77,12 +77,9 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
this->setFragmentData(primProc, pipeline, &nextSamplerIdx);
- if (primProc.getPixelLocalStorageState() !=
- GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
- const GrXferProcessor& xp = pipeline.getXferProcessor();
- fXferProcessor->setData(fProgramDataManager, xp);
- this->bindTextures(xp, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
- }
+ const GrXferProcessor& xp = pipeline.getXferProcessor();
+ fXferProcessor->setData(fProgramDataManager, xp);
+ this->bindTextures(xp, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
}
void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
@@ -93,12 +90,6 @@ void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
while (const GrFragmentProcessor* fp = iter.next()) {
this->generateMipmaps(*fp, pipeline.getAllowSRGBInputs());
}
-
- if (primProc.getPixelLocalStorageState() !=
- GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
- const GrXferProcessor& xp = pipeline.getXferProcessor();
- this->generateMipmaps(xp, pipeline.getAllowSRGBInputs());
- }
}
void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index f583420f29..a1f5173436 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -96,13 +96,6 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p
bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
const GrShaderCaps& shaderCaps = *fProgramBuilder->shaderCaps();
switch (feature) {
- case kPixelLocalStorage_GLSLFeature:
- if (shaderCaps.pixelLocalStorageSize() <= 0) {
- return false;
- }
- this->addFeature(1 << kPixelLocalStorage_GLSLFeature,
- "GL_EXT_shader_pixel_local_storage");
- return true;
case kMultisampleInterpolation_GLSLFeature:
if (!shaderCaps.multisampleInterpolationSupport()) {
return false;
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index ab806ea914..764f3bd812 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -29,7 +29,6 @@ public:
* if code is added that uses one of these features without calling enableFeature()
*/
enum GLSLFeature {
- kPixelLocalStorage_GLSLFeature = kLastGLSLPrivateFeature + 1,
kMultisampleInterpolation_GLSLFeature
};
diff --git a/src/gpu/glsl/GrGLSLPLSPathRendering.h b/src/gpu/glsl/GrGLSLPLSPathRendering.h
deleted file mode 100644
index 60889e98d2..0000000000
--- a/src/gpu/glsl/GrGLSLPLSPathRendering.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#define GR_GL_PLS_DSTCOLOR_NAME "pls.dstColor"
-#define GR_GL_PLS_PATH_DATA_DECL "__pixel_localEXT PLSData {\n"\
- " layout(rgba8i) ivec4 windings;\n"\
- " layout(rgba8) vec4 dstColor;\n"\
- "} pls;\n"
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 385026a52d..1fcf0405f7 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -62,12 +62,8 @@ bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage);
this->emitAndInstallFragProcs(inputColor, inputCoverage);
- if (primProc.getPixelLocalStorageState() !=
- GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
- this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor,
- *inputCoverage, primProc.getPixelLocalStorageState());
- this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
- }
+ this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage);
+ this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
return this->checkSamplerCounts() && this->checkImageStorageCounts();
}
@@ -217,8 +213,7 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
const GrGLSLExpr4& colorIn,
- const GrGLSLExpr4& coverageIn,
- GrPixelLocalStorageState plsState) {
+ const GrGLSLExpr4& coverageIn) {
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
@@ -243,7 +238,6 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
SkSTArray<2, ImageStorageHandle> imageStorageArray(xp.numImageStorages());
this->emitSamplersAndImageStorages(xp, &texSamplers, &bufferSamplers, &imageStorageArray);
- bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
GrGLSLXferProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->shaderCaps(),
@@ -253,8 +247,7 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
fFS.getSecondaryColorOutputName(),
texSamplers.begin(),
bufferSamplers.begin(),
- imageStorageArray.begin(),
- usePLSDstRead);
+ imageStorageArray.begin());
fXferProcessor->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 321d81cad2..748664625f 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -154,8 +154,7 @@ private:
GrGLSLExpr4* output);
void emitAndInstallXferProc(const GrXferProcessor&,
const GrGLSLExpr4& colorIn,
- const GrGLSLExpr4& coverageIn,
- GrPixelLocalStorageState plsState);
+ const GrGLSLExpr4& coverageIn);
void emitSamplersAndImageStorages(const GrProcessor& processor,
SkTArray<SamplerHandle>* outTexSamplerHandles,
SkTArray<SamplerHandle>* outBufferSamplerHandles,
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.h b/src/gpu/glsl/GrGLSLXferProcessor.h
index 90c1bce5b2..b4bde37e30 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ b/src/gpu/glsl/GrGLSLXferProcessor.h
@@ -35,20 +35,18 @@ public:
const char* outputSecondary,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
- const ImageStorageHandle* imageStorages,
- const bool usePLSDstRead)
- : fXPFragBuilder(fragBuilder)
- , fUniformHandler(uniformHandler)
- , fShaderCaps(caps)
- , fXP(xp)
- , fInputColor(inputColor)
- , fInputCoverage(inputCoverage)
- , fOutputPrimary(outputPrimary)
- , fOutputSecondary(outputSecondary)
- , fTexSamplers(texSamplers)
- , fBufferSamplers(bufferSamplers)
- , fImageStorages(imageStorages)
- , fUsePLSDstRead(usePLSDstRead) {}
+ const ImageStorageHandle* imageStorages)
+ : fXPFragBuilder(fragBuilder)
+ , fUniformHandler(uniformHandler)
+ , fShaderCaps(caps)
+ , fXP(xp)
+ , fInputColor(inputColor)
+ , fInputCoverage(inputCoverage)
+ , fOutputPrimary(outputPrimary)
+ , fOutputSecondary(outputSecondary)
+ , fTexSamplers(texSamplers)
+ , fBufferSamplers(bufferSamplers)
+ , fImageStorages(imageStorages) {}
GrGLSLXPFragmentBuilder* fXPFragBuilder;
GrGLSLUniformHandler* fUniformHandler;
@@ -61,7 +59,6 @@ public:
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
const ImageStorageHandle* fImageStorages;
- bool fUsePLSDstRead;
};
/**
* This is similar to emitCode() in the base class, except it takes a full shader builder.
diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h
index 1512642bb4..18c218fc9a 100644
--- a/src/gpu/ops/GrDrawOp.h
+++ b/src/gpu/ops/GrDrawOp.h
@@ -70,8 +70,7 @@ public:
const GrCaps& caps) const {
FragmentProcessorAnalysisInputs input;
this->getFragmentProcessorAnalysisInputs(&input);
- analysis->reset(*input.colorInput(), *input.coverageInput(), processors,
- input.usesPLSDstRead(), appliedClip, caps);
+ analysis->reset(*input.colorInput(), *input.coverageInput(), processors, appliedClip, caps);
}
protected:
@@ -121,14 +120,9 @@ protected:
GrPipelineInput* colorInput() { return &fColorInput; }
GrPipelineInput* coverageInput() { return &fCoverageInput; }
- void setUsesPLSDstRead() { fUsesPLSDstRead = true; }
-
- bool usesPLSDstRead() const { return fUsesPLSDstRead; }
-
private:
GrPipelineInput fColorInput;
GrPipelineInput fCoverageInput;
- bool fUsesPLSDstRead = false;
};
private:
diff --git a/src/gpu/ops/GrPLSPathRenderer.cpp b/src/gpu/ops/GrPLSPathRenderer.cpp
deleted file mode 100644
index ac2f4fcf2b..0000000000
--- a/src/gpu/ops/GrPLSPathRenderer.cpp
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrPLSPathRenderer.h"
-
-#include "GrCaps.h"
-#include "GrContext.h"
-#include "GrDefaultGeoProcFactory.h"
-#include "GrDrawOpTest.h"
-#include "GrOpFlushState.h"
-#include "GrPLSGeometryProcessor.h"
-#include "GrPathUtils.h"
-#include "GrPipelineBuilder.h"
-#include "GrProcessor.h"
-#include "GrStyle.h"
-#include "GrTessellator.h"
-#include "SkChunkAlloc.h"
-#include "SkGeometry.h"
-#include "SkPathPriv.h"
-#include "SkString.h"
-#include "SkTSort.h"
-#include "SkTraceEvent.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "glsl/GrGLSLGeometryProcessor.h"
-#include "glsl/GrGLSLPLSPathRendering.h"
-#include "ops/GrMeshDrawOp.h"
-
-GrPLSPathRenderer::GrPLSPathRenderer() {
-}
-
-struct PLSVertex {
- SkPoint fPos;
- // for triangles, these are the three triangle vertices
- // for quads, vert1 is the texture UV coords, and vert2 and vert3 are the line segment
- // comprising the flat edge of the quad
- SkPoint fVert1;
- SkPoint fVert2;
- SkPoint fVert3;
- int fWinding;
-};
-typedef SkTArray<PLSVertex, true> PLSVertices;
-
-typedef SkTArray<SkPoint, true> FinishVertices;
-
-static const float kCubicTolerance = 0.5f;
-static const float kConicTolerance = 0.5f;
-
-static const float kBloatSize = 1.0f;
-
-static const float kBloatLimit = 640000.0f;
-
-#define kQuadNumVertices 5
-static void add_quad(SkPoint pts[3], PLSVertices& vertices) {
- SkPoint normal = SkPoint::Make(pts[0].fY - pts[2].fY,
- pts[2].fX - pts[0].fX);
- normal.setLength(kBloatSize);
- SkScalar cross = (pts[1] - pts[0]).cross(pts[2] - pts[0]);
- if (cross < 0) {
- normal = -normal;
- }
- PLSVertex quad[kQuadNumVertices];
- quad[0].fPos = pts[0] + normal;
- quad[1].fPos = pts[0] - normal;
- quad[2].fPos = pts[1] - normal;
- quad[3].fPos = pts[2] - normal;
- quad[4].fPos = pts[2] + normal;
- for (int i = 0; i < kQuadNumVertices; i++) {
- quad[i].fWinding = cross < 0 ? 1 : -1;
- if (cross > 0.0) {
- quad[i].fVert2 = pts[0];
- quad[i].fVert3 = pts[2];
- }
- else {
- quad[i].fVert2 = pts[2];
- quad[i].fVert3 = pts[0];
- }
- }
- GrPathUtils::QuadUVMatrix DevToUV(pts);
- DevToUV.apply<kQuadNumVertices, sizeof(PLSVertex), sizeof(SkPoint)>(quad);
- for (int i = 2; i < kQuadNumVertices; i++) {
- vertices.push_back(quad[0]);
- vertices.push_back(quad[i - 1]);
- vertices.push_back(quad[i]);
- }
-}
-
-/* Used by bloat_tri; outsets a single point. */
-static bool outset(SkPoint* p1, SkPoint line1, SkPoint line2) {
- // rotate the two line vectors 90 degrees to form the normals, and compute
- // the dot product of the normals
- SkScalar dotProd = line1.fY * line2.fY + line1.fX * line2.fX;
- SkScalar lengthSq = 1.0f / ((1.0f - dotProd) / 2.0f);
- if (lengthSq > kBloatLimit) {
- return false;
- }
- SkPoint bisector = line1 + line2;
- bisector.setLength(SkScalarSqrt(lengthSq) * kBloatSize);
- *p1 += bisector;
- return true;
-}
-
-/* Bloats a triangle so as to create a border kBloatSize pixels wide all around it. */
-static bool bloat_tri(SkPoint pts[3]) {
- SkPoint line1 = pts[0] - pts[1];
- line1.normalize();
- SkPoint line2 = pts[0] - pts[2];
- line2.normalize();
- SkPoint line3 = pts[1] - pts[2];
- line3.normalize();
-
- SkPoint result[3];
- result[0] = pts[0];
- if (!outset(&result[0], line1, line2)) {
- return false;
- }
- result[1] = pts[1];
- if (!outset(&result[1], -line1, line3)) {
- return false;
- }
- result[2] = pts[2];
- if (!outset(&result[2], -line3, -line2)) {
- return false;
- }
- pts[0] = result[0];
- pts[1] = result[1];
- pts[2] = result[2];
- return true;
-}
-
-static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& triVertices,
- PLSVertices& quadVertices, GrResourceProvider* resourceProvider,
- SkRect bounds) {
- SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
- SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, m, bounds);
- int contourCnt;
- int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tol);
- if (maxPts <= 0) {
- return 0;
- }
- SkPath linesOnlyPath;
- linesOnlyPath.setFillType(path.getFillType());
- SkSTArray<15, SkPoint, true> quadPoints;
- SkPath::Iter iter(path, true);
- bool done = false;
- while (!done) {
- SkPoint pts[4];
- SkPath::Verb verb = iter.next(pts);
- switch (verb) {
- case SkPath::kMove_Verb:
- SkASSERT(quadPoints.count() % 3 == 0);
- for (int i = 0; i < quadPoints.count(); i += 3) {
- add_quad(&quadPoints[i], quadVertices);
- }
- quadPoints.reset();
- m.mapPoints(&pts[0], 1);
- linesOnlyPath.moveTo(pts[0]);
- break;
- case SkPath::kLine_Verb:
- m.mapPoints(&pts[1], 1);
- linesOnlyPath.lineTo(pts[1]);
- break;
- case SkPath::kQuad_Verb:
- m.mapPoints(pts, 3);
- linesOnlyPath.lineTo(pts[2]);
- quadPoints.push_back(pts[0]);
- quadPoints.push_back(pts[1]);
- quadPoints.push_back(pts[2]);
- break;
- case SkPath::kCubic_Verb: {
- m.mapPoints(pts, 4);
- SkSTArray<15, SkPoint, true> quads;
- GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, &quads);
- int count = quads.count();
- for (int q = 0; q < count; q += 3) {
- linesOnlyPath.lineTo(quads[q + 2]);
- quadPoints.push_back(quads[q]);
- quadPoints.push_back(quads[q + 1]);
- quadPoints.push_back(quads[q + 2]);
- }
- break;
- }
- case SkPath::kConic_Verb: {
- m.mapPoints(pts, 3);
- SkScalar weight = iter.conicWeight();
- SkAutoConicToQuads converter;
- const SkPoint* quads = converter.computeQuads(pts, weight, kConicTolerance);
- int count = converter.countQuads();
- for (int i = 0; i < count; ++i) {
- linesOnlyPath.lineTo(quads[2 * i + 2]);
- quadPoints.push_back(quads[2 * i]);
- quadPoints.push_back(quads[2 * i + 1]);
- quadPoints.push_back(quads[2 * i + 2]);
- }
- break;
- }
- case SkPath::kClose_Verb:
- linesOnlyPath.close();
- break;
- case SkPath::kDone_Verb:
- done = true;
- break;
- default: SkASSERT(false);
- }
- }
- SkASSERT(quadPoints.count() % 3 == 0);
- for (int i = 0; i < quadPoints.count(); i += 3) {
- add_quad(&quadPoints[i], quadVertices);
- }
-
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
- GrUniqueKey key;
- GrUniqueKey::Builder builder(&key, kDomain, 2);
- builder[0] = path.getGenerationID();
- builder[1] = path.getFillType();
- builder.finish();
- GrTessellator::WindingVertex* windingVertices;
- int triVertexCount = GrTessellator::PathToVertices(linesOnlyPath, 0, bounds, &windingVertices);
- if (triVertexCount > 0) {
- for (int i = 0; i < triVertexCount; i += 3) {
- SkPoint p1 = windingVertices[i].fPos;
- SkPoint p2 = windingVertices[i + 1].fPos;
- SkPoint p3 = windingVertices[i + 2].fPos;
- int winding = windingVertices[i].fWinding;
- SkASSERT(windingVertices[i + 1].fWinding == winding);
- SkASSERT(windingVertices[i + 2].fWinding == winding);
- SkScalar cross = (p2 - p1).cross(p3 - p1);
- SkPoint bloated[3] = { p1, p2, p3 };
- if (cross < 0.0f) {
- SkTSwap(p1, p3);
- }
- if (bloat_tri(bloated)) {
- triVertices.push_back({ bloated[0], p1, p2, p3, winding });
- triVertices.push_back({ bloated[1], p1, p2, p3, winding });
- triVertices.push_back({ bloated[2], p1, p2, p3, winding });
- }
- else {
- SkScalar minX = SkTMin(p1.fX, SkTMin(p2.fX, p3.fX)) - 1.0f;
- SkScalar minY = SkTMin(p1.fY, SkTMin(p2.fY, p3.fY)) - 1.0f;
- SkScalar maxX = SkTMax(p1.fX, SkTMax(p2.fX, p3.fX)) + 1.0f;
- SkScalar maxY = SkTMax(p1.fY, SkTMax(p2.fY, p3.fY)) + 1.0f;
- triVertices.push_back({ { minX, minY }, p1, p2, p3, winding });
- triVertices.push_back({ { maxX, minY }, p1, p2, p3, winding });
- triVertices.push_back({ { minX, maxY }, p1, p2, p3, winding });
- triVertices.push_back({ { maxX, minY }, p1, p2, p3, winding });
- triVertices.push_back({ { maxX, maxY }, p1, p2, p3, winding });
- triVertices.push_back({ { minX, maxY }, p1, p2, p3, winding });
- }
- }
- delete[] windingVertices;
- }
- return triVertexCount > 0 || quadVertices.count() > 0;
-}
-
-class PLSAATriangleEffect : public GrPLSGeometryProcessor {
-public:
-
- static GrPLSGeometryProcessor* Create(const SkMatrix& localMatrix,
- bool usesLocalCoords) {
- return new PLSAATriangleEffect(localMatrix, usesLocalCoords);
- }
-
- virtual ~PLSAATriangleEffect() {}
-
- const char* name() const override { return "PLSAATriangle"; }
-
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inVertex1() const { return fInVertex1; }
- const Attribute* inVertex2() const { return fInVertex2; }
- const Attribute* inVertex3() const { return fInVertex3; }
- const Attribute* inWindings() const { return fInWindings; }
- const SkMatrix& localMatrix() const { return fLocalMatrix; }
- bool usesLocalCoords() const { return fUsesLocalCoords; }
-
- class GLSLProcessor : public GrGLSLGeometryProcessor {
- public:
- GLSLProcessor(const GrGeometryProcessor&) {}
-
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
- const PLSAATriangleEffect& te = args.fGP.cast<PLSAATriangleEffect>();
- GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
- GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-
- varyingHandler->emitAttributes(te);
-
- this->setupPosition(vsBuilder, gpArgs, te.inPosition()->fName);
-
- GrGLSLVertToFrag v1(kVec2f_GrSLType);
- varyingHandler->addVarying("Vertex1", &v1, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
- v1.vsOut(),
- te.inVertex1()->fName,
- te.inVertex1()->fName);
-
- GrGLSLVertToFrag v2(kVec2f_GrSLType);
- varyingHandler->addVarying("Vertex2", &v2, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
- v2.vsOut(),
- te.inVertex2()->fName,
- te.inVertex2()->fName);
-
- GrGLSLVertToFrag v3(kVec2f_GrSLType);
- varyingHandler->addVarying("Vertex3", &v3, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
- v3.vsOut(),
- te.inVertex3()->fName,
- te.inVertex3()->fName);
-
- GrGLSLVertToFrag delta1(kVec2f_GrSLType);
- varyingHandler->addVarying("delta1", &delta1, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
- delta1.vsOut(), v1.vsOut(), v2.vsOut(), v2.vsOut(), v1.vsOut());
-
- GrGLSLVertToFrag delta2(kVec2f_GrSLType);
- varyingHandler->addVarying("delta2", &delta2, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
- delta2.vsOut(), v2.vsOut(), v3.vsOut(), v3.vsOut(), v2.vsOut());
-
- GrGLSLVertToFrag delta3(kVec2f_GrSLType);
- varyingHandler->addVarying("delta3", &delta3, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
- delta3.vsOut(), v3.vsOut(), v1.vsOut(), v1.vsOut(), v3.vsOut());
-
- GrGLSLVertToFrag windings(kInt_GrSLType);
- varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision);
- vsBuilder->codeAppendf("%s = %s;",
- windings.vsOut(), te.inWindings()->fName);
-
- // emit transforms
- this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
- te.inPosition()->fName, te.localMatrix(),
- args.fFPCoordTransformHandler);
-
- GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
- SkAssertResult(fsBuilder->enableFeature(
- GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
- fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
- // Compute four subsamples, each shifted a quarter pixel along x and y from
- // gl_FragCoord. The oriented box positioning of the subsamples is of course not
- // optimal, but it greatly simplifies the math and this simplification is necessary for
- // performance reasons.
- fsBuilder->codeAppendf("highp vec2 firstSample = sk_FragCoord.xy - vec2(0.25);");
- fsBuilder->codeAppendf("highp vec2 delta1 = %s;", delta1.fsIn());
- fsBuilder->codeAppendf("highp vec2 delta2 = %s;", delta2.fsIn());
- fsBuilder->codeAppendf("highp vec2 delta3 = %s;", delta3.fsIn());
- // Check whether first sample is inside the triangle by computing three dot products. If
- // all are < 0, we're inside. The first vector in each case is half of what it is
- // "supposed" to be, because we re-use them later as adjustment factors for which half
- // is the correct value, so we multiply the dots by two to compensate.
- fsBuilder->codeAppendf("highp float d1 = dot(delta1, (firstSample - %s).yx) * 2.0;",
- v1.fsIn());
- fsBuilder->codeAppendf("highp float d2 = dot(delta2, (firstSample - %s).yx) * 2.0;",
- v2.fsIn());
- fsBuilder->codeAppendf("highp float d3 = dot(delta3, (firstSample - %s).yx) * 2.0;",
- v3.fsIn());
- fsBuilder->codeAppend("highp float dmax = max(d1, max(d2, d3));");
- fsBuilder->codeAppendf("pls.windings[0] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
- // for subsequent samples, we don't recalculate the entire dot product -- just adjust it
- // to the value it would have if we did recompute it.
- fsBuilder->codeAppend("d1 += delta1.x;");
- fsBuilder->codeAppend("d2 += delta2.x;");
- fsBuilder->codeAppend("d3 += delta3.x;");
- fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
- fsBuilder->codeAppendf("pls.windings[1] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
- fsBuilder->codeAppend("d1 += delta1.y;");
- fsBuilder->codeAppend("d2 += delta2.y;");
- fsBuilder->codeAppend("d3 += delta3.y;");
- fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
- fsBuilder->codeAppendf("pls.windings[2] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
- fsBuilder->codeAppend("d1 -= delta1.x;");
- fsBuilder->codeAppend("d2 -= delta2.x;");
- fsBuilder->codeAppend("d3 -= delta3.x;");
- fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
- fsBuilder->codeAppendf("pls.windings[3] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
- }
-
- static inline void GenKey(const GrGeometryProcessor& gp,
- const GrShaderCaps&,
- GrProcessorKeyBuilder* b) {
- const PLSAATriangleEffect& te = gp.cast<PLSAATriangleEffect>();
- uint32_t key = 0;
- key |= te.localMatrix().hasPerspective() ? 0x1 : 0x0;
- b->add32(key);
- }
-
- void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
- this->setTransformDataHelper(gp.cast<PLSAATriangleEffect>().fLocalMatrix, pdman,
- &transformIter);
- }
-
- private:
- typedef GrGLSLGeometryProcessor INHERITED;
- };
-
- virtual void getGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const override {
- GLSLProcessor::GenKey(*this, caps, b);
- }
-
- virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
- return new GLSLProcessor(*this);
- }
-
-private:
- PLSAATriangleEffect(const SkMatrix& localMatrix, bool usesLocalCoords)
- : fLocalMatrix(localMatrix)
- , fUsesLocalCoords(usesLocalCoords) {
- this->initClassID<PLSAATriangleEffect>();
- fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInVertex1 = &this->addVertexAttrib("inVertex1", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInVertex2 = &this->addVertexAttrib("inVertex2", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInVertex3 = &this->addVertexAttrib("inVertex3", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
- kLow_GrSLPrecision);
- }
-
- const Attribute* fInPosition;
- const Attribute* fInVertex1;
- const Attribute* fInVertex2;
- const Attribute* fInVertex3;
- const Attribute* fInWindings;
- SkMatrix fLocalMatrix;
- bool fUsesLocalCoords;
-
- GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
-
- typedef GrGeometryProcessor INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-/*
- * Quadratic specified by 0=u^2-v canonical coords. u and v are the first
- * two components of the vertex attribute. Coverage is based on signed
- * distance with negative being inside, positive outside. The edge is specified in
- * window space (y-down). If either the third or fourth component of the interpolated
- * vertex coord is > 0 then the pixel is considered outside the edge. This is used to
- * attempt to trim to a portion of the infinite quad.
- * Requires shader derivative instruction support.
- */
-
-class PLSQuadEdgeEffect : public GrPLSGeometryProcessor {
-public:
-
- static GrPLSGeometryProcessor* Create(const SkMatrix& localMatrix,
- bool usesLocalCoords) {
- return new PLSQuadEdgeEffect(localMatrix, usesLocalCoords);
- }
-
- virtual ~PLSQuadEdgeEffect() {}
-
- const char* name() const override { return "PLSQuadEdge"; }
-
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inUV() const { return fInUV; }
- const Attribute* inEndpoint1() const { return fInEndpoint1; }
- const Attribute* inEndpoint2() const { return fInEndpoint2; }
- const Attribute* inWindings() const { return fInWindings; }
- const SkMatrix& localMatrix() const { return fLocalMatrix; }
- bool usesLocalCoords() const { return fUsesLocalCoords; }
-
- class GLSLProcessor : public GrGLSLGeometryProcessor {
- public:
- GLSLProcessor(const GrGeometryProcessor&) {}
-
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
- const PLSQuadEdgeEffect& qe = args.fGP.cast<PLSQuadEdgeEffect>();
- GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
- GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-
- // emit attributes
- varyingHandler->emitAttributes(qe);
-
- GrGLSLVertToFrag uv(kVec2f_GrSLType);
- varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qe.inUV()->fName);
-
- GrGLSLVertToFrag ep1(kVec2f_GrSLType);
- varyingHandler->addVarying("endpoint1", &ep1, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep1.vsOut(),
- qe.inEndpoint1()->fName, qe.inEndpoint1()->fName);
-
- GrGLSLVertToFrag ep2(kVec2f_GrSLType);
- varyingHandler->addVarying("endpoint2", &ep2, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep2.vsOut(),
- qe.inEndpoint2()->fName, qe.inEndpoint2()->fName);
-
- GrGLSLVertToFrag delta(kVec2f_GrSLType);
- varyingHandler->addVarying("delta", &delta, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
- delta.vsOut(), ep1.vsOut(), ep2.vsOut(), ep2.vsOut(),
- ep1.vsOut());
-
- GrGLSLVertToFrag windings(kInt_GrSLType);
- varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision);
- vsBuilder->codeAppendf("%s = %s;",
- windings.vsOut(), qe.inWindings()->fName);
-
- // Setup position
- this->setupPosition(vsBuilder, gpArgs, qe.inPosition()->fName);
-
- // emit transforms
- this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
- qe.inPosition()->fName, qe.localMatrix(),
- args.fFPCoordTransformHandler);
-
- GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
- SkAssertResult(fsBuilder->enableFeature(
- GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
- static const int QUAD_ARGS = 2;
- GrShaderVar inQuadArgs[QUAD_ARGS] = {
- GrShaderVar("dot", kFloat_GrSLType, 0, kHigh_GrSLPrecision),
- GrShaderVar("uv", kVec2f_GrSLType, 0, kHigh_GrSLPrecision)
- };
- SkString inQuadName;
-
- const char* inQuadCode = "if (uv.x * uv.x <= uv.y) {"
- "return dot >= 0.0;"
- "} else {"
- "return false;"
- "}";
- fsBuilder->emitFunction(kBool_GrSLType, "in_quad", QUAD_ARGS, inQuadArgs, inQuadCode,
- &inQuadName);
- fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
- // keep the derivative instructions outside the conditional
- fsBuilder->codeAppendf("highp vec2 uvdX = dFdx(%s);", uv.fsIn());
- fsBuilder->codeAppendf("highp vec2 uvdY = dFdy(%s);", uv.fsIn());
- fsBuilder->codeAppend("highp vec2 uvIncX = uvdX * 0.45 + uvdY * -0.1;");
- fsBuilder->codeAppend("highp vec2 uvIncY = uvdX * 0.1 + uvdY * 0.55;");
- fsBuilder->codeAppendf("highp vec2 uv = %s.xy - uvdX * 0.35 - uvdY * 0.25;",
- uv.fsIn());
- fsBuilder->codeAppendf("highp vec2 firstSample = sk_FragCoord.xy - vec2(0.25);");
- fsBuilder->codeAppendf("highp float d = dot(%s, (firstSample - %s).yx) * 2.0;",
- delta.fsIn(), ep1.fsIn());
- fsBuilder->codeAppendf("pls.windings[0] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
- windings.fsIn());
- fsBuilder->codeAppend("uv += uvIncX;");
- fsBuilder->codeAppendf("d += %s.x;", delta.fsIn());
- fsBuilder->codeAppendf("pls.windings[1] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
- windings.fsIn());
- fsBuilder->codeAppend("uv += uvIncY;");
- fsBuilder->codeAppendf("d += %s.y;", delta.fsIn());
- fsBuilder->codeAppendf("pls.windings[2] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
- windings.fsIn());
- fsBuilder->codeAppend("uv -= uvIncX;");
- fsBuilder->codeAppendf("d -= %s.x;", delta.fsIn());
- fsBuilder->codeAppendf("pls.windings[3] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
- windings.fsIn());
- }
-
- static inline void GenKey(const GrGeometryProcessor& gp,
- const GrShaderCaps&,
- GrProcessorKeyBuilder* b) {
- const PLSQuadEdgeEffect& qee = gp.cast<PLSQuadEdgeEffect>();
- uint32_t key = 0;
- key |= qee.usesLocalCoords() && qee.localMatrix().hasPerspective() ? 0x1 : 0x0;
- b->add32(key);
- }
-
- void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
- this->setTransformDataHelper(gp.cast<PLSQuadEdgeEffect>().fLocalMatrix, pdman,
- &transformIter);
- }
-
- private:
- typedef GrGLSLGeometryProcessor INHERITED;
- };
-
- virtual void getGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const override {
- GLSLProcessor::GenKey(*this, caps, b);
- }
-
- virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
- return new GLSLProcessor(*this);
- }
-
-private:
- PLSQuadEdgeEffect(const SkMatrix& localMatrix, bool usesLocalCoords)
- : fLocalMatrix(localMatrix)
- , fUsesLocalCoords(usesLocalCoords) {
- this->initClassID<PLSQuadEdgeEffect>();
- fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInUV = &this->addVertexAttrib("inUV", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision);
- fInEndpoint1 = &this->addVertexAttrib("inEndpoint1", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInEndpoint2 = &this->addVertexAttrib("inEndpoint2", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
- kLow_GrSLPrecision);
- }
-
- const Attribute* fInPosition;
- const Attribute* fInUV;
- const Attribute* fInEndpoint1;
- const Attribute* fInEndpoint2;
- const Attribute* fInWindings;
- SkMatrix fLocalMatrix;
- bool fUsesLocalCoords;
-
- GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
-
- typedef GrGeometryProcessor INHERITED;
-};
-
-class PLSFinishEffect : public GrGeometryProcessor {
-public:
-
- static GrGeometryProcessor* Create(GrColor color, bool useEvenOdd, const SkMatrix& localMatrix,
- bool usesLocalCoords) {
- return new PLSFinishEffect(color, useEvenOdd, localMatrix, usesLocalCoords);
- }
-
- virtual ~PLSFinishEffect() {}
-
- const char* name() const override { return "PLSFinish"; }
-
- const Attribute* inPosition() const { return fInPosition; }
- GrColor color() const { return fColor; }
- const SkMatrix& localMatrix() const { return fLocalMatrix; }
- bool usesLocalCoords() const { return fUsesLocalCoords; }
-
- GrPixelLocalStorageState getPixelLocalStorageState() const override {
- return GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState;
- }
-
- const char* getDestColorOverride() const override {
- return GR_GL_PLS_DSTCOLOR_NAME;
- }
-
- class GLSLProcessor : public GrGLSLGeometryProcessor {
- public:
- GLSLProcessor(const GrGeometryProcessor&) {}
-
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
- const PLSFinishEffect& fe = args.fGP.cast<PLSFinishEffect>();
- GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
- GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-
- fUseEvenOdd = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kFloat_GrSLType, kLow_GrSLPrecision,
- "useEvenOdd");
- const char* useEvenOdd = uniformHandler->getUniformCStr(fUseEvenOdd);
-
- varyingHandler->emitAttributes(fe);
- this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName);
- this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
- fe.inPosition()->fName, fe.localMatrix(),
- args.fFPCoordTransformHandler);
-
- GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
- SkAssertResult(fsBuilder->enableFeature(
- GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
- fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
- fsBuilder->codeAppend("float coverage;");
- fsBuilder->codeAppendf("if (%s != 0.0) {", useEvenOdd);
- fsBuilder->codeAppend("coverage = float(abs(pls.windings[0]) % 2) * 0.25;");
- fsBuilder->codeAppend("coverage += float(abs(pls.windings[1]) % 2) * 0.25;");
- fsBuilder->codeAppend("coverage += float(abs(pls.windings[2]) % 2) * 0.25;");
- fsBuilder->codeAppend("coverage += float(abs(pls.windings[3]) % 2) * 0.25;");
- fsBuilder->codeAppend("} else {");
- fsBuilder->codeAppend("coverage = pls.windings[0] != 0 ? 0.25 : 0.0;");
- fsBuilder->codeAppend("coverage += pls.windings[1] != 0 ? 0.25 : 0.0;");
- fsBuilder->codeAppend("coverage += pls.windings[2] != 0 ? 0.25 : 0.0;");
- fsBuilder->codeAppend("coverage += pls.windings[3] != 0 ? 0.25 : 0.0;");
- fsBuilder->codeAppend("}");
- this->setupUniformColor(fsBuilder, uniformHandler, args.fOutputColor,
- &fColorUniform);
- fsBuilder->codeAppendf("%s = vec4(coverage);", args.fOutputCoverage);
- fsBuilder->codeAppendf("%s = vec4(1.0, 0.0, 1.0, 1.0);", args.fOutputColor);
- }
-
- static inline void GenKey(const GrGeometryProcessor& gp,
- const GrShaderCaps&,
- GrProcessorKeyBuilder* b) {
- const PLSFinishEffect& fe = gp.cast<PLSFinishEffect>();
- uint32_t key = 0;
- key |= fe.usesLocalCoords() && fe.localMatrix().hasPerspective() ? 0x1 : 0x0;
- b->add32(key);
- }
-
- void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
- const PLSFinishEffect& fe = gp.cast<PLSFinishEffect>();
- pdman.set1f(fUseEvenOdd, fe.fUseEvenOdd);
- if (fe.color() != fColor) {
- GrGLfloat c[4];
- GrColorToRGBAFloat(fe.color(), c);
- pdman.set4fv(fColorUniform, 1, c);
- fColor = fe.color();
- }
- this->setTransformDataHelper(fe.fLocalMatrix, pdman, &transformIter);
- }
-
- private:
- GrColor fColor;
- UniformHandle fColorUniform;
- UniformHandle fUseEvenOdd;
-
- typedef GrGLSLGeometryProcessor INHERITED;
- };
-
- virtual void getGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const override {
- GLSLProcessor::GenKey(*this, caps, b);
- }
-
- virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
- return new GLSLProcessor(*this);
- }
-
-private:
- PLSFinishEffect(GrColor color, bool useEvenOdd, const SkMatrix& localMatrix,
- bool usesLocalCoords)
- : fColor(color)
- , fUseEvenOdd(useEvenOdd)
- , fLocalMatrix(localMatrix)
- , fUsesLocalCoords(usesLocalCoords) {
- this->initClassID<PLSFinishEffect>();
- fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
- kHigh_GrSLPrecision);
- }
-
- const Attribute* fInPosition;
- GrColor fColor;
- bool fUseEvenOdd;
- SkMatrix fLocalMatrix;
- bool fUsesLocalCoords;
-
- typedef GrGeometryProcessor INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- // We have support for even-odd rendering, but are having some troublesome
- // seams. Disable in the presence of even-odd for now.
- SkPath path;
- args.fShape->asPath(&path);
- return args.fShaderCaps->shaderDerivativeSupport() && GrAAType::kCoverage == args.fAAType &&
- args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
- path.getFillType() == SkPath::FillType::kWinding_FillType;
-}
-
-class PLSPathOp final : public GrMeshDrawOp {
-public:
- DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrDrawOp> Make(GrColor color, const SkPath& path,
- const SkMatrix& viewMatrix) {
- return std::unique_ptr<GrDrawOp>(new PLSPathOp(color, path, viewMatrix));
- }
-
- const char* name() const override { return "PLSPathOp"; }
-
- SkString dumpInfo() const override {
- SkString string;
- string.printf("Color 0x%08x, UsesLocalCoords: %d\n", fColor, fUsesLocalCoords);
- string.append(DumpPipelineInfo(*this->pipeline()));
- string.append(INHERITED::dumpInfo());
- return string;
- }
-
-private:
- PLSPathOp(GrColor color, const SkPath& path, const SkMatrix& viewMatrix)
- : INHERITED(ClassID()), fColor(color), fPath(path), fViewMatrix(viewMatrix) {
- // compute bounds
- this->setTransformedBounds(path.getBounds(), fViewMatrix, HasAABloat::kYes,
- IsZeroArea::kNo);
- }
-
- void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override {
- input->colorInput()->setToConstant(fColor);
- input->coverageInput()->setToUnknown();
- input->setUsesPLSDstRead();
- }
-
- void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
- optimizations.getOverrideColorIfSet(&fColor);
-
- fUsesLocalCoords = optimizations.readsLocalCoords();
- }
-
- void onPrepareDraws(Target* target) const override {
-
- SkMatrix invert;
- if (fUsesLocalCoords && !fViewMatrix.invert(&invert)) {
- SkDebugf("Could not invert viewmatrix\n");
- return;
- }
-
- // Setup GrGeometryProcessors
- sk_sp<GrPLSGeometryProcessor> triangleProcessor(
- PLSAATriangleEffect::Create(invert, fUsesLocalCoords));
- sk_sp<GrPLSGeometryProcessor> quadProcessor(
- PLSQuadEdgeEffect::Create(invert, fUsesLocalCoords));
-
- GrResourceProvider* rp = target->resourceProvider();
- SkRect bounds;
- this->bounds().roundOut(&bounds);
- triangleProcessor->setBounds(bounds);
- quadProcessor->setBounds(bounds);
-
- // We use the fact that SkPath::transform path does subdivision based on
- // perspective. Otherwise, we apply the view matrix when copying to the
- // segment representation.
- const SkMatrix* viewMatrix = &fViewMatrix;
-
- // We avoid initializing the path unless we have to
- const SkPath* pathPtr = &fPath;
- SkTLazy<SkPath> tmpPath;
- if (viewMatrix->hasPerspective()) {
- SkPath* tmpPathPtr = tmpPath.init(*pathPtr);
- tmpPathPtr->setIsVolatile(true);
- tmpPathPtr->transform(*viewMatrix);
- viewMatrix = &SkMatrix::I();
- pathPtr = tmpPathPtr;
- }
-
- GrMesh mesh;
-
- PLSVertices triVertices;
- PLSVertices quadVertices;
- if (!get_geometry(*pathPtr, *viewMatrix, triVertices, quadVertices, rp, bounds)) {
- return;
- }
-
- if (triVertices.count()) {
- const GrBuffer* triVertexBuffer;
- int firstTriVertex;
- size_t triStride = triangleProcessor->getVertexStride();
- PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
- triStride, triVertices.count(), &triVertexBuffer, &firstTriVertex));
- if (!triVerts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
- for (int i = 0; i < triVertices.count(); ++i) {
- triVerts[i] = triVertices[i];
- }
- mesh.init(kTriangles_GrPrimitiveType, triVertexBuffer, firstTriVertex,
- triVertices.count());
- target->draw(triangleProcessor.get(), mesh);
- }
-
- if (quadVertices.count()) {
- const GrBuffer* quadVertexBuffer;
- int firstQuadVertex;
- size_t quadStride = quadProcessor->getVertexStride();
- PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
- quadStride, quadVertices.count(), &quadVertexBuffer, &firstQuadVertex));
- if (!quadVerts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
- for (int i = 0; i < quadVertices.count(); ++i) {
- quadVerts[i] = quadVertices[i];
- }
- mesh.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex,
- quadVertices.count());
- target->draw(quadProcessor.get(), mesh);
- }
-
- sk_sp<GrGeometryProcessor> finishProcessor(
- PLSFinishEffect::Create(fColor,
- pathPtr->getFillType() ==
- SkPath::FillType::kEvenOdd_FillType,
- invert,
- fUsesLocalCoords));
- const GrBuffer* rectVertexBuffer;
- size_t finishStride = finishProcessor->getVertexStride();
- int firstRectVertex;
- static const int kRectVertexCount = 6;
- SkPoint* rectVerts = reinterpret_cast<SkPoint*>(target->makeVertexSpace(
- finishStride, kRectVertexCount, &rectVertexBuffer, &firstRectVertex));
- if (!rectVerts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
- rectVerts[0] = { bounds.fLeft, bounds.fTop };
- rectVerts[1] = { bounds.fLeft, bounds.fBottom };
- rectVerts[2] = { bounds.fRight, bounds.fBottom };
- rectVerts[3] = { bounds.fLeft, bounds.fTop };
- rectVerts[4] = { bounds.fRight, bounds.fTop };
- rectVerts[5] = { bounds.fRight, bounds.fBottom };
-
- mesh.init(kTriangles_GrPrimitiveType, rectVertexBuffer, firstRectVertex,
- kRectVertexCount);
- target->draw(finishProcessor.get(), mesh);
- }
-
- bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- return false;
- }
-
- bool fUsesLocalCoords;
-
- GrColor fColor;
- SkPath fPath;
- SkMatrix fViewMatrix;
- typedef GrMeshDrawOp INHERITED;
-};
-
-SkDEBUGCODE(bool inPLSDraw = false;)
-bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) {
- SkASSERT(!args.fShape->isEmpty());
- SkASSERT(!inPLSDraw);
- SkDEBUGCODE(inPLSDraw = true;)
- SkPath path;
- args.fShape->asPath(&path);
-
- std::unique_ptr<GrDrawOp> op = PLSPathOp::Make(args.fPaint.getColor(), path, *args.fViewMatrix);
- GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
- pipelineBuilder.setUserStencil(args.fUserStencilSettings);
-
- args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, std::move(op));
- SkDEBUGCODE(inPLSDraw = false;)
- return true;
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if GR_TEST_UTILS
-
-DRAW_OP_TEST_DEFINE(PLSPathOp) {
- GrColor color = GrRandomColor(random);
- SkMatrix vm = GrTest::TestMatrixInvertible(random);
- SkPath path = GrTest::TestPathConvex(random);
-
- return PLSPathOp::Make(color, path, vm);
-}
-
-#endif
diff --git a/src/gpu/ops/GrPLSPathRenderer.h b/src/gpu/ops/GrPLSPathRenderer.h
deleted file mode 100644
index 39f21ba68c..0000000000
--- a/src/gpu/ops/GrPLSPathRenderer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrPLSPathRenderer_DEFINED
-#define GrPLSPathRenderer_DEFINED
-
-#include "GrPathRenderer.h"
-
-/*
- * Renders arbitrary antialiased paths using pixel local storage as a scratch buffer. The overall
- * technique is very similar to the approach presented in "Resolution independent rendering of
- * deformable vector objects using graphics hardware" by Kokojima et al.
-
- * We first render the straight-line portions of the path (essentially pretending as if all segments
- * were kLine_Verb) as a triangle fan, using a fragment shader which updates the winding counts
- * appropriately. We then render the curved portions of the path using a Loop-Blinn shader which
- * calculates which portion of the triangle is covered by the quad (conics and cubics are split down
- * to quads). Where we diverge from Kokojima is that, instead of rendering into the stencil buffer
- * and using built-in MSAA to handle straight-line antialiasing, we use the pixel local storage area
- * and calculate the MSAA ourselves in the fragment shader. Essentially, we manually evaluate the
- * coverage of each pixel four times, storing four winding counts into the pixel local storage area,
- * and compute the final coverage based on those winding counts.
- *
- * Our approach is complicated by the need to perform antialiasing on straight edges as well,
- * without relying on hardware MSAA. We instead bloat the triangles to ensure complete coverage,
- * pass the original (un-bloated) vertices in to the fragment shader, and then have the fragment
- * shader use these vertices to evaluate whether a given sample is located within the triangle or
- * not. This gives us MSAA4 edges on triangles which line up nicely with no seams. We similarly face
- * problems on the back (flat) edges of quads, where we have to ensure that the back edge is
- * antialiased in the same way. Similar to the triangle case, we pass in the two (unbloated)
- * vertices defining the back edge of the quad and the fragment shader uses these vertex coordinates
- * to discard samples falling on the other side of the quad's back edge.
- */
-class GrPLSPathRenderer : public GrPathRenderer {
-public:
- GrPLSPathRenderer();
-
- bool onCanDrawPath(const CanDrawPathArgs& args) const override;
-
-protected:
- bool onDrawPath(const DrawPathArgs& args) override;
-};
-
-#endif