blob: e349f6337b0182234b27aef8edb911924b724301 [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
Robert Phillipse3302df2017-04-24 07:31:02 -040011#include "instanced/InstancedOp.h"
csmartdaltona7f29642016-07-07 08:49:11 -070012#include "instanced/InstancedRenderingTypes.h"
Robert Phillipse3302df2017-04-24 07:31:02 -040013
14#include "SkTInternalLList.h"
csmartdaltona7f29642016-07-07 08:49:11 -070015
Robert Phillips646e4292017-06-13 12:44:56 -040016class GrGpu;
csmartdaltona7f29642016-07-07 08:49:11 -070017class GrResourceProvider;
18
19namespace gr_instanced {
20
Robert Phillipse3302df2017-04-24 07:31:02 -040021class InstancedOp;
csmartdaltona7f29642016-07-07 08:49:11 -070022class InstanceProcessor;
23
Robert Phillipse3302df2017-04-24 07:31:02 -040024
csmartdaltona7f29642016-07-07 08:49:11 -070025/**
Robert Phillipse3302df2017-04-24 07:31:02 -040026 * Instanced Rendering occurs through the interaction of four class:
27 * InstancedOp
28 * OpAllocator
29 * InstancedRendering
30 * InstanceProcessor
csmartdaltona7f29642016-07-07 08:49:11 -070031 *
Robert Phillipse3302df2017-04-24 07:31:02 -040032 * The InstancedOp is a GrDrawOp but is more of a proxy than normal operations. It accumulates a
33 * LL of Draw objects that are allocated all together by the OpAllocator.
csmartdaltona7f29642016-07-07 08:49:11 -070034 *
Robert Phillipse3302df2017-04-24 07:31:02 -040035 * There is only one OpAllocator which encapsulates the creation of InstancedOps and the pool
36 * of memory used for their Draw objects.
37 *
38 * The InstancedRendering class tracks a list of InstancedOps that will all be drawn during
39 * the same flush. There is currently one per opList. The nature of instanced
40 * rendering allows these ops to combine well and render efficiently.
41 * During a flush, it assembles the accumulated draw data into a single vertex and texel
42 * buffer per opList, and its subclasses draw the ops using backend-specific instanced
43 * rendering APIs.
44 *
45 * InstanceProcessors implement the shaders required for instance rendering.
csmartdaltona7f29642016-07-07 08:49:11 -070046 */
47class InstancedRendering : public SkNoncopyable {
48public:
Robert Phillipsfbcef6e2017-06-15 12:07:18 -040049 virtual ~InstancedRendering();
csmartdaltona7f29642016-07-07 08:49:11 -070050
Hal Canary144caf52016-11-07 17:57:18 -050051 GrGpu* gpu() const { return fGpu.get(); }
csmartdaltona7f29642016-07-07 08:49:11 -070052
53 /**
csmartdaltona7f29642016-07-07 08:49:11 -070054 * Compiles all recorded draws into GPU buffers and allows the client to begin flushing the
Brian Salomon99ad1642016-12-16 09:50:45 -050055 * ops created by this class.
csmartdaltona7f29642016-07-07 08:49:11 -070056 */
57 void beginFlush(GrResourceProvider*);
58
Robert Phillipse3302df2017-04-24 07:31:02 -040059 void draw(const GrPipeline& pipeline, OpInfo info, const InstancedOp* baseOp);
60
csmartdaltona7f29642016-07-07 08:49:11 -070061 /**
Brian Salomon99ad1642016-12-16 09:50:45 -050062 * Called once the ops created previously by this class have all been released. Allows the
csmartdaltona7f29642016-07-07 08:49:11 -070063 * client to begin recording draws again.
64 */
65 void endFlush();
66
67 enum class ResetType : bool {
68 kDestroy,
69 kAbandon
70 };
71
72 /**
73 * Resets all GPU resources, including those that are held long term. They will be lazily
74 * reinitialized if the class begins to be used again.
75 */
76 void resetGpuResources(ResetType);
77
Robert Phillipse3302df2017-04-24 07:31:02 -040078 void addOp(InstancedOp* op) { fTrackedOps.addToTail(op); }
79 void removeOp(InstancedOp* op) { fTrackedOps.remove(op); }
80 int addOpParams(InstancedOp* op);
81
82#ifdef SK_DEBUG
83 bool isFlushing() const { return InstancedRendering::State::kFlushing == fState; }
84#endif
85
csmartdaltona7f29642016-07-07 08:49:11 -070086protected:
Robert Phillipse3302df2017-04-24 07:31:02 -040087 typedef SkTInternalLList<InstancedOp> OpList;
csmartdaltona7f29642016-07-07 08:49:11 -070088
csmartdaltone0d36292016-07-29 08:14:20 -070089 InstancedRendering(GrGpu* gpu);
csmartdaltona7f29642016-07-07 08:49:11 -070090
Brian Salomon99ad1642016-12-16 09:50:45 -050091 const OpList& trackedOps() const { return fTrackedOps; }
Hal Canary144caf52016-11-07 17:57:18 -050092 const GrBuffer* vertexBuffer() const { SkASSERT(fVertexBuffer); return fVertexBuffer.get(); }
93 const GrBuffer* indexBuffer() const { SkASSERT(fIndexBuffer); return fIndexBuffer.get(); }
csmartdaltona7f29642016-07-07 08:49:11 -070094
95 virtual void onBeginFlush(GrResourceProvider*) = 0;
Robert Phillipse3302df2017-04-24 07:31:02 -040096 virtual void onDraw(const GrPipeline&, const InstanceProcessor&, const InstancedOp*) = 0;
csmartdaltona7f29642016-07-07 08:49:11 -070097 virtual void onEndFlush() = 0;
98 virtual void onResetGpuResources(ResetType) = 0;
99
100private:
Robert Phillipse3302df2017-04-24 07:31:02 -0400101#ifdef SK_DEBUG
csmartdaltona7f29642016-07-07 08:49:11 -0700102 enum class State : bool {
103 kRecordingDraws,
104 kFlushing
105 };
Robert Phillipse3302df2017-04-24 07:31:02 -0400106#endif
csmartdaltona7f29642016-07-07 08:49:11 -0700107
Brian Salomon99ad1642016-12-16 09:50:45 -0500108 const sk_sp<GrGpu> fGpu;
Robert Phillipse3302df2017-04-24 07:31:02 -0400109 SkDEBUGCODE(State fState;)
Brian Salomon99ad1642016-12-16 09:50:45 -0500110 SkSTArray<1024, ParamsTexel, true> fParams;
111 OpList fTrackedOps;
112 sk_sp<const GrBuffer> fVertexBuffer;
113 sk_sp<const GrBuffer> fIndexBuffer;
114 sk_sp<GrBuffer> fParamsBuffer;
csmartdaltona7f29642016-07-07 08:49:11 -0700115};
116
117}
118
119#endif