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>
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp
index f3f10ae..5802eaf 100644
--- a/gm/bigrrectaaeffect.cpp
+++ b/gm/bigrrectaaeffect.cpp
@@ -7,7 +7,6 @@
#include "gm.h"
#include "sk_tool_utils.h"
-#include "GrCaps.h"
#include "GrContext.h"
#include "GrRenderTargetContextPriv.h"
#include "SkRRect.h"
@@ -82,8 +81,7 @@
SkRRect rrect = fRRect;
rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
- const auto& caps = *renderTargetContext->caps()->shaderCaps();
- auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
+ auto fp = GrRRectEffect::Make(edgeType, rrect, context);
SkASSERT(fp);
if (fp) {
GrPaint grPaint;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 462405e..b3c2d19 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -205,7 +205,9 @@
path->transform(m, &p);
GrClipEdgeType edgeType = (GrClipEdgeType) et;
- std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, p));
+ std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(
+ edgeType, p,
+ canvas->getGrContext()));
if (!fp) {
continue;
}
@@ -245,7 +247,9 @@
SkRect rect = *iter.get();
rect.offset(x, y);
GrClipEdgeType edgeType = (GrClipEdgeType) et;
- std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, rect));
+ std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(
+ edgeType, rect,
+ canvas->getGrContext()));
if (!fp) {
continue;
}
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index 2fbd3b9..4e5fce1 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -105,8 +105,7 @@
SkRRect rrect = fRRects[curRRect];
rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
GrClipEdgeType edgeType = (GrClipEdgeType) et;
- const auto& caps = *renderTargetContext->caps()->shaderCaps();
- auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
+ auto fp = GrRRectEffect::Make(edgeType, rrect, context);
if (fp) {
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index 14d10e2..57744d9 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -179,7 +179,7 @@
return;
}
- const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), rtc->caps(), kNumWindows);
+ const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), ctx, kNumWindows);
GrPaint paint;
if (GrFSAAType::kNone == rtc->fsaaType()) {
@@ -231,7 +231,7 @@
// Draw a checker pattern into the stencil buffer so we can visualize the regions left untouched
// by the clip mask generation.
this->stencilCheckerboard(rtc, false);
- reducedClip.drawStencilClipMask(ctx, rtc);
+ reducedClip.drawStencilClipMask(rtc);
// Now visualize the stencil mask by covering the entire render target. The regions inside
// window rectangles or outside the scissor should still have the initial checkerboard intact.
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 4f54eb1..defaacf 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -295,8 +295,6 @@
"$_src/gpu/ops/GrTextureOp.cpp",
"$_src/gpu/ops/GrTextureOp.h",
- "$_src/gpu/effects/GrAARectEffect.cpp",
- "$_src/gpu/effects/GrAARectEffect.h",
"$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.cpp",
"$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.h",
"$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 7497a64..3543896 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -30,7 +30,6 @@
]
skia_gpu_processor_sources = [
- "$_src/gpu/effects/GrAARectEffect.fp",
"$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.fp",
"$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp",
"$_src/gpu/effects/GrCircleBlurFragmentProcessor.fp",
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index 12c9921..35ef587 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -91,8 +91,7 @@
std::unique_ptr<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(
GrContext* context, const GrColorSpaceInfo&) const {
static int overdrawIndex = GrSkSLFP::NewIndex();
- return GrSkSLFP::Make(context, overdrawIndex, "Overdraw", SKSL_OVERDRAW_SRC, fColors,
- sizeof(fColors));
+ return GrSkSLFP::Make(context, overdrawIndex, "Overdraw", SKSL_OVERDRAW_SRC, fColors);
}
#endif
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index bd72e3a..c1663c0 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -344,8 +344,7 @@
arithmeticIndex,
"Arithmetic",
SKSL_ARITHMETIC_SRC,
- &inputs,
- sizeof(inputs));
+ inputs);
if (xferFP) {
((GrSkSLFP&) *xferFP).addChild(std::move(bgFP));
paint.addColorFragmentProcessor(std::move(xferFP));
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 92af020..5c429e0 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->contextPriv().caps(),
- maxWindowRectangles, maxAnalyticFPs, ccpr ? maxAnalyticFPs : 0);
+ GrReducedClip reducedClip(*fStack, devBounds, context, 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(context, renderTargetContext);
+ reducedClip.drawStencilClipMask(renderTargetContext);
renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor(),
reducedClip.numAnalyticFPs());
}
diff --git a/src/gpu/GrMemoryPool.cpp b/src/gpu/GrMemoryPool.cpp
index 89e8f01..7d085ea 100644
--- a/src/gpu/GrMemoryPool.cpp
+++ b/src/gpu/GrMemoryPool.cpp
@@ -11,6 +11,7 @@
#include "SkAtomics.h"
#endif
#include "ops/GrOp.h"
+#include "effects/GrSkSLFP.h"
#ifdef SK_DEBUG
#define VALIDATE this->validate()
@@ -18,6 +19,13 @@
#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 15399b6..316deae 100644
--- a/src/gpu/GrMemoryPool.h
+++ b/src/gpu/GrMemoryPool.h
@@ -115,13 +115,10 @@
SkTHashSet<int32_t> fAllocatedIDs;
#endif
-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),
- };
+public:
+ constexpr static size_t kBlockHeaderSize = sizeof(BlockHeader);
+
+ constexpr static size_t kAllocHeaderSize = sizeof(AllocHeader);
};
class GrOp;
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index aafe1d8..078cfbdf 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 = 36;
+static const int kFPFactoryCount = 35;
static const int kGPFactoryCount = 14;
static const int kXPFactoryCount = 4;
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 4cf3477..111ef7f 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -22,7 +22,6 @@
#include "GrUserStencilSettings.h"
#include "SkClipOpPriv.h"
#include "ccpr/GrCoverageCountingPathRenderer.h"
-#include "effects/GrAARectEffect.h"
#include "effects/GrConvexPolyEffect.h"
#include "effects/GrRRectEffect.h"
@@ -34,9 +33,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,
- const GrCaps* caps, int maxWindowRectangles, int maxAnalyticFPs,
- int maxCCPRClipPaths)
- : fCaps(caps)
+ GrContext* context, int maxWindowRectangles,
+ int maxAnalyticFPs, int maxCCPRClipPaths)
+ : fContext(context)
, fMaxWindowRectangles(maxWindowRectangles)
, fMaxAnalyticFPs(maxAnalyticFPs)
, fMaxCCPRClipPaths(maxCCPRClipPaths) {
@@ -612,13 +611,14 @@
}
}
-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(GrAARectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect));
+ fAnalyticFPs.push_back(GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect,
+ fContext));
SkASSERT(fAnalyticFPs.back());
return ClipResult::kClipped;
@@ -630,8 +630,7 @@
return ClipResult::kNotClipped;
}
- if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect,
- *fCaps->shaderCaps())) {
+ if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect, fContext)) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
}
@@ -648,7 +647,8 @@
return ClipResult::kNotClipped;
}
- if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath)) {
+ if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath,
+ fContext)) {
fAnalyticFPs.push_back(std::move(fp));
return ClipResult::kClipped;
}
@@ -805,8 +805,7 @@
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer.
-bool GrReducedClip::drawStencilClipMask(GrContext* context,
- GrRenderTargetContext* renderTargetContext) const {
+bool GrReducedClip::drawStencilClipMask(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());
@@ -848,14 +847,14 @@
GrShape shape(clipPath, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
- canDrawArgs.fCaps = context->contextPriv().caps();
+ canDrawArgs.fCaps = fContext->contextPriv().caps();
canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
canDrawArgs.fViewMatrix = &SkMatrix::I();
canDrawArgs.fShape = &shape;
canDrawArgs.fAAType = aaType;
canDrawArgs.fHasUserStencilSettings = false;
- GrDrawingManager* dm = context->contextPriv().drawingManager();
+ GrDrawingManager* dm = fContext->contextPriv().drawingManager();
pr = dm->getPathRenderer(canDrawArgs, false, GrPathRendererChain::DrawType::kStencil,
&stencilSupport);
if (!pr) {
@@ -895,7 +894,7 @@
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- GrPathRenderer::DrawPathArgs args{context,
+ GrPathRenderer::DrawPathArgs args{fContext,
std::move(paint),
&kDrawToStencil,
renderTargetContext,
@@ -908,7 +907,7 @@
pr->drawPath(args);
} else {
GrPathRenderer::StencilPathArgs args;
- args.fContext = context;
+ args.fContext = fContext;
args.fRenderTargetContext = renderTargetContext;
args.fClip = &stencilClip.fixedClip();
args.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
@@ -933,7 +932,7 @@
GrShape shape(clipPath, GrStyle::SimpleFill());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- GrPathRenderer::DrawPathArgs args{context,
+ GrPathRenderer::DrawPathArgs args{fContext,
std::move(paint),
*pass,
renderTargetContext,
@@ -967,7 +966,7 @@
SkASSERT(ccpr);
SkASSERT(fHasScissor);
auto fp = ccpr->makeClipProcessor(opListID, ccprClipPath, fScissor, rtWidth, rtHeight,
- *fCaps);
+ *fContext->contextPriv().caps());
fAnalyticFPs.push_back(std::move(fp));
}
fCCPRClipPaths.reset();
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index fcdc66c..6a8bc9e 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -26,8 +26,9 @@
using Element = SkClipStack::Element;
using ElementList = SkTLList<SkClipStack::Element, 16>;
- GrReducedClip(const SkClipStack&, const SkRect& queryBounds, const GrCaps* caps,
- int maxWindowRectangles = 0, int maxAnalyticFPs = 0, int maxCCPRClipPaths = 0);
+ GrReducedClip(const SkClipStack&, const SkRect& queryBounds, GrContext* context,
+ int maxWindowRectangles = 0, int maxAnalyticFPs = 0,
+ int maxCCPRClipPaths = 0);
enum class InitialState : bool {
kAllIn,
@@ -83,7 +84,7 @@
bool maskRequiresAA() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskRequiresAA; }
bool drawAlphaClipMask(GrRenderTargetContext*) const;
- bool drawStencilClipMask(GrContext*, GrRenderTargetContext*) const;
+ bool drawStencilClipMask(GrRenderTargetContext*) const;
int numAnalyticFPs() const { return fAnalyticFPs.count() + fCCPRClipPaths.count(); }
@@ -131,7 +132,7 @@
void makeEmpty();
- const GrCaps* fCaps;
+ GrContext* fContext;
const int fMaxWindowRectangles;
const int fMaxAnalyticFPs;
const int fMaxCCPRClipPaths;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 584ed33..3333328 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1224,14 +1224,13 @@
inverseVM.reset();
}
- const auto& caps = *this->caps()->shaderCaps();
// TODO these need to be a geometry processors
- auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
+ auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, fContext);
if (!innerEffect) {
return false;
}
- auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
+ auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, fContext);
if (!outerEffect) {
return false;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index f78ef18..9f348c2 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, sizeof(ditherRange));
+ ditherRange);
if (ditherFP) {
grPaint->addColorFragmentProcessor(std::move(ditherFP));
}
diff --git a/src/gpu/effects/GrAARectEffect.cpp b/src/gpu/effects/GrAARectEffect.cpp
deleted file mode 100644
index 9ee0ad5..0000000
--- a/src/gpu/effects/GrAARectEffect.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 95064dd..0000000
--- a/src/gpu/effects/GrAARectEffect.fp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 94974e2..0000000
--- a/src/gpu/effects/GrAARectEffect.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 4751fec..a0440f0 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -7,13 +7,52 @@
#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 {
@@ -88,7 +127,8 @@
//////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType type,
- const SkPath& path) {
+ const SkPath& path,
+ GrContext* context) {
if (GrClipEdgeType::kHairlineAA == type) {
return nullptr;
}
@@ -158,12 +198,34 @@
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) {
+ const SkRect& rect,
+ GrContext* context) {
if (GrClipEdgeType::kHairlineAA == edgeType){
return nullptr;
}
- return GrAARectEffect::Make(edgeType, rect);
+ 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());
}
GrConvexPolyEffect::~GrConvexPolyEffect() {}
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index d2ab4c9..886fed4 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -50,12 +50,14 @@
* 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&);
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&,
+ GrContext* context);
/**
- * 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&);
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&,
+ GrContext* context);
~GrConvexPolyEffect() override;
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 6478306..0666089 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -7,6 +7,8 @@
#include "GrRRectEffect.h"
+#include "GrContext.h"
+#include "GrContextPriv.h"
#include "GrConvexPolyEffect.h"
#include "GrFragmentProcessor.h"
#include "GrOvalEffect.h"
@@ -122,7 +124,7 @@
do {
GrClipEdgeType et =
(GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
- fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
+ fp = GrRRectEffect::Make(et, rrect, d->context());
} while (nullptr == fp);
return fp;
}
@@ -471,7 +473,7 @@
std::unique_ptr<GrFragmentProcessor> fp;
do {
GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
- fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
+ fp = GrRRectEffect::Make(et, rrect, d->context());
} while (nullptr == fp);
return fp;
}
@@ -670,13 +672,14 @@
std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType,
const SkRRect& rrect,
- const GrShaderCaps& caps) {
+ GrContext* context) {
if (rrect.isRect()) {
- return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
}
if (rrect.isOval()) {
- return GrOvalEffect::Make(edgeType, rrect.getBounds(), caps);
+ return GrOvalEffect::Make(edgeType, rrect.getBounds(),
+ *context->contextPriv().caps()->shaderCaps());
}
if (rrect.isSimple()) {
@@ -684,7 +687,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());
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
}
if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
return CircularRRectEffect::Make(edgeType, CircularRRectEffect::kAll_CornerFlags,
@@ -749,7 +752,7 @@
return CircularRRectEffect::Make(edgeType, cornerFlags, *rr);
}
case CircularRRectEffect::kNone_CornerFlags:
- return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
+ return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
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 55ef535..f44de74 100644
--- a/src/gpu/effects/GrRRectEffect.h
+++ b/src/gpu/effects/GrRRectEffect.h
@@ -12,6 +12,7 @@
#include "GrTypesPriv.h"
#include "SkRefCnt.h"
+class GrContext;
class GrFragmentProcessor;
class GrShaderCaps;
class GrProcessor;
@@ -23,7 +24,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&, const GrShaderCaps&);
+std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, GrContext*);
};
#endif
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index aa81ea5..3174d40 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -6,7 +6,6 @@
*/
#include "GrSkSLFP.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "GrContext.h"
@@ -34,6 +33,9 @@
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);
}
@@ -53,7 +55,8 @@
size_t offset = 0;
for (const auto& v : fInputVars) {
SkSL::String name(v->fName);
- if (&v->fType == fCompiler.context().fInt_Type.get()) {
+ if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
+ &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)));
@@ -80,178 +83,172 @@
return result;
}
-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) {}
+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) {}
- 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");
+GrSLType GrGLSLSkSLFP::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;
}
+ SK_ABORT("unsupported uniform type");
+ return kFloat_GrSLType;
+}
- 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()));
- }
+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()));
}
- 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;
+ }
+ 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;
}
- default:
- fragBuilder->codeAppendf("%c", c);
+ break;
}
- substringStartIndex = i + 1;
+ default:
+ fragBuilder->codeAppendf("%c", c);
}
- }
- fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
- fGLSL.length() - substringStartIndex);
- }
-
- 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());
- }
+ substringStartIndex = i + 1;
}
}
+ fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
+ fGLSL.length() - substringStartIndex);
+}
- 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));
+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");
+ }
+ 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);
+ }
}
GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
int index, const char* name, const char* sksl, const void* inputs,
- size_t inputSize)
+ size_t inputSize, const void* extraData, size_t extraDataSize,
+ UntypedDataHookFn setDataHook)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
, fFactoryCache(factoryCache)
, fShaderCaps(sk_ref_sp(shaderCaps))
, fIndex(index)
, fName(name)
, fSkSL(sksl)
- , fInputs(new int8_t[inputSize])
- , fInputSize(inputSize) {
- memcpy(fInputs.get(), inputs, inputSize);
-}
+ , fInputs(inputs)
+ , fInputSize(inputSize)
+ , fExtraData(extraData)
+ , fExtraDataSize(extraDataSize)
+ , fSetDataHook(setDataHook) {}
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
@@ -261,10 +258,11 @@
, fIndex(other.fIndex)
, fName(other.fName)
, fSkSL(other.fSkSL)
- , fInputs(new int8_t[other.fInputSize])
- , fInputSize(other.fInputSize) {
- memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
-}
+ , fInputs(other.fInputs)
+ , fInputSize(other.fInputSize)
+ , fExtraData(other.fExtraData)
+ , fExtraDataSize(other.fExtraDataSize)
+ , fSetDataHook(other.fSetDataHook) {}
const char* GrSkSLFP::name() const {
return fName;
@@ -286,24 +284,30 @@
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
this->createFactory();
- const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
+ const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs, 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);
}
- return new GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fInputVars, glsl, formatArgs);
+ 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);
}
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
this->createFactory();
size_t offset = 0;
- char* inputs = (char*) fInputs.get();
+ uint8_t* inputs = (uint8_t*) fInputs;
const SkSL::Context& context = fFactory->fCompiler.context();
for (const auto& v : fFactory->fInputVars) {
- if (&v->fType == context.fInt_Type.get()) {
+ if (v->fType.kind() == SkSL::Type::kEnum_Kind || &v->fType == context.fInt_Type.get()) {
offset = SkAlign4(offset);
if (v->fModifiers.fLayout.fKey) {
fKey += inputs[offset + 0];
@@ -350,11 +354,20 @@
const GrSkSLFP& sk = other.cast<GrSkSLFP>();
SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
return fIndex == sk.fIndex &&
- !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize);
+ !memcmp(fInputs, sk.fInputs, fInputSize);
}
std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
- std::unique_ptr<GrSkSLFP> result(new GrSkSLFP(*this));
+ 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;
+ }
for (int i = 0; i < this->numChildProcessors(); ++i) {
result->registerChildProcessor(this->childProcessor(i).clone());
}
@@ -398,6 +411,7 @@
#include "GrConstColorProcessor.h"
#include "SkArithmeticImageFilter.h"
+#include "effects/GrConvexPolyEffect.h"
extern const char* SKSL_ARITHMETIC_SRC;
extern const char* SKSL_DITHER_SRC;
@@ -406,14 +420,13 @@
using Value = SkSL::Program::Settings::Value;
std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
- int type = d->fRandom->nextULessThan(3);
+ int type = d->fRandom->nextULessThan(4);
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,
- sizeof(rangeType));
+ SKSL_DITHER_SRC, rangeType);
return std::unique_ptr<GrFragmentProcessor>(result.release());
}
case 1: {
@@ -426,7 +439,7 @@
inputs.enforcePMColor = d->fRandom->nextBool();
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), arithmeticIndex,
"Arithmetic", SKSL_ARITHMETIC_SRC,
- &inputs, sizeof(inputs));
+ inputs);
result->addChild(GrConstColorProcessor::Make(
SK_PMColor4fWHITE,
GrConstColorProcessor::InputMode::kIgnore));
@@ -440,9 +453,23 @@
}
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), overdrawIndex,
"Overdraw", SKSL_OVERDRAW_SRC,
- &inputs, sizeof(inputs));
+ 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 c4acfd0..ae9be33 100644
--- a/src/gpu/effects/GrSkSLFP.h
+++ b/src/gpu/effects/GrSkSLFP.h
@@ -9,12 +9,17 @@
#define GrSkSLFP_DEFINED
#include "GrCaps.h"
-#include "GrFragmentProcessor.h"
+#include "GrContext.h"
+#include "GrContextPriv.h"
#include "GrCoordTransform.h"
+#include "GrFragmentProcessor.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
@@ -25,9 +30,16 @@
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.
@@ -66,23 +78,72 @@
* 'NewIndex()'. Each given SkSL string should have a single, statically defined index
* associated with it.
*/
- static std::unique_ptr<GrSkSLFP> Make(
- GrContext* context,
- int index,
- const char* name,
- const char* sksl,
- const void* inputs,
- size_t inputSize);
+ 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));
+ }
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 char* name, const char* sksl, const void* inputs, size_t inputSize,
+ const void* extraData, size_t extraDataSize, UntypedDataHookFn setDataHook);
GrSkSLFP(const GrSkSLFP& other);
@@ -106,10 +167,16 @@
const char* fSkSL;
- const std::unique_ptr<int8_t[]> fInputs;
+ const void* fInputs;
size_t fInputSize;
+ const void* fExtraData;
+
+ size_t fExtraDataSize;
+
+ UntypedDataHookFn fSetDataHook;
+
mutable SkSL::String fKey;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
@@ -121,6 +188,41 @@
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
@@ -147,6 +249,8 @@
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;
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index c267058..f7492eb 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -596,6 +596,11 @@
case Statement::kSwitch_Kind: {
SwitchStatement& ss = (SwitchStatement&) **s;
this->addExpression(cfg, &ss.fValue, true);
+ for (const auto& c : ss.fCases) {
+ if (c->fValue) {
+ this->addExpression(cfg, &c->fValue, true);
+ }
+ }
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
nullptr, s });
BlockId start = cfg.fCurrent;
@@ -604,11 +609,6 @@
for (const auto& c : ss.fCases) {
cfg.newBlock();
cfg.addExit(start, cfg.fCurrent);
- if (c->fValue) {
- // technically this should go in the start block, but it doesn't actually matter
- // because it must be constant. Not worth running two loops for.
- this->addExpression(cfg, &c->fValue, true);
- }
for (auto& caseStatement : c->fStatements) {
this->addStatement(cfg, &caseStatement);
}
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 41ff5cc..09af06b 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -57,6 +57,7 @@
;
static const char* SKSL_PIPELINE_STAGE_INCLUDE =
+#include "sksl_enums.inc"
#include "sksl_pipeline.inc"
;
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index bf9e5e1..5f79896 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -933,14 +933,13 @@
ASTType enumType(e.fOffset, e.fTypeName, ASTType::kIdentifier_Kind, {});
const Type* type = this->convertType(enumType);
Modifiers modifiers(layout, Modifiers::kConst_Flag);
- std::shared_ptr<SymbolTable> symbols(new SymbolTable(fSymbolTable, &fErrors));
- fSymbolTable = symbols;
+ AutoSymbolTable s(this);
+ std::shared_ptr<SymbolTable> symbols = fSymbolTable;
for (size_t i = 0; i < e.fNames.size(); i++) {
std::unique_ptr<Expression> value;
if (e.fValues[i]) {
value = this->convertExpression(*e.fValues[i]);
if (!value) {
- fSymbolTable = symbols->fParent;
return;
}
this->getConstantInt(*value, ¤tValue);
@@ -956,7 +955,6 @@
}
fProgramElements->push_back(std::unique_ptr<ProgramElement>(new Enum(e.fOffset, e.fTypeName,
symbols)));
- fSymbolTable = symbols->fParent;
}
const Type* IRGenerator::convertType(const ASTType& type) {
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index 4ca839d..694b368 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -146,8 +146,7 @@
found = true;
break;
}
- if (var.fModifiers.fFlags & (Modifiers::kIn_Flag |
- Modifiers::kUniform_Flag)) {
+ if (var.fModifiers.fFlags & Modifiers::kUniform_Flag) {
++index;
}
}
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 4cbde55..719767d 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -223,6 +223,14 @@
, fInheritedElements(inheritedElements)
, fElements(std::move(elements)) {}
+ ~Program() {
+ // destroy elements in reverse order, so references to variables are destroyed before the
+ // variables themselves
+ while (fElements.size()) {
+ fElements.pop_back();
+ }
+ }
+
iterator begin() {
if (fInheritedElements) {
return iterator(fInheritedElements->begin(), fInheritedElements->end(),
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 2cfeaae..0f1966b 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -1041,7 +1041,6 @@
}
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
// Zero the memory we will new the GrReducedClip into. This ensures the elements gen ID
// will be kInvalidGenID if left uninitialized.
@@ -1052,7 +1051,8 @@
// Get the reduced version of the stack.
SkRect queryBounds = kBounds;
queryBounds.outset(kBounds.width() / 2, kBounds.height() / 2);
- const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, queryBounds, caps);
+ const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, queryBounds,
+ context.get());
REPORTER_ASSERT(reporter,
reduced->maskElements().isEmpty() ||
@@ -1112,12 +1112,12 @@
SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
SkAlignedSTStorage<1, GrReducedClip> storage;
memset(storage.get(), 0, sizeof(GrReducedClip));
GR_STATIC_ASSERT(0 == SkClipStack::kInvalidGenID);
- const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds, caps);
+ const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds,
+ context.get());
REPORTER_ASSERT(reporter, reduced->maskElements().count() == 1);
// Clips will be cached based on the generation id. Make sure the gen id is valid.
@@ -1201,10 +1201,9 @@
#undef XYWH
#undef IXYWH
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
for (size_t i = 0; i < SK_ARRAY_COUNT(testCases); ++i) {
- const GrReducedClip reduced(stack, testCases[i].testBounds, caps);
+ const GrReducedClip reduced(stack, testCases[i].testBounds, context.get());
REPORTER_ASSERT(reporter, reduced.maskElements().count() ==
testCases[i].reducedClipCount);
SkASSERT(reduced.maskElements().count() == testCases[i].reducedClipCount);
@@ -1229,10 +1228,9 @@
SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
// At the time, this would crash.
- const GrReducedClip reduced(stack, bounds, caps);
+ const GrReducedClip reduced(stack, bounds, context.get());
REPORTER_ASSERT(reporter, reduced.maskElements().isEmpty());
}
@@ -1248,11 +1246,10 @@
const SkRect& preXformQuery, ClipMethod expectedMethod,
int numExpectedElems = 0) {
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
SkRect queryBounds;
queryXform.mapRect(&queryBounds, preXformQuery);
- const GrReducedClip reduced(stack, queryBounds, caps);
+ const GrReducedClip reduced(stack, queryBounds, context.get());
SkClipStack::BoundsType stackBoundsType;
SkRect stackBounds;
@@ -1410,14 +1407,13 @@
pathStack.clipPath(clipPath, SkMatrix::I(), kIntersect_SkClipOp, true);
auto context = GrContext::MakeMock(nullptr);
- const GrCaps* caps = context->contextPriv().caps();
for (const SkClipStack& stack : {rectStack, pathStack}) {
for (SkRect queryBounds : {SkRect::MakeXYWH(53, 60, GrClip::kBoundsTolerance, 1000),
SkRect::MakeXYWH(53, 60, GrClip::kBoundsTolerance/2, 1000),
SkRect::MakeXYWH(53, 160, 1000, GrClip::kBoundsTolerance),
SkRect::MakeXYWH(53, 160, 1000, GrClip::kBoundsTolerance/2)}) {
- const GrReducedClip reduced(stack, queryBounds, caps);
+ const GrReducedClip reduced(stack, queryBounds, context.get());
REPORTER_ASSERT(reporter, !reduced.hasScissor());
REPORTER_ASSERT(reporter, reduced.maskElements().isEmpty());
REPORTER_ASSERT(reporter,