Lift the tessellation atlas into its own path renderer
Creates a new path renderer, GrAtlasPathRenderer, that handles all the
atlasing. Managing the atlas in its own path renderer gives us more
control over when atlasing happens in the chain, will allow us to more
easily use the atlas in kCoverage mode, and makes the clipping code
cleaner.
Bug: skia:12258
Change-Id: Ie0b669974936c23895c8ab794e2d97206ed140f8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/431896
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/ops/GrDrawAtlasPathOp.h b/src/gpu/ops/GrDrawAtlasPathOp.h
new file mode 100644
index 0000000..1e79ec9
--- /dev/null
+++ b/src/gpu/ops/GrDrawAtlasPathOp.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrDrawAtlasPathOp_DEFINED
+#define GrDrawAtlasPathOp_DEFINED
+
+#include "src/core/SkIPoint16.h"
+#include "src/gpu/ops/GrAtlasInstancedHelper.h"
+#include "src/gpu/ops/GrDrawOp.h"
+
+// Fills a rectangle of pixels with a clip against coverage values from an atlas.
+class GrDrawAtlasPathOp : public GrDrawOp {
+public:
+ DEFINE_OP_CLASS_ID
+
+ GrDrawAtlasPathOp(SkArenaAlloc* arena, const SkIRect& fillBounds, const SkMatrix& localToDevice,
+ GrPaint&& paint, SkIPoint16 locationInAtlas, const SkIRect& pathDevIBounds,
+ bool transposedInAtlas, GrSurfaceProxyView atlasView, bool isInverseFill)
+ : GrDrawOp(ClassID())
+ , fHeadInstance(arena->make<Instance>(fillBounds, localToDevice, paint.getColor4f(),
+ locationInAtlas, pathDevIBounds,
+ transposedInAtlas))
+ , fTailInstance(&fHeadInstance->fNext)
+ , fAtlasHelper(std::move(atlasView),
+ isInverseFill ? GrAtlasInstancedHelper::ShaderFlags::kCheckBounds |
+ GrAtlasInstancedHelper::ShaderFlags::kInvertCoverage
+ : GrAtlasInstancedHelper::ShaderFlags::kNone)
+ , fProcessors(std::move(paint)) {
+ this->setBounds(SkRect::Make(fillBounds), HasAABloat::kYes, IsHairline::kNo);
+ }
+
+ const char* name() const override { return "GrDrawAtlasPathOp"; }
+ FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
+ void visitProxies(const GrVisitProxyFunc& func) const override {
+ func(fAtlasHelper.proxy(), GrMipmapped::kNo);
+ fProcessors.visitProxies(func);
+ }
+ GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
+ CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
+
+ void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView& writeView, GrAppliedClip*,
+ const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
+ void onPrepare(GrOpFlushState*) override;
+ void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
+
+private:
+ void prepareProgram(const GrCaps&, SkArenaAlloc*, const GrSurfaceProxyView& writeView,
+ bool usesMSAASurface, GrAppliedClip&&, const GrDstProxyView&,
+ GrXferBarrierFlags, GrLoadOp colorLoadOp);
+
+ struct Instance {
+ Instance(const SkIRect& fillIBounds, const SkMatrix& m,
+ const SkPMColor4f& color, SkIPoint16 locationInAtlas,
+ const SkIRect& pathDevIBounds, bool transposedInAtlas)
+ : fFillBounds(fillIBounds)
+ , fLocalToDeviceIfUsingLocalCoords{m.getScaleX(), m.getSkewY(),
+ m.getSkewX(), m.getScaleY(),
+ m.getTranslateX(), m.getTranslateY()}
+ , fColor(color)
+ , fAtlasInstance(locationInAtlas, pathDevIBounds, transposedInAtlas) {
+ }
+ SkIRect fFillBounds;
+ std::array<float, 6> fLocalToDeviceIfUsingLocalCoords;
+ SkPMColor4f fColor;
+ GrAtlasInstancedHelper::Instance fAtlasInstance;
+ Instance* fNext = nullptr;
+ };
+
+ Instance* fHeadInstance;
+ Instance** fTailInstance;
+
+ GrAtlasInstancedHelper fAtlasHelper;
+ bool fUsesLocalCoords = false;
+
+ int fInstanceCount = 1;
+
+ GrProgramInfo* fProgram = nullptr;
+
+ sk_sp<const GrBuffer> fInstanceBuffer;
+ int fBaseInstance;
+
+ // Only used if sk_VertexID is not supported.
+ sk_sp<const GrGpuBuffer> fVertexBufferIfNoIDSupport;
+
+ GrProcessorSet fProcessors;
+};
+
+#endif