aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCPRCoverageOp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/ccpr/GrCCPRCoverageOp.h')
-rw-r--r--src/gpu/ccpr/GrCCPRCoverageOp.h170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.h b/src/gpu/ccpr/GrCCPRCoverageOp.h
new file mode 100644
index 0000000000..77013dd0f7
--- /dev/null
+++ b/src/gpu/ccpr/GrCCPRCoverageOp.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrCCPRCoverageOp_DEFINED
+#define GrCCPRCoverageOp_DEFINED
+
+#include "GrMesh.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "ccpr/GrCCPRCoverageProcessor.h"
+#include "ccpr/GrCCPRGeometry.h"
+#include "ops/GrDrawOp.h"
+
+class GrCCPRCoverageOp;
+class GrOnFlushResourceProvider;
+class SkMatrix;
+class SkPath;
+
+/**
+ * This class produces GrCCPRCoverageOps that render coverage count masks and atlases. A path is
+ * added to the current op in two steps:
+ *
+ * 1) parsePath(ScissorMode, viewMatrix, path, &devBounds, &devBounds45);
+ *
+ * <client decides where to put the mask within an atlas, if wanted>
+ *
+ * 2) saveParsedPath(offsetX, offsetY, clipBounds);
+ *
+ * The client can flush the currently saved paths to a GrCCPRCoverageOp by calling emitOp, and
+ * retrieve all emitted ops after calling finalize().
+ */
+class GrCCPRCoverageOpsBuilder {
+public:
+ // Indicates whether a path should enforce a scissor clip when rendering its mask. (Specified
+ // as an int because these values get used directly as indices into arrays.)
+ enum class ScissorMode : int {
+ kNonScissored = 0,
+ kScissored = 1
+ };
+ static constexpr int kNumScissorModes = 2;
+
+ GrCCPRCoverageOpsBuilder(int maxTotalPaths, int numSkPoints, int numSkVerbs)
+ : fPathsInfo(maxTotalPaths)
+ , fGeometry(numSkPoints, numSkVerbs)
+ , fTallies{PrimitiveTallies(), PrimitiveTallies()}
+ , fScissorBatches(maxTotalPaths) {}
+
+ ~GrCCPRCoverageOpsBuilder() {
+ // Enforce the contract that the client always calls saveParsedPath or discardParsedPath.
+ SkASSERT(!fParsingPath);
+ }
+
+ // Parses an SkPath into a temporary staging area. The path will not yet be included in the next
+ // Op unless there is a matching call to saveParsedPath. The user must complement this with a
+ // following call to either saveParsedPath or discardParsedPath.
+ //
+ // Returns two tight bounding boxes: device space and "45 degree" (| 1 -1 | * devCoords) space.
+ // | 1 1 |
+ void parsePath(const SkMatrix&, const SkPath&, SkRect* devBounds, SkRect* devBounds45);
+
+ // Commits the currently-parsed path from staging to the next Op, and specifies whether the mask
+ // should be rendered with a scissor clip in effect. Accepts an optional post-device-space
+ // translate for placement in an atlas.
+ void saveParsedPath(ScissorMode, const SkIRect& clippedDevIBounds,
+ int16_t atlasOffsetX, int16_t atlasOffsetY);
+ void discardParsedPath();
+
+ // Flushes all currently-saved paths internally to a GrCCPRCoverageOp.
+ //
+ // NOTE: if there is a parsed path in the staging area, it will not be included. But the client
+ // may still call saveParsedPath to include it in a future Op.
+ void emitOp(SkISize drawBounds);
+
+ // Builds GPU buffers and returns the list of GrCCPRCoverageOps as specified by calls to emitOp.
+ bool finalize(GrOnFlushResourceProvider*, SkTArray<std::unique_ptr<GrCCPRCoverageOp>>*);
+
+private:
+ using PrimitiveTallies = GrCCPRGeometry::PrimitiveTallies;
+
+ // Every kBeginPath verb has a corresponding PathInfo entry.
+ struct PathInfo {
+ ScissorMode fScissorMode;
+ int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff)
+ std::unique_ptr<GrCCPRCoverageOp> fTerminatingOp;
+ };
+
+ // Every PathInfo with a mode of kScissored has a corresponding ScissorBatch.
+ struct ScissorBatch {
+ PrimitiveTallies fInstanceCounts;
+ SkIRect fScissor;
+ };
+
+ void endContourIfNeeded(bool insideContour);
+
+ // Staging area for the path being parsed.
+ SkDEBUGCODE(int fParsingPath = false);
+ int fCurrPathPointsIdx;
+ int fCurrPathVerbsIdx;
+ PrimitiveTallies fCurrPathTallies;
+
+ SkSTArray<32, PathInfo, true> fPathsInfo;
+
+ GrCCPRGeometry fGeometry;
+
+ PrimitiveTallies fTallies[kNumScissorModes];
+ SkTArray<ScissorBatch, true> fScissorBatches;
+
+ std::unique_ptr<GrCCPRCoverageOp> fTerminatingOp;
+
+ friend class GrCCPRCoverageOp; // For ScissorBatch.
+};
+
+/**
+ * This Op renders coverage count masks and atlases. Create it using GrCCPRCoverageOpsBuilder.
+ */
+class GrCCPRCoverageOp : public GrDrawOp {
+public:
+ DEFINE_OP_CLASS_ID
+
+ // GrDrawOp interface.
+ const char* name() const override { return "GrCCPRCoverageOp"; }
+ FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
+ RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override {
+ return RequiresDstTexture::kNo;
+ }
+ bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
+ void onPrepare(GrOpFlushState*) override {}
+ void onExecute(GrOpFlushState*) override;
+
+private:
+ static constexpr int kNumScissorModes = GrCCPRCoverageOpsBuilder::kNumScissorModes;
+ using PrimitiveTallies = GrCCPRGeometry::PrimitiveTallies;
+ using ScissorBatch = GrCCPRCoverageOpsBuilder::ScissorBatch;
+
+ GrCCPRCoverageOp(SkTArray<ScissorBatch, true>&& scissorBatches, const SkISize& drawBounds)
+ : INHERITED(ClassID())
+ , fScissorBatches(std::move(scissorBatches))
+ , fDrawBounds(drawBounds) {
+ this->setBounds(SkRect::MakeIWH(fDrawBounds.width(), fDrawBounds.height()),
+ GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
+ }
+
+ void setBuffers(sk_sp<GrBuffer> pointsBuffer, sk_sp<GrBuffer> instanceBuffer,
+ const PrimitiveTallies baseInstances[kNumScissorModes],
+ const PrimitiveTallies endInstances[kNumScissorModes]);
+
+ void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, const GrCCPRCoverageProcessor::Mode,
+ GrPrimitiveType, int vertexCount,
+ int PrimitiveTallies::* instanceType) const;
+
+ sk_sp<GrBuffer> fPointsBuffer;
+ sk_sp<GrBuffer> fInstanceBuffer;
+ PrimitiveTallies fBaseInstances[kNumScissorModes];
+ PrimitiveTallies fInstanceCounts[kNumScissorModes];
+ const SkTArray<ScissorBatch, true> fScissorBatches;
+ const SkISize fDrawBounds;
+
+ mutable SkTArray<GrMesh> fMeshesScratchBuffer;
+ mutable SkTArray<GrPipeline::DynamicState> fDynamicStatesScratchBuffer;
+
+ friend class GrCCPRCoverageOpsBuilder;
+
+ typedef GrDrawOp INHERITED;
+};
+
+#endif