Revert "converted AARectEffect to new FP system"
This reverts commit 222e275b0ab4c8a2af152c637bf9dbc28b4a097f.
Reason for revert: perf regression
Original change's description:
> converted AARectEffect to new FP system
>
> Bug: skia:
> Change-Id: I0e4141c7f547bab92c65a6abff120ed04d5c2c66
> Reviewed-on: https://skia-review.googlesource.com/c/153550
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
TBR=bsalomon@google.com,ethannicholas@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: skia:
Change-Id: I3d7036a78d8582d6790c77b20a60e6e5257d1881
Reviewed-on: https://skia-review.googlesource.com/c/162283
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 5c429e0..92af020 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -211,8 +211,8 @@
}
auto* ccpr = context->contextPriv().drawingManager()->getCoverageCountingPathRenderer();
- GrReducedClip reducedClip(*fStack, devBounds, context, maxWindowRectangles, maxAnalyticFPs,
- ccpr ? maxAnalyticFPs : 0);
+ GrReducedClip reducedClip(*fStack, devBounds, context->contextPriv().caps(),
+ maxWindowRectangles, maxAnalyticFPs, ccpr ? maxAnalyticFPs : 0);
if (InitialState::kAllOut == reducedClip.initialState() &&
reducedClip.maskElements().isEmpty()) {
return false;
@@ -291,7 +291,7 @@
// after clipping is overhauled.
if (renderTargetContext->priv().mustRenderClip(reducedClip.maskGenID(), reducedClip.scissor(),
reducedClip.numAnalyticFPs())) {
- reducedClip.drawStencilClipMask(renderTargetContext);
+ reducedClip.drawStencilClipMask(context, renderTargetContext);
renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor(),
reducedClip.numAnalyticFPs());
}
diff --git a/src/gpu/GrMemoryPool.cpp b/src/gpu/GrMemoryPool.cpp
index 7d085ea..89e8f01 100644
--- a/src/gpu/GrMemoryPool.cpp
+++ b/src/gpu/GrMemoryPool.cpp
@@ -11,7 +11,6 @@
#include "SkAtomics.h"
#endif
#include "ops/GrOp.h"
-#include "effects/GrSkSLFP.h"
#ifdef SK_DEBUG
#define VALIDATE this->validate()
@@ -19,13 +18,6 @@
#define VALIDATE
#endif
-enum {
- // We assume this alignment is good enough for everybody.
- kAlignment = alignof(GrSkSLFP),
- kHeaderSize = GR_CT_ALIGN_UP(GrMemoryPool::kBlockHeaderSize, kAlignment),
- kPerAllocPad = GR_CT_ALIGN_UP(GrMemoryPool::kAllocHeaderSize, kAlignment),
-};
-
void GrOpMemoryPool::release(std::unique_ptr<GrOp> op) {
GrOp* tmp = op.release();
SkASSERT(tmp);
diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h
index 316deae..15399b6 100644
--- a/src/gpu/GrMemoryPool.h
+++ b/src/gpu/GrMemoryPool.h
@@ -115,10 +115,13 @@
SkTHashSet<int32_t> fAllocatedIDs;
#endif
-public:
- constexpr static size_t kBlockHeaderSize = sizeof(BlockHeader);
-
- constexpr static size_t kAllocHeaderSize = sizeof(AllocHeader);
+protected:
+ enum {
+ // We assume this alignment is good enough for everybody.
+ kAlignment = 8,
+ kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
+ kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
+ };
};
class GrOp;
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 078cfbdf..aafe1d8 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -57,7 +57,7 @@
* we verify the count is as expected. If a new factory is added, then these numbers must be
* manually adjusted.
*/
-static const int kFPFactoryCount = 35;
+static const int kFPFactoryCount = 36;
static const int kGPFactoryCount = 14;
static const int kXPFactoryCount = 4;
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 111ef7f..4cf3477 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -22,6 +22,7 @@
#include "GrUserStencilSettings.h"
#include "SkClipOpPriv.h"
#include "ccpr/GrCoverageCountingPathRenderer.h"
+#include "effects/GrAARectEffect.h"
#include "effects/GrConvexPolyEffect.h"
#include "effects/GrRRectEffect.h"
@@ -33,9 +34,9 @@
* take a rect in case the caller knows a bound on what is to be drawn through this clip.
*/
GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds,
- GrContext* context, int maxWindowRectangles,
- int maxAnalyticFPs, int maxCCPRClipPaths)
- : fContext(context)
+ const GrCaps* caps, int maxWindowRectangles, int maxAnalyticFPs,
+ int maxCCPRClipPaths)
+ : fCaps(caps)
, fMaxWindowRectangles(maxWindowRectangles)
, fMaxAnalyticFPs(maxAnalyticFPs)
, fMaxCCPRClipPaths(maxCCPRClipPaths) {
@@ -611,14 +612,13 @@
}
}
-GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRect& deviceSpaceRect, Invert invert,
- GrAA aa) {
+GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRect& deviceSpaceRect,
+ Invert invert, GrAA aa) {
if (this->numAnalyticFPs() >= fMaxAnalyticFPs) {
return ClipResult::kNotClipped;
}
- fAnalyticFPs.push_back(GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect,
- fContext));
+ fAnalyticFPs.push_back(GrAARectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect));
SkASSERT(fAnalyticFPs.back());
return ClipResult::kClipped;
@@ -630,7 +630,8 @@
return ClipResult::kNotClipped;
}
- if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect, fContext)) {
+ if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect,
+ *fCaps->shaderCaps())) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
}
@@ -647,8 +648,7 @@
return ClipResult::kNotClipped;
}
- if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath,
- fContext)) {
+ if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath)) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
}
@@ -805,7 +805,8 @@
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer.
-bool GrReducedClip::drawStencilClipMask(GrRenderTargetContext* renderTargetContext) const {
+bool GrReducedClip::drawStencilClipMask(GrContext* context,
+ GrRenderTargetContext* renderTargetContext) const {
// We set the current clip to the bounds so that our recursive draws are scissored to them.
GrStencilClip stencilClip(fScissor, this->maskGenID());
@@ -847,14 +848,14 @@
GrShape shape(clipPath, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
- canDrawArgs.fCaps = fContext->contextPriv().caps();
+ canDrawArgs.fCaps = context->contextPriv().caps();
canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
canDrawArgs.fViewMatrix = &SkMatrix::I();
canDrawArgs.fShape = &shape;
canDrawArgs.fAAType = aaType;
canDrawArgs.fHasUserStencilSettings = false;
- GrDrawingManager* dm = fContext->contextPriv().drawingManager();
+ GrDrawingManager* dm = context->contextPriv().drawingManager();
pr = dm->getPathRenderer(canDrawArgs, false, GrPathRendererChain::DrawType::kStencil,
&stencilSupport);
if (!pr) {
@@ -894,7 +895,7 @@
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- GrPathRenderer::DrawPathArgs args{fContext,
+ GrPathRenderer::DrawPathArgs args{context,
std::move(paint),
&kDrawToStencil,
renderTargetContext,
@@ -907,7 +908,7 @@
pr->drawPath(args);
} else {
GrPathRenderer::StencilPathArgs args;
- args.fContext = fContext;
+ args.fContext = context;
args.fRenderTargetContext = renderTargetContext;
args.fClip = &stencilClip.fixedClip();
args.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
@@ -932,7 +933,7 @@
GrShape shape(clipPath, GrStyle::SimpleFill());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- GrPathRenderer::DrawPathArgs args{fContext,
+ GrPathRenderer::DrawPathArgs args{context,
std::move(paint),
*pass,
renderTargetContext,
@@ -966,7 +967,7 @@
SkASSERT(ccpr);
SkASSERT(fHasScissor);
auto fp = ccpr->makeClipProcessor(opListID, ccprClipPath, fScissor, rtWidth, rtHeight,
- *fContext->contextPriv().caps());
+ *fCaps);
fAnalyticFPs.push_back(std::move(fp));
}
fCCPRClipPaths.reset();
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index 6a8bc9e..fcdc66c 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -26,9 +26,8 @@
using Element = SkClipStack::Element;
using ElementList = SkTLList<SkClipStack::Element, 16>;
- GrReducedClip(const SkClipStack&, const SkRect& queryBounds, GrContext* context,
- int maxWindowRectangles = 0, int maxAnalyticFPs = 0,
- int maxCCPRClipPaths = 0);
+ GrReducedClip(const SkClipStack&, const SkRect& queryBounds, const GrCaps* caps,
+ int maxWindowRectangles = 0, int maxAnalyticFPs = 0, int maxCCPRClipPaths = 0);
enum class InitialState : bool {
kAllIn,
@@ -84,7 +83,7 @@
bool maskRequiresAA() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskRequiresAA; }
bool drawAlphaClipMask(GrRenderTargetContext*) const;
- bool drawStencilClipMask(GrRenderTargetContext*) const;
+ bool drawStencilClipMask(GrContext*, GrRenderTargetContext*) const;
int numAnalyticFPs() const { return fAnalyticFPs.count() + fCCPRClipPaths.count(); }
@@ -132,7 +131,7 @@
void makeEmpty();
- GrContext* fContext;
+ const GrCaps* fCaps;
const int fMaxWindowRectangles;
const int fMaxAnalyticFPs;
const int fMaxCCPRClipPaths;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 369eee8..6b9e3d1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1253,13 +1253,14 @@
inverseVM.reset();
}
+ const auto& caps = *this->caps()->shaderCaps();
// TODO these need to be a geometry processors
- auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, fContext);
+ auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
if (!innerEffect) {
return false;
}
- auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, fContext);
+ auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
if (!outerEffect) {
return false;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 9f348c2..f78ef18 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -490,7 +490,7 @@
if (ditherRange >= 0) {
static int ditherIndex = GrSkSLFP::NewIndex();
auto ditherFP = GrSkSLFP::Make(context, ditherIndex, "Dither", SKSL_DITHER_SRC,
- ditherRange);
+ &ditherRange, sizeof(ditherRange));
if (ditherFP) {
grPaint->addColorFragmentProcessor(std::move(ditherFP));
}
diff --git a/src/gpu/effects/GrAARectEffect.cpp b/src/gpu/effects/GrAARectEffect.cpp
new file mode 100644
index 0000000..9ee0ad5
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * 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 GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrAARectEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLAARectEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLAARectEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrAARectEffect& _outer = args.fFp.cast<GrAARectEffect>();
+ (void)_outer;
+ auto edgeType = _outer.edgeType();
+ (void)edgeType;
+ auto rect = _outer.rect();
+ (void)rect;
+ prevRect = float4(-1.0);
+ fRectUniformVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "rectUniform");
+ fragBuilder->codeAppendf(
+ "float4 prevRect = float4(%f, %f, %f, %f);\nhalf alpha;\n@switch (%d) {\n case "
+ "0:\n case 2:\n alpha = half(all(greaterThan(float4(sk_FragCoord.xy, "
+ "%s.zw), float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0);\n break;\n "
+ "default:\n half xSub, ySub;\n xSub = half(min(sk_FragCoord.x - "
+ "%s.x, 0.0));\n xSub += half(min(%s.z - sk_FragCoord.x, 0.0));\n "
+ "ySub = half(min(sk_FragCoord.y - %s.y, 0.0));\n ySub += half(min(%s.w - "
+ "sk_FragCoord.y, 0.0));\n alpha = half((1",
+ prevRect.left(),
+ prevRect.top(),
+ prevRect.right(),
+ prevRect.bottom(),
+ (int)_outer.edgeType(),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar),
+ args.fUniformHandler->getUniformCStr(fRectUniformVar));
+ fragBuilder->codeAppendf(
+ ".0 + max(float(xSub), -1.0)) * (1.0 + max(float(ySub), -1.0)));\n}\n@if (%d == 2 "
+ "|| %d == 3) {\n alpha = half(1.0 - float(alpha));\n}\n%s = %s * alpha;\n",
+ (int)_outer.edgeType(),
+ (int)_outer.edgeType(),
+ args.fOutputColor,
+ args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrAARectEffect& _outer = _proc.cast<GrAARectEffect>();
+ auto edgeType = _outer.edgeType();
+ (void)edgeType;
+ auto rect = _outer.rect();
+ (void)rect;
+ UniformHandle& rectUniform = fRectUniformVar;
+ (void)rectUniform;
+
+ const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? rect.makeInset(.5f, .5f) : rect;
+ if (newRect != prevRect) {
+ pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
+ prevRect = newRect;
+ }
+ }
+ SkRect prevRect = float4(0);
+ UniformHandle fRectUniformVar;
+};
+GrGLSLFragmentProcessor* GrAARectEffect::onCreateGLSLInstance() const {
+ return new GrGLSLAARectEffect();
+}
+void GrAARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)fEdgeType);
+}
+bool GrAARectEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrAARectEffect& that = other.cast<GrAARectEffect>();
+ (void)that;
+ if (fEdgeType != that.fEdgeType) return false;
+ if (fRect != that.fRect) return false;
+ return true;
+}
+GrAARectEffect::GrAARectEffect(const GrAARectEffect& src)
+ : INHERITED(kGrAARectEffect_ClassID, src.optimizationFlags())
+ , fEdgeType(src.fEdgeType)
+ , fRect(src.fRect) {}
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAARectEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::TestCreate(GrProcessorTestData* d) {
+ SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1());
+ std::unique_ptr<GrFragmentProcessor> fp;
+ do {
+ GrClipEdgeType edgeType =
+ static_cast<GrClipEdgeType>(d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
+
+ fp = GrAARectEffect::Make(edgeType, rect);
+ } while (nullptr == fp);
+ return fp;
+}
+#endif
diff --git a/src/gpu/effects/GrAARectEffect.fp b/src/gpu/effects/GrAARectEffect.fp
new file mode 100644
index 0000000..95064dd
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.fp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+layout(key) in GrClipEdgeType edgeType;
+layout(ctype=SkRect) in float4 rect;
+layout(ctype=SkRect) float4 prevRect = float4(-1);
+uniform float4 rectUniform;
+
+@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag }
+
+void main() {
+ half alpha;
+ @switch (edgeType) {
+ case GrClipEdgeType::kFillBW: // fall through
+ case GrClipEdgeType::kInverseFillBW:
+ // non-AA
+ alpha = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),
+ float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0;
+ break;
+ default:
+ // The amount of coverage removed in x and y by the edges is computed as a pair of
+ // negative numbers, xSub and ySub.
+ half xSub, ySub;
+ xSub = min(sk_FragCoord.x - rectUniform.x, 0.0);
+ xSub += min(rectUniform.z - sk_FragCoord.x, 0.0);
+ ySub = min(sk_FragCoord.y - rectUniform.y, 0.0);
+ ySub += min(rectUniform.w - sk_FragCoord.y, 0.0);
+ // Now compute coverage in x and y and multiply them to get the fraction of the pixel
+ // covered.
+ alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));
+ }
+
+ @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) {
+ alpha = 1.0 - alpha;
+ }
+ sk_OutColor = sk_InColor * alpha;
+}
+
+@setData(pdman) {
+ const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ?
+ rect.makeInset(.5f, .5f) : rect;
+ if (newRect != prevRect) {
+ pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
+ prevRect = newRect;
+ }
+}
+
+@test(d) {
+ SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1());
+ std::unique_ptr<GrFragmentProcessor> fp;
+ do {
+ GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
+ d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
+
+ fp = GrAARectEffect::Make(edgeType, rect);
+ } while (nullptr == fp);
+ return fp;
+}
diff --git a/src/gpu/effects/GrAARectEffect.h b/src/gpu/effects/GrAARectEffect.h
new file mode 100644
index 0000000..94974e2
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * 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 GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrAARectEffect_DEFINED
+#define GrAARectEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrAARectEffect : public GrFragmentProcessor {
+public:
+ const GrClipEdgeType& edgeType() const { return fEdgeType; }
+ const SkRect& rect() const { return fRect; }
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkRect rect) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(edgeType, rect));
+ }
+ GrAARectEffect(const GrAARectEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "AARectEffect"; }
+
+private:
+ GrAARectEffect(GrClipEdgeType edgeType, SkRect rect)
+ : INHERITED(kGrAARectEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , fEdgeType(edgeType)
+ , fRect(rect) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ GrClipEdgeType fEdgeType;
+ SkRect fRect;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index a0440f0..4751fec 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -7,52 +7,13 @@
#include "GrConvexPolyEffect.h"
#include "SkPathPriv.h"
+#include "effects/GrAARectEffect.h"
#include "effects/GrConstColorProcessor.h"
-#include "effects/GrSkSLFP.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
-GR_FP_SRC_STRING SKSL_AARECT_SRC = R"(
-layout(key) in GrClipEdgeType edgeType;
-layout(ctype=SkRect) in float4 rect;
-uniform float4 rectUniform;
-
-void main(int x, int y, inout half4 color) {
- half alpha;
- @switch (edgeType) {
- case GrClipEdgeType::kFillBW: // fall through
- case GrClipEdgeType::kInverseFillBW:
- // non-AA
- alpha = all(greaterThan(float4(x, y, rectUniform.zw),
- float4(rectUniform.xy, x, y))) ? 1 : 0;
- break;
- default:
- // The amount of coverage removed in x and y by the edges is computed as a pair of
- // negative numbers, xSub and ySub.
- half xSub, ySub;
- xSub = min(x - rectUniform.x, 0.0);
- xSub += min(rectUniform.z - x, 0.0);
- ySub = min(y - rectUniform.y, 0.0);
- ySub += min(rectUniform.w - y, 0.0);
- // Now compute coverage in x and y and multiply them to get the fraction of the pixel
- // covered.
- alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));
- }
-
- @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) {
- alpha = 1.0 - alpha;
- }
- color *= alpha;
-}
-)";
-
-struct AARectInputs {
- GrClipEdgeType fEdgeType;
- SkRect fRect;
-};
-
//////////////////////////////////////////////////////////////////////////////
class GrGLConvexPolyEffect : public GrGLSLFragmentProcessor {
@@ -127,8 +88,7 @@
//////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType type,
- const SkPath& path,
- GrContext* context) {
+ const SkPath& path) {
if (GrClipEdgeType::kHairlineAA == type) {
return nullptr;
}
@@ -198,34 +158,12 @@
return Make(type, n, edges);
}
-static void aa_rect_set_data_hook(const GrGLSLProgramDataManager& pdman,
- const GrGLSLSkSLFP& glslProc,
- const AARectInputs& inputs,
- SkRect* prevRect) {
- if (inputs.fRect != *prevRect) {
- const SkRect& newRect = GrProcessorEdgeTypeIsAA(inputs.fEdgeType) ?
- inputs.fRect.makeInset(.5f, .5f) : inputs.fRect;
- pdman.set4f(glslProc.uniformHandle(0), newRect.fLeft, newRect.fTop, newRect.fRight,
- newRect.fBottom);
- *prevRect = inputs.fRect;
- }
-}
-
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType edgeType,
- const SkRect& rect,
- GrContext* context) {
+ const SkRect& rect) {
if (GrClipEdgeType::kHairlineAA == edgeType){
return nullptr;
}
- static int aaRectIndex = GrSkSLFP::NewIndex();
- AARectInputs inputs;
- inputs.fEdgeType = edgeType;
- inputs.fRect = rect;
- std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(context, aaRectIndex, "AARect",
- SKSL_AARECT_SRC, inputs,
- SkRect::MakeXYWH(-1, -1, -1, -1),
- aa_rect_set_data_hook);
- return std::unique_ptr<GrFragmentProcessor>(result.release());
+ return GrAARectEffect::Make(edgeType, rect);
}
GrConvexPolyEffect::~GrConvexPolyEffect() {}
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index 886fed4..d2ab4c9 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -50,14 +50,12 @@
* Creates an effect that clips against the path. If the path is not a convex polygon, is
* inverse filled, or has too many edges, this will return nullptr.
*/
- static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&,
- GrContext* context);
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&);
/**
- * Creates an effect that fills inside the rect with AA edges.
+ * Creates an effect that fills inside the rect with AA edges..
*/
- static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&,
- GrContext* context);
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&);
~GrConvexPolyEffect() override;
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 0666089..6478306 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -7,8 +7,6 @@
#include "GrRRectEffect.h"
-#include "GrContext.h"
-#include "GrContextPriv.h"
#include "GrConvexPolyEffect.h"
#include "GrFragmentProcessor.h"
#include "GrOvalEffect.h"
@@ -124,7 +122,7 @@
do {
GrClipEdgeType et =
(GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
- fp = GrRRectEffect::Make(et, rrect, d->context());
+ fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
} while (nullptr == fp);
return fp;
}
@@ -473,7 +471,7 @@
std::unique_ptr<GrFragmentProcessor> fp;
do {
GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
- fp = GrRRectEffect::Make(et, rrect, d->context());
+ fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
} while (nullptr == fp);
return fp;
}
@@ -672,14 +670,13 @@
std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType,
const SkRRect& rrect,
- GrContext* context) {
+ const GrShaderCaps& caps) {
if (rrect.isRect()) {
- return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
}
if (rrect.isOval()) {
- return GrOvalEffect::Make(edgeType, rrect.getBounds(),
- *context->contextPriv().caps()->shaderCaps());
+ return GrOvalEffect::Make(edgeType, rrect.getBounds(), caps);
}
if (rrect.isSimple()) {
@@ -687,7 +684,7 @@
SkRRectPriv::GetSimpleRadii(rrect).fY < kRadiusMin) {
// In this case the corners are extremely close to rectangular and we collapse the
// clip to a rectangular clip.
- return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
}
if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
return CircularRRectEffect::Make(edgeType, CircularRRectEffect::kAll_CornerFlags,
@@ -752,7 +749,7 @@
return CircularRRectEffect::Make(edgeType, cornerFlags, *rr);
}
case CircularRRectEffect::kNone_CornerFlags:
- return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
default: {
if (squashedRadii) {
// If we got here then we squashed some but not all the radii to zero. (If all
diff --git a/src/gpu/effects/GrRRectEffect.h b/src/gpu/effects/GrRRectEffect.h
index f44de74..55ef535 100644
--- a/src/gpu/effects/GrRRectEffect.h
+++ b/src/gpu/effects/GrRRectEffect.h
@@ -12,7 +12,6 @@
#include "GrTypesPriv.h"
#include "SkRefCnt.h"
-class GrContext;
class GrFragmentProcessor;
class GrShaderCaps;
class GrProcessor;
@@ -24,7 +23,7 @@
* Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support
* all varieties of SkRRect so the caller must check for a nullptr return.
*/
-std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, GrContext*);
+std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, const GrShaderCaps&);
};
#endif
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 3174d40..aa81ea5 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -6,6 +6,7 @@
*/
#include "GrSkSLFP.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "GrContext.h"
@@ -33,9 +34,6 @@
if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
fInputVars.push_back(&var);
}
- if (var.fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
- fUniformVars.push_back(&var);
- }
if (var.fModifiers.fLayout.fKey) {
fKeyVars.push_back(&var);
}
@@ -55,8 +53,7 @@
size_t offset = 0;
for (const auto& v : fInputVars) {
SkSL::String name(v->fName);
- if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
- &v->fType == fCompiler.context().fInt_Type.get()) {
+ if (&v->fType == fCompiler.context().fInt_Type.get()) {
offset = SkAlign4(offset);
int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset);
inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
@@ -83,172 +80,178 @@
return result;
}
-GrGLSLSkSLFP::GrGLSLSkSLFP(SkSL::Context* context,
- const std::vector<const SkSL::Variable*>* uniformVars,
- SkSL::String glsl,
- std::vector<SkSL::Compiler::FormatArg> formatArgs,
- void* extraData)
- : fContext(*context)
- , fUniformVars(*uniformVars)
- , fGLSL(glsl)
- , fFormatArgs(formatArgs)
- , fExtraData(extraData) {}
+class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLSkSLFP(const SkSL::Context* context, const std::vector<const SkSL::Variable*>* inputVars,
+ SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs)
+ : fContext(*context)
+ , fInputVars(*inputVars)
+ , fGLSL(glsl)
+ , fFormatArgs(formatArgs) {}
-GrSLType GrGLSLSkSLFP::uniformType(const SkSL::Type& type) {
- if (type == *fContext.fFloat_Type) {
+ GrSLType uniformType(const SkSL::Type& type) {
+ if (type == *fContext.fFloat_Type) {
+ return kFloat_GrSLType;
+ } else if (type == *fContext.fHalf_Type) {
+ return kHalf_GrSLType;
+ } else if (type == *fContext.fFloat2_Type) {
+ return kFloat2_GrSLType;
+ } else if (type == *fContext.fHalf2_Type) {
+ return kHalf2_GrSLType;
+ } else if (type == *fContext.fFloat4_Type) {
+ return kFloat4_GrSLType;
+ } else if (type == *fContext.fHalf4_Type) {
+ return kHalf4_GrSLType;
+ } else if (type == *fContext.fFloat4x4_Type) {
+ return kFloat4x4_GrSLType;
+ } else if (type == *fContext.fHalf4x4_Type) {
+ return kHalf4x4_GrSLType;
+ } else if (type == *fContext.fBool_Type) {
+ return kBool_GrSLType;
+ } else if (type == *fContext.fInt_Type) {
+ return kInt_GrSLType;
+ }
+ printf("%s\n", SkSL::String(type.fName).c_str());
+ SK_ABORT("unsupported uniform type");
return kFloat_GrSLType;
- } else if (type == *fContext.fHalf_Type) {
- return kHalf_GrSLType;
- } else if (type == *fContext.fFloat2_Type) {
- return kFloat2_GrSLType;
- } else if (type == *fContext.fHalf2_Type) {
- return kHalf2_GrSLType;
- } else if (type == *fContext.fFloat4_Type) {
- return kFloat4_GrSLType;
- } else if (type == *fContext.fHalf4_Type) {
- return kHalf4_GrSLType;
- } else if (type == *fContext.fFloat4x4_Type) {
- return kFloat4x4_GrSLType;
- } else if (type == *fContext.fHalf4x4_Type) {
- return kHalf4x4_GrSLType;
- } else if (type == *fContext.fBool_Type) {
- return kBool_GrSLType;
- } else if (type == *fContext.fInt_Type) {
- return kInt_GrSLType;
}
- SK_ABORT("unsupported uniform type");
- return kFloat_GrSLType;
-}
-void* GrGLSLSkSLFP::extraData() const {
- return fExtraData;
-}
-
-void GrGLSLSkSLFP::emitCode(EmitArgs& args) {
- for (const auto& v : fUniformVars) {
- if (v->fType != *fContext.fFragmentProcessor_Type) {
- fUniformHandles.push_back(args.fUniformHandler->addUniform(
- kFragment_GrShaderFlag,
- this->uniformType(v->fType),
- kDefault_GrSLPrecision,
- SkSL::String(v->fName).c_str()));
+ void emitCode(EmitArgs& args) override {
+ for (const auto& v : fInputVars) {
+ if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag && v->fType !=
+ *fContext.fFragmentProcessor_Type) {
+ fUniformHandles.push_back(args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag,
+ this->uniformType(v->fType),
+ kDefault_GrSLPrecision,
+ SkSL::String(v->fName).c_str()));
+ }
}
- }
- std::vector<SkString> childNames;
- for (int i = 0; i < this->numChildProcessors(); ++i) {
- childNames.push_back(SkStringPrintf("_child%d", i));
- this->emitChild(i, &childNames[i], args);
- }
- GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- int substringStartIndex = 0;
- int formatArgIndex = 0;
- for (size_t i = 0; i < fGLSL.length(); ++i) {
- char c = fGLSL[i];
- if (c == '%') {
- fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
- i - substringStartIndex);
- ++i;
- c = fGLSL[i];
- switch (c) {
- case 's': {
- SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
- switch (arg.fKind) {
- case SkSL::Compiler::FormatArg::Kind::kInput:
- fragBuilder->codeAppend(args.fInputColor);
- break;
- case SkSL::Compiler::FormatArg::Kind::kOutput:
- fragBuilder->codeAppend(args.fOutputColor);
- break;
- case SkSL::Compiler::FormatArg::Kind::kUniform:
- fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
- fUniformHandles[arg.fIndex]));
- break;
- case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
- fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
- break;
+ std::vector<SkString> childNames;
+ for (int i = 0; i < this->numChildProcessors(); ++i) {
+ childNames.push_back(SkStringPrintf("_child%d", i));
+ this->emitChild(i, &childNames[i], args);
+ }
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ int substringStartIndex = 0;
+ int formatArgIndex = 0;
+ for (size_t i = 0; i < fGLSL.length(); ++i) {
+ char c = fGLSL[i];
+ if (c == '%') {
+ fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
+ i - substringStartIndex);
+ ++i;
+ c = fGLSL[i];
+ switch (c) {
+ case 's': {
+ SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
+ switch (arg.fKind) {
+ case SkSL::Compiler::FormatArg::Kind::kInput:
+ fragBuilder->codeAppend(args.fInputColor);
+ break;
+ case SkSL::Compiler::FormatArg::Kind::kOutput:
+ fragBuilder->codeAppend(args.fOutputColor);
+ break;
+ case SkSL::Compiler::FormatArg::Kind::kUniform:
+ fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
+ fUniformHandles[arg.fIndex]));
+ break;
+ case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
+ fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
+ break;
+ }
+ break;
}
- break;
+ default:
+ fragBuilder->codeAppendf("%c", c);
}
- default:
- fragBuilder->codeAppendf("%c", c);
+ substringStartIndex = i + 1;
}
- substringStartIndex = i + 1;
}
+ fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
+ fGLSL.length() - substringStartIndex);
}
- fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
- fGLSL.length() - substringStartIndex);
-}
-void GrGLSLSkSLFP::onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& _proc) {
- size_t uniformIndex = 0;
- size_t offset = 0;
- const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
- uint8_t* inputs = (uint8_t*) outer.fInputs;
- const SkSL::Context& context = outer.fFactory->fCompiler.context();
- for (const auto& v : outer.fFactory->fInputVars) {
- if (&v->fType == context.fFloat4_Type.get() ||
- &v->fType == context.fHalf4_Type.get()) {
- float f1, f2, f3, f4;
- switch (v->fModifiers.fLayout.fCType) {
- case SkSL::Layout::CType::kSkPMColor:
- f1 = inputs[offset++] / 255.0;
- f2 = inputs[offset++] / 255.0;
- f3 = inputs[offset++] / 255.0;
- f4 = inputs[offset++] / 255.0;
- break;
- case SkSL::Layout::CType::kSkRect: // fall through
- case SkSL::Layout::CType::kDefault:
- offset = SkAlign4(offset);
- f1 = *(float*) (inputs + offset);
- offset += sizeof(float);
- f2 = *(float*) (inputs + offset);
- offset += sizeof(float);
- f3 = *(float*) (inputs + offset);
- offset += sizeof(float);
- f4 = *(float*) (inputs + offset);
- offset += sizeof(float);
- break;
- default:
- SK_ABORT("unsupported uniform ctype");
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ size_t uniformIndex = 0;
+ size_t offset = 0;
+ const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
+ char* inputs = (char*) outer.fInputs.get();
+ const SkSL::Context& context = outer.fFactory->fCompiler.context();
+ for (const auto& v : outer.fFactory->fInputVars) {
+ if (&v->fType == context.fFloat4_Type.get() ||
+ &v->fType == context.fHalf4_Type.get()) {
+ float f1, f2, f3, f4;
+ switch (v->fModifiers.fLayout.fCType) {
+ case SkSL::Layout::CType::kSkPMColor:
+ f1 = ((uint8_t*) inputs)[offset++] / 255.0;
+ f2 = ((uint8_t*) inputs)[offset++] / 255.0;
+ f3 = ((uint8_t*) inputs)[offset++] / 255.0;
+ f4 = ((uint8_t*) inputs)[offset++] / 255.0;
+ break;
+ case SkSL::Layout::CType::kSkRect: // fall through
+ case SkSL::Layout::CType::kDefault:
+ offset = SkAlign4(offset);
+ f1 = *(float*) (inputs + offset);
+ offset += sizeof(float);
+ f2 = *(float*) (inputs + offset);
+ offset += sizeof(float);
+ f3 = *(float*) (inputs + offset);
+ offset += sizeof(float);
+ f4 = *(float*) (inputs + offset);
+ offset += sizeof(float);
+ break;
+ default:
+ SK_ABORT("unsupported uniform ctype");
+ }
+ if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
+ pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
+ }
+ } else if (&v->fType == context.fInt_Type.get()) {
+ int32_t i = *(int*) (inputs + offset);
+ offset += sizeof(int32_t);
+ if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
+ pdman.set1i(fUniformHandles[uniformIndex++], i);
+ }
+ } else if (&v->fType == context.fBool_Type.get()) {
+ SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
+ ++offset;
+ } else {
+ SkASSERT(&v->fType == context.fFragmentProcessor_Type.get());
}
- if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
- pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
- }
- } else if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
- &v->fType == context.fInt_Type.get()) {
- int32_t i = *(int*) (inputs + offset);
- offset += sizeof(int32_t);
- if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
- pdman.set1i(fUniformHandles[uniformIndex++], i);
- }
- } else if (&v->fType == context.fBool_Type.get()) {
- SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
- ++offset;
- } else {
- SkASSERT(&v->fType == context.fFragmentProcessor_Type.get());
}
}
- if (fUniformHandles.size() && outer.fSetDataHook) {
- outer.fSetDataHook(pdman, *this, outer.fInputs, fExtraData);
- }
+
+ const SkSL::Context& fContext;
+ const std::vector<const SkSL::Variable*>& fInputVars;
+ // nearly-finished GLSL; still contains printf-style "%s" format tokens
+ const SkSL::String fGLSL;
+ std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
+ std::vector<UniformHandle> fUniformHandles;
+};
+
+std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext* context, int index, const char* name,
+ const char* sksl, const void* inputs,
+ size_t inputSize) {
+ return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->contextPriv().getFPFactoryCache(),
+ context->contextPriv().caps()->shaderCaps(),
+ index, name, sksl, inputs, inputSize));
}
GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
int index, const char* name, const char* sksl, const void* inputs,
- size_t inputSize, const void* extraData, size_t extraDataSize,
- UntypedDataHookFn setDataHook)
+ size_t inputSize)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
, fFactoryCache(factoryCache)
, fShaderCaps(sk_ref_sp(shaderCaps))
, fIndex(index)
, fName(name)
, fSkSL(sksl)
- , fInputs(inputs)
- , fInputSize(inputSize)
- , fExtraData(extraData)
- , fExtraDataSize(extraDataSize)
- , fSetDataHook(setDataHook) {}
+ , fInputs(new int8_t[inputSize])
+ , fInputSize(inputSize) {
+ memcpy(fInputs.get(), inputs, inputSize);
+}
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
@@ -258,11 +261,10 @@
, fIndex(other.fIndex)
, fName(other.fName)
, fSkSL(other.fSkSL)
- , fInputs(other.fInputs)
- , fInputSize(other.fInputSize)
- , fExtraData(other.fExtraData)
- , fExtraDataSize(other.fExtraDataSize)
- , fSetDataHook(other.fSetDataHook) {}
+ , fInputs(new int8_t[other.fInputSize])
+ , fInputSize(other.fInputSize) {
+ memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
+}
const char* GrSkSLFP::name() const {
return fName;
@@ -284,30 +286,24 @@
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
this->createFactory();
- const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs, fInputSize);
+ const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
SkSL::String glsl;
std::vector<SkSL::Compiler::FormatArg> formatArgs;
if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) {
printf("%s\n", fFactory->fCompiler.errorText().c_str());
SkASSERT(false);
}
- void* result = ::operator new(sizeof(GrGLSLSkSLFP) + fExtraDataSize);
- void* extraDataBytes = ((uint8_t*) result) + sizeof(GrGLSLSkSLFP);
- if (fExtraDataSize) {
- memcpy(extraDataBytes, fExtraData, fExtraDataSize);
- }
- return new (result) GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fUniformVars, glsl,
- formatArgs, extraDataBytes);
+ return new GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fInputVars, glsl, formatArgs);
}
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
this->createFactory();
size_t offset = 0;
- uint8_t* inputs = (uint8_t*) fInputs;
+ char* inputs = (char*) fInputs.get();
const SkSL::Context& context = fFactory->fCompiler.context();
for (const auto& v : fFactory->fInputVars) {
- if (v->fType.kind() == SkSL::Type::kEnum_Kind || &v->fType == context.fInt_Type.get()) {
+ if (&v->fType == context.fInt_Type.get()) {
offset = SkAlign4(offset);
if (v->fModifiers.fLayout.fKey) {
fKey += inputs[offset + 0];
@@ -354,20 +350,11 @@
const GrSkSLFP& sk = other.cast<GrSkSLFP>();
SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
return fIndex == sk.fIndex &&
- !memcmp(fInputs, sk.fInputs, fInputSize);
+ !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize);
}
std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
- void* placement = GrSkSLFP::operator new(sizeof(GrSkSLFP) + fInputSize + fExtraDataSize);
- std::unique_ptr<GrSkSLFP> result(new (placement) GrSkSLFP(*this));
- void* inputsTarget = ((int8_t*) placement) + sizeof(GrSkSLFP);
- memcpy(inputsTarget, fInputs, fInputSize);
- result->fInputs = inputsTarget;
- if (fExtraData) {
- void* extraDataTarget = ((int8_t*) placement) + sizeof(GrSkSLFP) + fInputSize;
- memcpy(extraDataTarget, fExtraData, fExtraDataSize);
- result->fExtraData = extraDataTarget;
- }
+ std::unique_ptr<GrSkSLFP> result(new GrSkSLFP(*this));
for (int i = 0; i < this->numChildProcessors(); ++i) {
result->registerChildProcessor(this->childProcessor(i).clone());
}
@@ -411,7 +398,6 @@
#include "GrConstColorProcessor.h"
#include "SkArithmeticImageFilter.h"
-#include "effects/GrConvexPolyEffect.h"
extern const char* SKSL_ARITHMETIC_SRC;
extern const char* SKSL_DITHER_SRC;
@@ -420,13 +406,14 @@
using Value = SkSL::Program::Settings::Value;
std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
- int type = d->fRandom->nextULessThan(4);
+ int type = d->fRandom->nextULessThan(3);
switch (type) {
case 0: {
static int ditherIndex = NewIndex();
int rangeType = d->fRandom->nextULessThan(3);
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), ditherIndex, "Dither",
- SKSL_DITHER_SRC, rangeType);
+ SKSL_DITHER_SRC, &rangeType,
+ sizeof(rangeType));
return std::unique_ptr<GrFragmentProcessor>(result.release());
}
case 1: {
@@ -439,7 +426,7 @@
inputs.enforcePMColor = d->fRandom->nextBool();
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), arithmeticIndex,
"Arithmetic", SKSL_ARITHMETIC_SRC,
- inputs);
+ &inputs, sizeof(inputs));
result->addChild(GrConstColorProcessor::Make(
SK_PMColor4fWHITE,
GrConstColorProcessor::InputMode::kIgnore));
@@ -453,23 +440,9 @@
}
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), overdrawIndex,
"Overdraw", SKSL_OVERDRAW_SRC,
- inputs);
+ &inputs, sizeof(inputs));
return std::unique_ptr<GrFragmentProcessor>(result.release());
}
- case 3: {
- SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
- d->fRandom->nextSScalar1(),
- d->fRandom->nextSScalar1(),
- d->fRandom->nextSScalar1());
- std::unique_ptr<GrFragmentProcessor> fp;
- do {
- GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
- d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
-
- fp = GrConvexPolyEffect::Make(edgeType, rect, d->context());
- } while (nullptr == fp);
- return fp;
- }
}
SK_ABORT("unreachable");
return nullptr;
diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h
index ae9be33..c4acfd0 100644
--- a/src/gpu/effects/GrSkSLFP.h
+++ b/src/gpu/effects/GrSkSLFP.h
@@ -9,17 +9,12 @@
#define GrSkSLFP_DEFINED
#include "GrCaps.h"
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
#include "GrShaderCaps.h"
#include "SkSLCompiler.h"
#include "SkSLPipelineStageCodeGenerator.h"
#include "SkRefCnt.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
#include "../private/GrSkSLFPFactoryCache.h"
#if GR_TEST_UTILS
@@ -30,16 +25,9 @@
class GrContext;
class GrSkSLFPFactory;
-class GrGLSLSkSLFP;
class GrSkSLFP : public GrFragmentProcessor {
public:
- using UniformHandle = GrGLSLUniformHandler::UniformHandle;
-
- template<typename Inputs, typename ExtraData>
- using DataHookFn = void(const GrGLSLProgramDataManager& pdman, const GrGLSLSkSLFP& glslProc,
- const Inputs& inputs, ExtraData* extraData);
-
/**
* Returns a new unique identifier. Each different SkSL fragment processor should call
* NewIndex once, statically, and use this index for all calls to Make.
@@ -78,72 +66,23 @@
* 'NewIndex()'. Each given SkSL string should have a single, statically defined index
* associated with it.
*/
- template<typename Inputs>
- static std::unique_ptr<GrSkSLFP> Make(GrContext* context, int index, const char* name,
- const char* sksl, const Inputs& inputs) {
- void* resultBytes = GrSkSLFP::operator new(sizeof(GrSkSLFP) + sizeof(Inputs));
- void* inputBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP);
- memcpy(inputBytes, &inputs, sizeof(Inputs));
- GrSkSLFP* result = new (resultBytes) GrSkSLFP(context->contextPriv().getFPFactoryCache(),
- context->contextPriv().caps()->shaderCaps(),
- index, name, sksl, inputBytes,
- sizeof(Inputs), nullptr, 0, nullptr);
- return std::unique_ptr<GrSkSLFP>(result);
- }
-
- /**
- * As the above overload of Make, but also tracks an additional extraData struct which is shared
- * between all instances of the FP. The extraData struct is copied into the GrGLSLSkSLFP and is
- * passed as an argument to the setDataHook function. setDataHook is called after the automatic
- * handling of 'in uniform' variables is completed and is responsible for providing values for
- * all non-'in' uniform variables.
- */
- template<typename Inputs, typename ExtraData>
- static std::unique_ptr<GrSkSLFP> Make(GrContext* context, int index, const char* name,
- const char* sksl, const Inputs& inputs,
- const ExtraData& extraData,
- DataHookFn<Inputs, ExtraData>* setDataHook) {
- void* resultBytes = GrSkSLFP::operator new(sizeof(GrSkSLFP) + sizeof(Inputs) +
- sizeof(ExtraData));
- void* inputBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP);
- memcpy(inputBytes, &inputs, sizeof(Inputs));
- void* extraDataBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP) + sizeof(Inputs);
- memcpy(extraDataBytes, &extraData, sizeof(ExtraData));
- auto genericFn = [setDataHook] (const GrGLSLProgramDataManager& pdman,
- const GrGLSLSkSLFP& glslProc,
- const void* inputs,
- void* extraData) {
- (*setDataHook)(pdman, glslProc, *reinterpret_cast<const Inputs*>(inputs),
- reinterpret_cast<ExtraData*>(extraData));
- };
- return std::unique_ptr<GrSkSLFP>(new (resultBytes) GrSkSLFP(
- context->contextPriv().getFPFactoryCache(),
- context->contextPriv().caps()->shaderCaps(),
- index, name, sksl, inputBytes,
- sizeof(Inputs), extraDataBytes,
- sizeof(ExtraData), genericFn));
- }
+ static std::unique_ptr<GrSkSLFP> Make(
+ GrContext* context,
+ int index,
+ const char* name,
+ const char* sksl,
+ const void* inputs,
+ size_t inputSize);
const char* name() const override;
void addChild(std::unique_ptr<GrFragmentProcessor> child);
- void setSetDataHook(void (*hook)(const GrGLSLProgramDataManager& pdman,
- const GrGLSLSkSLFP& glslProc,
- const GrSkSLFP& proc));
-
- const void* inputs() const { return fInputs; }
-
std::unique_ptr<GrFragmentProcessor> clone() const override;
private:
- using UntypedDataHookFn = std::function<void(const GrGLSLProgramDataManager&,
- const GrGLSLSkSLFP&,
- const void*,
- void*)>;
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, int fIndex,
- const char* name, const char* sksl, const void* inputs, size_t inputSize,
- const void* extraData, size_t extraDataSize, UntypedDataHookFn setDataHook);
+ const char* name, const char* sksl, const void* inputs, size_t inputSize);
GrSkSLFP(const GrSkSLFP& other);
@@ -167,16 +106,10 @@
const char* fSkSL;
- const void* fInputs;
+ const std::unique_ptr<int8_t[]> fInputs;
size_t fInputSize;
- const void* fExtraData;
-
- size_t fExtraDataSize;
-
- UntypedDataHookFn fSetDataHook;
-
mutable SkSL::String fKey;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
@@ -188,41 +121,6 @@
friend class GrSkSLFPFactory;
};
-class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
-public:
- GrGLSLSkSLFP(SkSL::Context* context, const std::vector<const SkSL::Variable*>* uniformVars,
- SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs,
- void* extraData);
-
- GrSLType uniformType(const SkSL::Type& type);
-
- /**
- * Returns the extraData pointer.
- */
- void* extraData() const;
-
- void emitCode(EmitArgs& args) override;
-
- void onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& _proc) override;
-
- UniformHandle uniformHandle(int index) const { return fUniformHandles[index]; }
-
-private:
- const SkSL::Context& fContext;
-
- const std::vector<const SkSL::Variable*>& fUniformVars;
-
- // nearly-finished GLSL; still contains printf-style "%s" format tokens
- const SkSL::String fGLSL;
-
- std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
-
- std::vector<UniformHandle> fUniformHandles;
-
- void* fExtraData;
-};
-
/**
* Produces GrFragmentProcessors from SkSL code. As the shader code produced from the SkSL depends
* upon the inputs to the SkSL (static if's, etc.) we first create a factory for a given SkSL
@@ -249,8 +147,6 @@
std::vector<const SkSL::Variable*> fInputVars;
- std::vector<const SkSL::Variable*> fUniformVars;
-
std::vector<const SkSL::Variable*> fKeyVars;
std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;