1 /* 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 11 #include "instanced/InstancedOp.h" 12 #include "instanced/InstancedRenderingTypes.h" 13 14 #include "SkTInternalLList.h" 15 16 class GrGpu; 17 class GrResourceProvider; 18 19 namespace gr_instanced { 20 21 class InstancedOp; 22 class InstanceProcessor; 23 24 25 /** 26 * Instanced Rendering occurs through the interaction of four class: 27 * InstancedOp 28 * OpAllocator 29 * InstancedRendering 30 * InstanceProcessor 31 * 32 * 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. 34 * 35 * 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. 46 */ 47 class InstancedRendering : public SkNoncopyable { 48 public: 49 virtual ~InstancedRendering(); 50 gpu()51 GrGpu* gpu() const { return fGpu.get(); } 52 53 /** 54 * Compiles all recorded draws into GPU buffers and allows the client to begin flushing the 55 * ops created by this class. 56 */ 57 void beginFlush(GrResourceProvider*); 58 59 void draw(const GrPipeline& pipeline, OpInfo info, const InstancedOp* baseOp); 60 61 /** 62 * Called once the ops created previously by this class have all been released. Allows the 63 * 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 addOp(InstancedOp * op)78 void addOp(InstancedOp* op) { fTrackedOps.addToTail(op); } removeOp(InstancedOp * op)79 void removeOp(InstancedOp* op) { fTrackedOps.remove(op); } 80 int addOpParams(InstancedOp* op); 81 82 #ifdef SK_DEBUG isFlushing()83 bool isFlushing() const { return InstancedRendering::State::kFlushing == fState; } 84 #endif 85 86 protected: 87 typedef SkTInternalLList<InstancedOp> OpList; 88 89 InstancedRendering(GrGpu* gpu); 90 trackedOps()91 const OpList& trackedOps() const { return fTrackedOps; } vertexBuffer()92 const GrBuffer* vertexBuffer() const { SkASSERT(fVertexBuffer); return fVertexBuffer.get(); } indexBuffer()93 const GrBuffer* indexBuffer() const { SkASSERT(fIndexBuffer); return fIndexBuffer.get(); } 94 95 virtual void onBeginFlush(GrResourceProvider*) = 0; 96 virtual void onDraw(const GrPipeline&, const InstanceProcessor&, const InstancedOp*) = 0; 97 virtual void onEndFlush() = 0; 98 virtual void onResetGpuResources(ResetType) = 0; 99 100 private: 101 #ifdef SK_DEBUG 102 enum class State : bool { 103 kRecordingDraws, 104 kFlushing 105 }; 106 #endif 107 108 const sk_sp<GrGpu> fGpu; 109 SkDEBUGCODE(State fState;) 110 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; 115 }; 116 117 } 118 119 #endif 120