Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Unified Diff: src/gpu/GrInstancedRendering.h

Issue 1897203002: Implement instanced rendering for simple shapes (Closed) Base URL: https://skia.googlesource.com/skia.git@upload2_requireHWAA
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrInstancedRendering.h
diff --git a/src/gpu/GrInstancedRendering.h b/src/gpu/GrInstancedRendering.h
new file mode 100644
index 0000000000000000000000000000000000000000..d016f0f0787f4d25c7e9fb379b34d3cfadbae5c1
--- /dev/null
+++ b/src/gpu/GrInstancedRendering.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrInstancedRendering_DEFINED
+#define GrInstancedRendering_DEFINED
+
+#include "GrAllocator.h"
+#include "GrInstancedRenderingTypes.h"
+#include "batches/GrDrawBatch.h"
+
+class GrInstanceProcessor;
+class GrResourceProvider;
+
+/**
+ * This class serves as a centralized clearinghouse for instanced rendering. It accumulates data for
+ * instanced draws into one location, and creates special batches that pull from this data. The
+ * nature of instanced rendering allows these batches to combine well and render efficiently.
+ *
+ * During a flush, this class assembles the accumulated draw data into a single vertex and texel
+ * buffer, and its subclass draws the batches using backend-specific instanced rendering APIs.
+ *
+ * This class is responsible for the CPU side of instanced rendering. Shaders are implemented by
+ * GrInstanceProcessor.
+ */
+class GrInstancedRendering : public SkNoncopyable, protected GrInstancedRenderingTypes {
+public:
+ virtual ~GrInstancedRendering() { SkASSERT(State::kRecordingShapes == fState); }
+
+ GrGpu* gpu() const { return fGpu; }
+
+ enum Flags {
+ kStencilWrite_Flag = (1 << 0),
+ kStencilBufferMSAA_Flag = (1 << 1),
+ kColorWrite_Flag = (1 << 2),
+ kColorBufferMSAA_Flag = (1 << 3),
+ /**
+ * This should not be set if the fragment shader uses derivatives, automatic mipmap LOD, or
+ * other features that depend on neighboring pixels.
+ */
+ kCanDiscardFragments_Flag = (1 << 4)
+ };
+
+ /**
+ * These methods record a new instanced draw and return a batch that can render it. The client
+ * must call commitToGpu() before attempting to draw batches returned by this class. After
+ * commitToGpu(), it becomes invalid to record new draws until a subsequent call to restart().
+ *
+ * The caller is responsible to enable HW antialias in the GrPipelineBuilder if (and only if)
+ * the value of "antialias" is true and the draw is fully multisampled (e.g. stencil-only draw
+ * to a multisampled stencil buffer, stencil + color draw when both buffers are multisampled),
+ * or if the value of "requireHWAA" gets overwritten with true. requireHWAA will be left
+ * unchanged unless the batch requires HW antialias under different circumstances than those
+ * listed above (e.g. mixed samples).
+ */
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
+ bool antialias, uint32_t flags,
+ bool* requireHWAA = nullptr);
+
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
+ const SkRect& localRect, bool antialias,
+ uint32_t flags, bool* requireHWAA = nullptr);
+
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
+ const SkMatrix& localMatrix, bool antialias,
+ uint32_t flags, bool* requireHWAA = nullptr);
+
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&, GrColor,
+ bool antialias, uint32_t flags,
+ bool* requireHWAA = nullptr);
+
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&, GrColor,
+ bool antialias, uint32_t flags,
+ bool* requireHWAA = nullptr);
+
+ GrDrawBatch* SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer, const SkRRect& inner,
+ const SkMatrix&, GrColor, bool antialias,
+ uint32_t flags, bool* requireHWAA = nullptr);
+
+ /**
+ * Commits all recorded draws to GPU memory and allows the client to begin drawing the batches
+ * created by this class.
+ */
+ void commitToGpu(GrResourceProvider*);
+
+ /**
+ * Called once the batches created previously by this class have all been released. Allows the
+ * client to begin recording draws again.
+ */
+ void restart();
+
+ enum class ClearType {
+ kDestroy,
+ kAbandon
+ };
+
+ /**
+ * Clears all GPU resources, including those that are held long term. They will be lazily
+ * reinitialized if the class begins to be used again.
+ */
+ void clearGpuResources(ClearType);
+
+protected:
+ class Batch : public GrDrawBatch {
+ public:
+ virtual ~Batch() { fInUse = false; } // fInUse will continue to be accessed.
+
+ const char* name() const override { return "Instanced Batch"; }
+
+ void computePipelineOptimizations(GrInitInvariantOutput* color,
+ GrInitInvariantOutput* coverage,
+ GrBatchToXPOverrides*) const override;
+
+ protected:
+ Batch(uint32_t classID, GrInstancedRendering* instRendering, AntialiasMode aa,
+ uint32_t flags, int instanceIdx)
+ : INHERITED(classID),
+ fInstancedRendering(instRendering),
+ fAntialiasMode(aa),
+ fFlags(flags),
+ fFirstInstanceIdx(instanceIdx),
+ fInUse(true) {
+#ifdef SK_DEBUG
+ fIsCombined = false;
+#endif
+ }
+
+ void initBatchTracker(const GrXPOverridesForBatch&) override;
+
+ void onPrepare(GrBatchFlushState*) override {}
+ void onDraw(GrBatchFlushState*) override;
+ void onDelete() const override;
+
+ GrInstancedRendering* const fInstancedRendering;
+ const AntialiasMode fAntialiasMode;
+ const uint32_t fFlags;
+ const int fFirstInstanceIdx;
+ BatchTracker fTracker;
+ bool fInUse;
+#ifdef SK_DEBUG
+ bool fIsCombined;
+#endif
+
+ typedef GrDrawBatch INHERITED;
+
+ friend class GrInstancedRendering;
+ };
+
+ class BatchAllocator : public GrAllocator {
+ public:
+ BatchAllocator(size_t sizeofBatchClass)
+ : INHERITED(sizeofBatchClass, kBatchesPerBlock, nullptr) {
+ fFirstBlock = sk_malloc_throw(kBatchesPerBlock * sizeofBatchClass);
+ this->setInitialBlock(fFirstBlock);
+ }
+
+ ~BatchAllocator() {
+ sk_free(fFirstBlock);
+ }
+
+ private:
+ enum { kBatchesPerBlock = 128 };
+
+ void* fFirstBlock;
+
+ typedef GrAllocator INHERITED;
+ };
+
+ GrInstancedRendering(GrGpu* gpu, uint32_t supportedAAModes, size_t sizeofBatchClass);
+
+ const GrBuffer* vertexBuffer() const { SkASSERT(fVertexBuffer); return fVertexBuffer; }
+ const GrBuffer* indexBuffer() const { SkASSERT(fIndexBuffer); return fIndexBuffer; }
+ const GrBuffer* instanceBuffer() const { SkASSERT(fInstanceBuffer); return fInstanceBuffer; }
+ const BatchAllocator* batchAllocator() const { return &fBatchAllocator; }
+
+ virtual void onCommitToGpu(GrResourceProvider*) = 0;
+ virtual void onDraw(const GrPipeline&, const GrInstanceProcessor&, const Batch*) = 0;
+ virtual void onRestart() = 0;
+ virtual void onClearGpuResources(ClearType) = 0;
+
+#ifdef SK_DEBUG
+ int fInUseBatchCount;
+#endif
+
+private:
+ enum class State {
+ kRecordingShapes,
+ kDrawingBatches
+ };
+
+ Batch* SK_WARN_UNUSED_RESULT recordShape(ShapeType, const SkRect& bounds,
+ const SkMatrix& viewMatrix, GrColor,
+ const SkRect& localRect, bool antialias,
+ uint32_t flags, bool* requireHWAA);
+
+ bool selectAntialiasMode(const SkMatrix& viewMatrix, bool antialias, uint32_t flags,
+ AntialiasMode*, bool* requireHWAA);
+
+ void appendRRectParams(const SkRRect&, BatchTracker*);
+ void appendParamsTexel(const SkScalar* vals, int count);
+ void appendParamsTexel(float x, float y, float z, float w);
+ void appendParamsTexel(float x, float y, float z);
+
+ virtual Batch* constructBatch(void* storage, AntialiasMode, uint32_t flags,
+ int instanceIdx) = 0;
+
+ const SkAutoTUnref<GrGpu> fGpu;
+ const uint32_t fSupportedAAModes;
+ State fState;
+ SkSTArray<1024, Instance, true> fInstances;
+ SkSTArray<1024, ParamsTexel, true> fParams;
+ BatchAllocator fBatchAllocator;
+ SkAutoTUnref<const GrBuffer> fVertexBuffer;
+ SkAutoTUnref<const GrBuffer> fIndexBuffer;
+ SkAutoTUnref<const GrBuffer> fInstanceBuffer;
+ SkAutoTUnref<GrBuffer> fParamsBuffer;
+};
+
+#endif

Powered by Google App Engine
This is Rietveld 408576698