1 /* 2 * Copyright 2015 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 GrDrawBatch_DEFINED 9 #define GrDrawBatch_DEFINED 10 11 #include <functional> 12 #include "GrBatch.h" 13 #include "GrPipeline.h" 14 15 struct GrInitInvariantOutput; 16 17 /** 18 * GrDrawBatches are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources 19 * and draws are determined and scheduled. They are issued in the draw phase. GrBatchToken is used 20 * to sequence the uploads relative to each other and to draws. 21 **/ 22 23 class GrBatchDrawToken { 24 public: AlreadyFlushedToken()25 static GrBatchDrawToken AlreadyFlushedToken() { return GrBatchDrawToken(0); } 26 GrBatchDrawToken(const GrBatchDrawToken & that)27 GrBatchDrawToken(const GrBatchDrawToken& that) : fSequenceNumber(that.fSequenceNumber) {} 28 GrBatchDrawToken& operator =(const GrBatchDrawToken& that) { 29 fSequenceNumber = that.fSequenceNumber; 30 return *this; 31 } 32 bool operator==(const GrBatchDrawToken& that) const { 33 return fSequenceNumber == that.fSequenceNumber; 34 } 35 bool operator!=(const GrBatchDrawToken& that) const { return !(*this == that); } 36 37 private: 38 GrBatchDrawToken(); GrBatchDrawToken(uint64_t sequenceNumber)39 explicit GrBatchDrawToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {} 40 friend class GrBatchFlushState; 41 uint64_t fSequenceNumber; 42 }; 43 44 /** 45 * Base class for GrBatches that draw. These batches have a GrPipeline installed by GrDrawTarget. 46 */ 47 class GrDrawBatch : public GrBatch { 48 public: 49 /** Method that performs an upload on behalf of a DeferredUploadFn. */ 50 using WritePixelsFn = std::function<bool(GrSurface* texture, 51 int left, int top, int width, int height, 52 GrPixelConfig config, const void* buffer, 53 size_t rowBytes)>; 54 /** See comments before GrDrawBatch::Target definition on how deferred uploaders work. */ 55 using DeferredUploadFn = std::function<void(WritePixelsFn&)>; 56 57 class Target; 58 59 GrDrawBatch(uint32_t classID); 60 ~GrDrawBatch() override; 61 62 /** 63 * Fills in a structure informing the XP of overrides to its normal behavior. 64 */ 65 void getPipelineOptimizations(GrPipelineOptimizations* override) const; 66 pipeline()67 const GrPipeline* pipeline() const { 68 SkASSERT(fPipelineInstalled); 69 return reinterpret_cast<const GrPipeline*>(fPipelineStorage.get()); 70 } 71 72 bool installPipeline(const GrPipeline::CreateArgs&); 73 74 // TODO no GrPrimitiveProcessors yet read fragment position willReadFragmentPosition()75 bool willReadFragmentPosition() const { return false; } 76 renderTargetUniqueID()77 uint32_t renderTargetUniqueID() const final { 78 SkASSERT(fPipelineInstalled); 79 return this->pipeline()->getRenderTarget()->uniqueID(); 80 } 81 renderTarget()82 GrRenderTarget* renderTarget() const final { 83 SkASSERT(fPipelineInstalled); 84 return this->pipeline()->getRenderTarget(); 85 } 86 dumpInfo()87 SkString dumpInfo() const override { 88 SkString string; 89 string.appendf("RT: %d\n", this->renderTargetUniqueID()); 90 string.append("ColorStages:\n"); 91 for (int i = 0; i < this->pipeline()->numColorFragmentProcessors(); i++) { 92 string.appendf("\t\t%s\n\t\t%s\n", 93 this->pipeline()->getColorFragmentProcessor(i).name(), 94 this->pipeline()->getColorFragmentProcessor(i).dumpInfo().c_str()); 95 } 96 string.append("CoverageStages:\n"); 97 for (int i = 0; i < this->pipeline()->numCoverageFragmentProcessors(); i++) { 98 string.appendf("\t\t%s\n\t\t%s\n", 99 this->pipeline()->getCoverageFragmentProcessor(i).name(), 100 this->pipeline()->getCoverageFragmentProcessor(i).dumpInfo().c_str()); 101 } 102 string.appendf("XP: %s\n", this->pipeline()->getXferProcessor().name()); 103 104 bool scissorEnabled = this->pipeline()->getScissorState().enabled(); 105 string.appendf("Scissor: "); 106 if (scissorEnabled) { 107 string.appendf("[L: %d, T: %d, R: %d, B: %d]\n", 108 this->pipeline()->getScissorState().rect().fLeft, 109 this->pipeline()->getScissorState().rect().fTop, 110 this->pipeline()->getScissorState().rect().fRight, 111 this->pipeline()->getScissorState().rect().fBottom); 112 } else { 113 string.appendf("<disabled>\n"); 114 } 115 string.append(INHERITED::dumpInfo()); 116 117 return string; 118 } 119 120 protected: 121 virtual void computePipelineOptimizations(GrInitInvariantOutput* color, 122 GrInitInvariantOutput* coverage, 123 GrBatchToXPOverrides* overrides) const = 0; 124 125 private: 126 /** 127 * initBatchTracker is a hook for the some additional overrides / optimization possibilities 128 * from the GrXferProcessor. 129 */ 130 virtual void initBatchTracker(const GrXPOverridesForBatch&) = 0; 131 132 protected: 133 struct QueuedUpload { QueuedUploadQueuedUpload134 QueuedUpload(DeferredUploadFn&& upload, GrBatchDrawToken token) 135 : fUpload(std::move(upload)) 136 , fUploadBeforeToken(token) {} 137 DeferredUploadFn fUpload; 138 GrBatchDrawToken fUploadBeforeToken; 139 }; 140 SkTArray<QueuedUpload> fInlineUploads; 141 142 private: 143 SkAlignedSTStorage<1, GrPipeline> fPipelineStorage; 144 bool fPipelineInstalled; 145 typedef GrBatch INHERITED; 146 }; 147 148 #endif 149