Make InstancedRendering more opList-splitting friendly
This CL splits the InstancedRendering class into an allocator and a per-opList op tracker. This was done because we need to allocate the InstancedRendering ops before we know the final destination opList. The InstancedRendering ops are now still all allocated from the same pool but the tracking and execution is done per opList.
Change-Id: Ieddabb6f85f8f187c5e7373f7f6cb155d69a9685
Reviewed-on: https://skia-review.googlesource.com/13860
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h
index a8b9530..3c5976d 100644
--- a/src/gpu/instanced/InstancedRendering.h
+++ b/src/gpu/instanced/InstancedRendering.h
@@ -8,29 +8,41 @@
#ifndef gr_instanced_InstancedRendering_DEFINED
#define gr_instanced_InstancedRendering_DEFINED
-#include "../private/GrInstancedPipelineInfo.h"
#include "GrGpu.h"
-#include "GrMemoryPool.h"
-#include "SkTInternalLList.h"
+#include "instanced/InstancedOp.h"
#include "instanced/InstancedRenderingTypes.h"
-#include "ops/GrDrawOp.h"
+
+#include "SkTInternalLList.h"
class GrResourceProvider;
namespace gr_instanced {
+class InstancedOp;
class InstanceProcessor;
+
/**
- * This class serves as a centralized clearinghouse for instanced rendering. It accumulates data for
- * instanced draws into one location, and creates special ops that pull from this data. The
- * nature of instanced rendering allows these ops to combine well and render efficiently.
+ * Instanced Rendering occurs through the interaction of four class:
+ * InstancedOp
+ * OpAllocator
+ * InstancedRendering
+ * InstanceProcessor
*
- * During a flush, this class assembles the accumulated draw data into a single vertex and texel
- * buffer, and its subclass draws the ops using backend-specific instanced rendering APIs.
+ * The InstancedOp is a GrDrawOp but is more of a proxy than normal operations. It accumulates a
+ * LL of Draw objects that are allocated all together by the OpAllocator.
*
- * This class is responsible for the CPU side of instanced rendering. Shaders are implemented by
- * InstanceProcessor.
+ * There is only one OpAllocator which encapsulates the creation of InstancedOps and the pool
+ * of memory used for their Draw objects.
+ *
+ * The InstancedRendering class tracks a list of InstancedOps that will all be drawn during
+ * the same flush. There is currently one per opList. The nature of instanced
+ * rendering allows these ops to combine well and render efficiently.
+ * During a flush, it assembles the accumulated draw data into a single vertex and texel
+ * buffer per opList, and its subclasses draw the ops using backend-specific instanced
+ * rendering APIs.
+ *
+ * InstanceProcessors implement the shaders required for instance rendering.
*/
class InstancedRendering : public SkNoncopyable {
public:
@@ -39,45 +51,13 @@
GrGpu* gpu() const { return fGpu.get(); }
/**
- * These methods make a new record internally for an instanced draw, and return an op that is
- * effectively just an index to that record. The returned op is not self-contained, but
- * rather relies on this class to handle the rendering. The client must call beginFlush() on
- * this class before attempting to flush ops returned by it. It is invalid to record new
- * draws between beginFlush() and endFlush().
- */
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrPaint&&, GrAA,
- const GrInstancedPipelineInfo&);
-
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrPaint&&, const SkRect& localRect,
- GrAA,
- const GrInstancedPipelineInfo&);
-
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
- GrPaint&&,
- const SkMatrix& localMatrix, GrAA,
- const GrInstancedPipelineInfo&);
-
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&,
- GrPaint&&, GrAA,
- const GrInstancedPipelineInfo&);
-
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&,
- GrPaint&&, GrAA,
- const GrInstancedPipelineInfo&);
-
- std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer,
- const SkRRect& inner,
- const SkMatrix&, GrPaint&&, GrAA,
- const GrInstancedPipelineInfo&);
-
- /**
* Compiles all recorded draws into GPU buffers and allows the client to begin flushing the
* ops created by this class.
*/
void beginFlush(GrResourceProvider*);
+ void draw(const GrPipeline& pipeline, OpInfo info, const InstancedOp* baseOp);
+
/**
* Called once the ops created previously by this class have all been released. Allows the
* client to begin recording draws again.
@@ -95,81 +75,16 @@
*/
void resetGpuResources(ResetType);
+ void addOp(InstancedOp* op) { fTrackedOps.addToTail(op); }
+ void removeOp(InstancedOp* op) { fTrackedOps.remove(op); }
+ int addOpParams(InstancedOp* op);
+
+#ifdef SK_DEBUG
+ bool isFlushing() const { return InstancedRendering::State::kFlushing == fState; }
+#endif
+
protected:
- class Op : public GrDrawOp {
- public:
- SK_DECLARE_INTERNAL_LLIST_INTERFACE(Op);
-
- ~Op() override;
- const char* name() const override { return "InstancedRendering::Op"; }
-
- SkString dumpInfo() const override {
- SkString string;
- string.printf(
- "AA: %d, ShapeTypes: 0x%02x, IShapeTypes: 0x%02x, Persp %d, "
- "NonSquare: %d, PLoad: %0.2f, Tracked: %d, NumDraws: %d, "
- "GeomChanges: %d\n",
- (unsigned)fInfo.fAAType,
- fInfo.fShapeTypes,
- fInfo.fInnerShapeTypes,
- fInfo.fHasPerspective,
- fInfo.fNonSquare,
- fPixelLoad,
- fIsTracked,
- fNumDraws,
- fNumChangesInGeometry);
- string.append(INHERITED::dumpInfo());
- return string;
- }
-
- struct Draw {
- Instance fInstance;
- IndexRange fGeometry;
- Draw* fNext;
- };
-
- Draw& getSingleDraw() const { SkASSERT(fHeadDraw && !fHeadDraw->fNext); return *fHeadDraw; }
- Instance& getSingleInstance() const { return this->getSingleDraw().fInstance; }
-
- void appendRRectParams(const SkRRect&);
- void appendParamsTexel(const SkScalar* vals, int count);
- void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w);
- void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z);
- FixedFunctionFlags fixedFunctionFlags() const override {
- return GrAATypeIsHW(fInfo.aaType()) ? FixedFunctionFlags::kUsesHWAA
- : FixedFunctionFlags::kNone;
- }
- bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override;
-
- // Registers the op with the InstancedRendering list of tracked ops.
- void wasRecorded() override;
-
- protected:
- Op(uint32_t classID, GrPaint&&, InstancedRendering*);
-
- InstancedRendering* const fInstancedRendering;
- OpInfo fInfo;
- SkScalar fPixelLoad;
- GrProcessorSet fProcessors;
- SkSTArray<5, ParamsTexel, true> fParams;
- bool fIsTracked : 1;
- bool fRequiresBarrierOnOverlap : 1;
- int fNumDraws;
- int fNumChangesInGeometry;
- Draw* fHeadDraw;
- Draw* fTailDraw;
-
- private:
- bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
- void onPrepare(GrOpFlushState*) override {}
- void onExecute(GrOpFlushState*) override;
-
- typedef GrDrawOp INHERITED;
-
- friend class InstancedRendering;
- };
-
- typedef SkTInternalLList<Op> OpList;
+ typedef SkTInternalLList<InstancedOp> OpList;
InstancedRendering(GrGpu* gpu);
@@ -178,29 +93,20 @@
const GrBuffer* indexBuffer() const { SkASSERT(fIndexBuffer); return fIndexBuffer.get(); }
virtual void onBeginFlush(GrResourceProvider*) = 0;
- virtual void onDraw(const GrPipeline&, const InstanceProcessor&, const Op*) = 0;
+ virtual void onDraw(const GrPipeline&, const InstanceProcessor&, const InstancedOp*) = 0;
virtual void onEndFlush() = 0;
virtual void onResetGpuResources(ResetType) = 0;
private:
+#ifdef SK_DEBUG
enum class State : bool {
kRecordingDraws,
kFlushing
};
-
- std::unique_ptr<Op> SK_WARN_UNUSED_RESULT recordShape(ShapeType, const SkRect& bounds,
- const SkMatrix& viewMatrix, GrPaint&&,
- const SkRect& localRect, GrAA aa,
- const GrInstancedPipelineInfo&);
-
- bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&,
- GrAAType*);
-
- virtual std::unique_ptr<Op> makeOp(GrPaint&&) = 0;
+#endif
const sk_sp<GrGpu> fGpu;
- State fState;
- GrObjectMemoryPool<Op::Draw> fDrawPool;
+ SkDEBUGCODE(State fState;)
SkSTArray<1024, ParamsTexel, true> fParams;
OpList fTrackedOps;
sk_sp<const GrBuffer> fVertexBuffer;