blob: 778e8b4511c569d970c5d869baa2a4e550445f35 [file] [log] [blame]
csmartdaltona7f29642016-07-07 08:49:11 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef gr_instanced_InstancedRendering_DEFINED
9#define gr_instanced_InstancedRendering_DEFINED
10
Brian Salomon89527432016-12-16 09:52:16 -050011#include "../private/GrInstancedPipelineInfo.h"
Greg Daniel77b53f62016-10-18 11:48:51 -040012#include "GrGpu.h"
csmartdaltona7f29642016-07-07 08:49:11 -070013#include "GrMemoryPool.h"
14#include "SkTInternalLList.h"
csmartdaltona7f29642016-07-07 08:49:11 -070015#include "instanced/InstancedRenderingTypes.h"
Brian Salomon89527432016-12-16 09:52:16 -050016#include "ops/GrDrawOp.h"
csmartdaltona7f29642016-07-07 08:49:11 -070017
18class GrResourceProvider;
19
20namespace gr_instanced {
21
22class InstanceProcessor;
23
24/**
25 * This class serves as a centralized clearinghouse for instanced rendering. It accumulates data for
Brian Salomon89527432016-12-16 09:52:16 -050026 * instanced draws into one location, and creates special ops that pull from this data. The
27 * nature of instanced rendering allows these ops to combine well and render efficiently.
csmartdaltona7f29642016-07-07 08:49:11 -070028 *
29 * During a flush, this class assembles the accumulated draw data into a single vertex and texel
Brian Salomon99ad1642016-12-16 09:50:45 -050030 * buffer, and its subclass draws the ops using backend-specific instanced rendering APIs.
csmartdaltona7f29642016-07-07 08:49:11 -070031 *
32 * This class is responsible for the CPU side of instanced rendering. Shaders are implemented by
33 * InstanceProcessor.
34 */
35class InstancedRendering : public SkNoncopyable {
36public:
37 virtual ~InstancedRendering() { SkASSERT(State::kRecordingDraws == fState); }
38
Hal Canary144caf52016-11-07 17:57:18 -050039 GrGpu* gpu() const { return fGpu.get(); }
csmartdaltona7f29642016-07-07 08:49:11 -070040
41 /**
Brian Salomon99ad1642016-12-16 09:50:45 -050042 * These methods make a new record internally for an instanced draw, and return an op that is
43 * effectively just an index to that record. The returned op is not self-contained, but
csmartdaltona7f29642016-07-07 08:49:11 -070044 * rather relies on this class to handle the rendering. The client must call beginFlush() on
Brian Salomon99ad1642016-12-16 09:50:45 -050045 * this class before attempting to flush ops returned by it. It is invalid to record new
csmartdaltona7f29642016-07-07 08:49:11 -070046 * draws between beginFlush() and endFlush().
47 */
Brian Salomonf8334782017-01-03 09:42:58 -050048 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
49 GrColor, GrAA,
50 const GrInstancedPipelineInfo&,
51 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070052
Brian Salomonf8334782017-01-03 09:42:58 -050053 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
54 GrColor, const SkRect& localRect,
55 GrAA, const GrInstancedPipelineInfo&,
56 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070057
Brian Salomonf8334782017-01-03 09:42:58 -050058 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&,
59 GrColor, const SkMatrix& localMatrix,
60 GrAA, const GrInstancedPipelineInfo&,
61 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070062
Brian Salomonf8334782017-01-03 09:42:58 -050063 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&,
64 GrColor, GrAA,
65 const GrInstancedPipelineInfo&,
66 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070067
Brian Salomonf8334782017-01-03 09:42:58 -050068 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&,
69 GrColor, GrAA,
70 const GrInstancedPipelineInfo&,
71 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070072
Brian Salomonf8334782017-01-03 09:42:58 -050073 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer,
74 const SkRRect& inner,
75 const SkMatrix&, GrColor, GrAA,
76 const GrInstancedPipelineInfo&,
77 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -070078
79 /**
80 * Compiles all recorded draws into GPU buffers and allows the client to begin flushing the
Brian Salomon99ad1642016-12-16 09:50:45 -050081 * ops created by this class.
csmartdaltona7f29642016-07-07 08:49:11 -070082 */
83 void beginFlush(GrResourceProvider*);
84
85 /**
Brian Salomon99ad1642016-12-16 09:50:45 -050086 * Called once the ops created previously by this class have all been released. Allows the
csmartdaltona7f29642016-07-07 08:49:11 -070087 * client to begin recording draws again.
88 */
89 void endFlush();
90
91 enum class ResetType : bool {
92 kDestroy,
93 kAbandon
94 };
95
96 /**
97 * Resets all GPU resources, including those that are held long term. They will be lazily
98 * reinitialized if the class begins to be used again.
99 */
100 void resetGpuResources(ResetType);
101
102protected:
Brian Salomon99ad1642016-12-16 09:50:45 -0500103 class Op : public GrDrawOp {
csmartdaltona7f29642016-07-07 08:49:11 -0700104 public:
Brian Salomon99ad1642016-12-16 09:50:45 -0500105 SK_DECLARE_INTERNAL_LLIST_INTERFACE(Op);
csmartdaltona7f29642016-07-07 08:49:11 -0700106
Brian Salomon99ad1642016-12-16 09:50:45 -0500107 ~Op() override;
108 const char* name() const override { return "InstancedRendering::Op"; }
csmartdaltona7f29642016-07-07 08:49:11 -0700109
Brian Salomon7c3e7182016-12-01 09:35:30 -0500110 SkString dumpInfo() const override {
111 SkString string;
Brian Salomonaf9847e2017-03-01 11:28:27 -0500112 string.printf(
113 "AA: %d, ShapeTypes: 0x%02x, IShapeTypes: 0x%02x, Persp %d, "
114 "NonSquare: %d, PLoad: %0.2f, Tracked: %d, NumDraws: %d, "
115 "GeomChanges: %d\n",
116 (unsigned)fInfo.fAAType,
117 fInfo.fShapeTypes,
118 fInfo.fInnerShapeTypes,
119 fInfo.fHasPerspective,
120 fInfo.fNonSquare,
121 fPixelLoad,
122 fIsTracked,
123 fNumDraws,
124 fNumChangesInGeometry);
Brian Salomon7c3e7182016-12-01 09:35:30 -0500125 string.append(DumpPipelineInfo(*this->pipeline()));
126 string.append(INHERITED::dumpInfo());
127 return string;
128 }
129
csmartdaltona7f29642016-07-07 08:49:11 -0700130 struct Draw {
131 Instance fInstance;
132 IndexRange fGeometry;
133 Draw* fNext;
134 };
135
136 Draw& getSingleDraw() const { SkASSERT(fHeadDraw && !fHeadDraw->fNext); return *fHeadDraw; }
137 Instance& getSingleInstance() const { return this->getSingleDraw().fInstance; }
138
139 void appendRRectParams(const SkRRect&);
140 void appendParamsTexel(const SkScalar* vals, int count);
141 void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w);
142 void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z);
143
Brian Salomond543e0a2017-03-06 16:36:49 -0500144 // Registers the op with the InstancedRendering list of tracked ops.
145 void wasRecorded() override;
146
csmartdaltona7f29642016-07-07 08:49:11 -0700147 protected:
Brian Salomon99ad1642016-12-16 09:50:45 -0500148 Op(uint32_t classID, InstancedRendering* ir);
csmartdaltona7f29642016-07-07 08:49:11 -0700149
Brian Salomon99ad1642016-12-16 09:50:45 -0500150 InstancedRendering* const fInstancedRendering;
151 OpInfo fInfo;
152 SkScalar fPixelLoad;
153 SkSTArray<5, ParamsTexel, true> fParams;
154 bool fIsTracked;
155 int fNumDraws;
156 int fNumChangesInGeometry;
157 Draw* fHeadDraw;
158 Draw* fTailDraw;
csmartdaltona7f29642016-07-07 08:49:11 -0700159
Brian Salomon92aee3d2016-12-21 09:20:25 -0500160 private:
Brian Salomon5298dc82017-02-22 11:52:03 -0500161 void getFragmentProcessorAnalysisInputs(
162 FragmentProcessorAnalysisInputs* input) const override;
Brian Salomon92aee3d2016-12-21 09:20:25 -0500163 void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
164 bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
165 void onPrepare(GrOpFlushState*) override {}
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500166 void onExecute(GrOpFlushState*) override;
Brian Salomon92aee3d2016-12-21 09:20:25 -0500167
Brian Salomon9afd3712016-12-01 10:59:09 -0500168 typedef GrDrawOp INHERITED;
csmartdaltona7f29642016-07-07 08:49:11 -0700169
170 friend class InstancedRendering;
171 };
172
Brian Salomon99ad1642016-12-16 09:50:45 -0500173 typedef SkTInternalLList<Op> OpList;
csmartdaltona7f29642016-07-07 08:49:11 -0700174
csmartdaltone0d36292016-07-29 08:14:20 -0700175 InstancedRendering(GrGpu* gpu);
csmartdaltona7f29642016-07-07 08:49:11 -0700176
Brian Salomon99ad1642016-12-16 09:50:45 -0500177 const OpList& trackedOps() const { return fTrackedOps; }
Hal Canary144caf52016-11-07 17:57:18 -0500178 const GrBuffer* vertexBuffer() const { SkASSERT(fVertexBuffer); return fVertexBuffer.get(); }
179 const GrBuffer* indexBuffer() const { SkASSERT(fIndexBuffer); return fIndexBuffer.get(); }
csmartdaltona7f29642016-07-07 08:49:11 -0700180
181 virtual void onBeginFlush(GrResourceProvider*) = 0;
Brian Salomon99ad1642016-12-16 09:50:45 -0500182 virtual void onDraw(const GrPipeline&, const InstanceProcessor&, const Op*) = 0;
csmartdaltona7f29642016-07-07 08:49:11 -0700183 virtual void onEndFlush() = 0;
184 virtual void onResetGpuResources(ResetType) = 0;
185
186private:
187 enum class State : bool {
188 kRecordingDraws,
189 kFlushing
190 };
191
Brian Salomonf8334782017-01-03 09:42:58 -0500192 std::unique_ptr<Op> SK_WARN_UNUSED_RESULT recordShape(ShapeType, const SkRect& bounds,
193 const SkMatrix& viewMatrix, GrColor,
194 const SkRect& localRect, GrAA aa,
195 const GrInstancedPipelineInfo&,
196 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -0700197
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500198 bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&,
Brian Salomonaf9847e2017-03-01 11:28:27 -0500199 GrAAType*);
csmartdaltona7f29642016-07-07 08:49:11 -0700200
Brian Salomonf8334782017-01-03 09:42:58 -0500201 virtual std::unique_ptr<Op> makeOp() = 0;
csmartdaltona7f29642016-07-07 08:49:11 -0700202
Brian Salomon99ad1642016-12-16 09:50:45 -0500203 const sk_sp<GrGpu> fGpu;
204 State fState;
205 GrObjectMemoryPool<Op::Draw> fDrawPool;
206 SkSTArray<1024, ParamsTexel, true> fParams;
207 OpList fTrackedOps;
208 sk_sp<const GrBuffer> fVertexBuffer;
209 sk_sp<const GrBuffer> fIndexBuffer;
210 sk_sp<GrBuffer> fParamsBuffer;
csmartdaltona7f29642016-07-07 08:49:11 -0700211};
212
213}
214
215#endif