blob: 9bd6b9409c41c2355e4246e42527e80b5fe1c053 [file] [log] [blame]
joshualitt4d8da812015-01-28 12:53:54 -08001/*
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 GrBatchBuffer_DEFINED
9#define GrBatchBuffer_DEFINED
10
joshualitt5bf99f12015-03-13 11:47:42 -070011#include "GrBatchAtlas.h"
joshualitt6065b882015-02-24 13:20:59 -080012#include "GrBufferAllocPool.h"
joshualitt4d8da812015-01-28 12:53:54 -080013#include "GrPendingProgramElement.h"
joshualitt7bc18b72015-02-03 16:41:41 -080014#include "GrPipeline.h"
joshualitt4d8da812015-01-28 12:53:54 -080015#include "GrGpu.h"
16#include "GrTRecorder.h"
17
18/*
19 * GrBatch instances use this object to allocate space for their geometry and to issue the draws
20 * that render their batch.
21 */
22
joshualitt7bc18b72015-02-03 16:41:41 -080023class GrIndexBufferAllocPool;
24class GrVertexBufferAllocPool;
25
joshualitt4d8da812015-01-28 12:53:54 -080026class GrBatchTarget : public SkNoncopyable {
27public:
joshualitt5bf99f12015-03-13 11:47:42 -070028 typedef GrBatchAtlas::BatchToken BatchToken;
joshualitt4d8da812015-01-28 12:53:54 -080029 GrBatchTarget(GrGpu* gpu,
30 GrVertexBufferAllocPool* vpool,
joshualitt5bf99f12015-03-13 11:47:42 -070031 GrIndexBufferAllocPool* ipool);
joshualitt4d8da812015-01-28 12:53:54 -080032
33 typedef GrDrawTarget::DrawInfo DrawInfo;
34 void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
35 GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
joshualitt7bc18b72015-02-03 16:41:41 -080036 fNumberOfDraws++;
joshualitt5bf99f12015-03-13 11:47:42 -070037 fCurrentToken++;
38 }
39
40 class TextureUploader {
41 public:
42 TextureUploader(GrGpu* gpu) : fGpu(gpu) { SkASSERT(gpu); }
43
44 /**
45 * Updates the pixels in a rectangle of a texture.
46 *
47 * @param left left edge of the rectangle to write (inclusive)
48 * @param top top edge of the rectangle to write (inclusive)
49 * @param width width of rectangle to write in pixels.
50 * @param height height of rectangle to write in pixels.
51 * @param config the pixel config of the source buffer
52 * @param buffer memory to read pixels from
53 * @param rowBytes number of bytes between consecutive rows. Zero
54 * means rows are tightly packed.
55 */
56 bool writeTexturePixels(GrTexture* texture,
57 int left, int top, int width, int height,
58 GrPixelConfig config, const void* buffer,
59 size_t rowBytes) {
60 return fGpu->writeTexturePixels(texture, left, top, width, height, config, buffer,
61 rowBytes);
62 }
63
64 private:
65 GrGpu* fGpu;
66 };
67
68 class Uploader : public SkRefCnt {
69 public:
70 Uploader(BatchToken lastUploadToken) : fLastUploadToken(lastUploadToken) {}
71 BatchToken lastUploadToken() const { return fLastUploadToken; }
72 virtual void upload(TextureUploader)=0;
73
74 private:
75 BatchToken fLastUploadToken;
76 };
77
78 void upload(Uploader* upload) {
79 if (this->asapToken() == upload->lastUploadToken()) {
80 fAsapUploads.push_back().reset(SkRef(upload));
81 } else {
82 fInlineUploads.push_back().reset(SkRef(upload));
83 }
joshualitt4d8da812015-01-28 12:53:54 -080084 }
85
86 void draw(const GrDrawTarget::DrawInfo& draw) {
87 fFlushBuffer.back().fDraws.push_back(draw);
88 }
89
joshualitt5bf99f12015-03-13 11:47:42 -070090 bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; }
91 BatchToken currentToken() const { return fCurrentToken; }
92 BatchToken asapToken() const { return fLastFlushedToken + 1; }
93
94 // TODO much of this complexity goes away when batch is everywhere
joshualitt7bc18b72015-02-03 16:41:41 -080095 void resetNumberOfDraws() { fNumberOfDraws = 0; }
96 int numberOfDraws() const { return fNumberOfDraws; }
joshualitt5bf99f12015-03-13 11:47:42 -070097 void preFlush() {
98 int updateCount = fAsapUploads.count();
99 for (int i = 0; i < updateCount; i++) {
100 fAsapUploads[i]->upload(TextureUploader(fGpu));
joshualitt7bc18b72015-02-03 16:41:41 -0800101 }
joshualitt5bf99f12015-03-13 11:47:42 -0700102 fInlineUpdatesIndex = 0;
103 fIter = FlushBuffer::Iter(fFlushBuffer);
joshualitt7bc18b72015-02-03 16:41:41 -0800104 }
joshualitt5bf99f12015-03-13 11:47:42 -0700105 void flushNext(int n);
106 void postFlush() {
107 SkASSERT(!fIter.next());
108 fFlushBuffer.reset();
109 fAsapUploads.reset();
110 fInlineUploads.reset();
111 }
joshualitt4d8da812015-01-28 12:53:54 -0800112
113 // TODO This goes away when everything uses batch
114 GrBatchTracker* currentBatchTracker() {
115 SkASSERT(!fFlushBuffer.empty());
116 return &fFlushBuffer.back().fBatchTracker;
117 }
118
joshualitt7bc18b72015-02-03 16:41:41 -0800119 const GrDrawTargetCaps& caps() const { return *fGpu->caps(); }
120
joshualitt4d8da812015-01-28 12:53:54 -0800121 GrVertexBufferAllocPool* vertexPool() { return fVertexPool; }
122 GrIndexBufferAllocPool* indexPool() { return fIndexPool; }
123
joshualitt5bf99f12015-03-13 11:47:42 -0700124 const static int kVertsPerRect = 4;
125 const static int kIndicesPerRect = 6;
joshualitt76e7fb62015-02-11 08:52:27 -0800126 const GrIndexBuffer* quadIndexBuffer() const { return fGpu->getQuadIndexBuffer(); }
127
joshualitt6065b882015-02-24 13:20:59 -0800128 // A helper for draws which overallocate and then return data to the pool
129 void putBackIndices(size_t indices) { fIndexPool->putBack(indices * sizeof(uint16_t)); }
130
131 void putBackVertices(size_t vertices, size_t vertexStride) {
132 fVertexPool->putBack(vertices * vertexStride);
133 }
134
joshualitt4d8da812015-01-28 12:53:54 -0800135private:
136 GrGpu* fGpu;
137 GrVertexBufferAllocPool* fVertexPool;
138 GrIndexBufferAllocPool* fIndexPool;
139
140 typedef void* TBufferAlign; // This wouldn't be enough align if a command used long double.
141
142 struct BufferedFlush {
143 BufferedFlush(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline)
144 : fPrimitiveProcessor(primProc)
joshualitt7bc18b72015-02-03 16:41:41 -0800145 , fPipeline(pipeline) {}
joshualitt4d8da812015-01-28 12:53:54 -0800146 typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
147 ProgramPrimitiveProcessor fPrimitiveProcessor;
148 const GrPipeline* fPipeline;
149 GrBatchTracker fBatchTracker;
joshualitt7bc18b72015-02-03 16:41:41 -0800150 SkSTArray<1, DrawInfo, true> fDraws;
joshualitt4d8da812015-01-28 12:53:54 -0800151 };
152
153 enum {
154 kFlushBufferInitialSizeInBytes = 8 * sizeof(BufferedFlush),
joshualitt4d8da812015-01-28 12:53:54 -0800155 };
156
157 typedef GrTRecorder<BufferedFlush, TBufferAlign> FlushBuffer;
158
159 FlushBuffer fFlushBuffer;
160 // TODO this is temporary
161 FlushBuffer::Iter fIter;
joshualitt7bc18b72015-02-03 16:41:41 -0800162 int fNumberOfDraws;
joshualitt5bf99f12015-03-13 11:47:42 -0700163 BatchToken fCurrentToken;
164 BatchToken fLastFlushedToken; // The next token to be flushed
165 SkTArray<SkAutoTUnref<Uploader>, true> fAsapUploads;
166 SkTArray<SkAutoTUnref<Uploader>, true> fInlineUploads;
167 int fInlineUpdatesIndex;
joshualitt4d8da812015-01-28 12:53:54 -0800168};
169
170#endif