blob: 91726e5b9f7df20e942e64b688cc12052e0956b3 [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 "GrTRecorder.h"
bsalomoncb8979d2015-05-05 09:51:38 -070016#include "GrVertices.h"
joshualitt4d8da812015-01-28 12:53:54 -080017
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
joshualitt4d8da812015-01-28 12:53:54 -080033 void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
34 GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
joshualitt7bc18b72015-02-03 16:41:41 -080035 fNumberOfDraws++;
joshualitt5bf99f12015-03-13 11:47:42 -070036 fCurrentToken++;
37 }
38
39 class TextureUploader {
40 public:
41 TextureUploader(GrGpu* gpu) : fGpu(gpu) { SkASSERT(gpu); }
42
43 /**
44 * Updates the pixels in a rectangle of a texture.
45 *
46 * @param left left edge of the rectangle to write (inclusive)
47 * @param top top edge of the rectangle to write (inclusive)
48 * @param width width of rectangle to write in pixels.
49 * @param height height of rectangle to write in pixels.
50 * @param config the pixel config of the source buffer
51 * @param buffer memory to read pixels from
52 * @param rowBytes number of bytes between consecutive rows. Zero
53 * means rows are tightly packed.
54 */
55 bool writeTexturePixels(GrTexture* texture,
56 int left, int top, int width, int height,
57 GrPixelConfig config, const void* buffer,
58 size_t rowBytes) {
59 return fGpu->writeTexturePixels(texture, left, top, width, height, config, buffer,
60 rowBytes);
61 }
62
63 private:
64 GrGpu* fGpu;
65 };
66
67 class Uploader : public SkRefCnt {
68 public:
69 Uploader(BatchToken lastUploadToken) : fLastUploadToken(lastUploadToken) {}
70 BatchToken lastUploadToken() const { return fLastUploadToken; }
71 virtual void upload(TextureUploader)=0;
72
73 private:
74 BatchToken fLastUploadToken;
75 };
76
77 void upload(Uploader* upload) {
78 if (this->asapToken() == upload->lastUploadToken()) {
79 fAsapUploads.push_back().reset(SkRef(upload));
80 } else {
81 fInlineUploads.push_back().reset(SkRef(upload));
82 }
joshualitt4d8da812015-01-28 12:53:54 -080083 }
84
bsalomoncb8979d2015-05-05 09:51:38 -070085 void draw(const GrVertices& vertices) {
86 fFlushBuffer.back().fVertexDraws.push_back(vertices);
joshualitt4d8da812015-01-28 12:53:54 -080087 }
88
joshualitt5bf99f12015-03-13 11:47:42 -070089 bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; }
90 BatchToken currentToken() const { return fCurrentToken; }
91 BatchToken asapToken() const { return fLastFlushedToken + 1; }
92
93 // TODO much of this complexity goes away when batch is everywhere
joshualitt7bc18b72015-02-03 16:41:41 -080094 void resetNumberOfDraws() { fNumberOfDraws = 0; }
95 int numberOfDraws() const { return fNumberOfDraws; }
joshualitt5bf99f12015-03-13 11:47:42 -070096 void preFlush() {
97 int updateCount = fAsapUploads.count();
98 for (int i = 0; i < updateCount; i++) {
99 fAsapUploads[i]->upload(TextureUploader(fGpu));
joshualitt7bc18b72015-02-03 16:41:41 -0800100 }
joshualitt5bf99f12015-03-13 11:47:42 -0700101 fInlineUpdatesIndex = 0;
102 fIter = FlushBuffer::Iter(fFlushBuffer);
joshualitt7bc18b72015-02-03 16:41:41 -0800103 }
joshualitt5bf99f12015-03-13 11:47:42 -0700104 void flushNext(int n);
105 void postFlush() {
106 SkASSERT(!fIter.next());
107 fFlushBuffer.reset();
108 fAsapUploads.reset();
109 fInlineUploads.reset();
110 }
joshualitt4d8da812015-01-28 12:53:54 -0800111
112 // TODO This goes away when everything uses batch
113 GrBatchTracker* currentBatchTracker() {
114 SkASSERT(!fFlushBuffer.empty());
115 return &fFlushBuffer.back().fBatchTracker;
116 }
117
joshualitt7bc18b72015-02-03 16:41:41 -0800118 const GrDrawTargetCaps& caps() const { return *fGpu->caps(); }
119
joshualitt4d8da812015-01-28 12:53:54 -0800120 GrVertexBufferAllocPool* vertexPool() { return fVertexPool; }
121 GrIndexBufferAllocPool* indexPool() { return fIndexPool; }
122
bsalomoned0bcad2015-05-04 10:36:42 -0700123 GrResourceProvider* resourceProvider() const { return fGpu->getContext()->resourceProvider(); }
joshualitt76e7fb62015-02-11 08:52:27 -0800124
joshualitt6065b882015-02-24 13:20:59 -0800125 // A helper for draws which overallocate and then return data to the pool
126 void putBackIndices(size_t indices) { fIndexPool->putBack(indices * sizeof(uint16_t)); }
127
128 void putBackVertices(size_t vertices, size_t vertexStride) {
129 fVertexPool->putBack(vertices * vertexStride);
130 }
131
joshualitt4d8da812015-01-28 12:53:54 -0800132private:
133 GrGpu* fGpu;
134 GrVertexBufferAllocPool* fVertexPool;
135 GrIndexBufferAllocPool* fIndexPool;
136
137 typedef void* TBufferAlign; // This wouldn't be enough align if a command used long double.
138
139 struct BufferedFlush {
140 BufferedFlush(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline)
141 : fPrimitiveProcessor(primProc)
joshualitt7bc18b72015-02-03 16:41:41 -0800142 , fPipeline(pipeline) {}
joshualitt4d8da812015-01-28 12:53:54 -0800143 typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
144 ProgramPrimitiveProcessor fPrimitiveProcessor;
145 const GrPipeline* fPipeline;
146 GrBatchTracker fBatchTracker;
bsalomoncb8979d2015-05-05 09:51:38 -0700147 SkSTArray<1, GrVertices, true> fVertexDraws;
joshualitt4d8da812015-01-28 12:53:54 -0800148 };
149
150 enum {
151 kFlushBufferInitialSizeInBytes = 8 * sizeof(BufferedFlush),
joshualitt4d8da812015-01-28 12:53:54 -0800152 };
153
154 typedef GrTRecorder<BufferedFlush, TBufferAlign> FlushBuffer;
155
156 FlushBuffer fFlushBuffer;
157 // TODO this is temporary
158 FlushBuffer::Iter fIter;
joshualitt7bc18b72015-02-03 16:41:41 -0800159 int fNumberOfDraws;
joshualitt5bf99f12015-03-13 11:47:42 -0700160 BatchToken fCurrentToken;
161 BatchToken fLastFlushedToken; // The next token to be flushed
162 SkTArray<SkAutoTUnref<Uploader>, true> fAsapUploads;
163 SkTArray<SkAutoTUnref<Uploader>, true> fInlineUploads;
164 int fInlineUpdatesIndex;
joshualitt4d8da812015-01-28 12:53:54 -0800165};
166
167#endif