blob: ae046c1ee1e2cb44e406d1603187682d9e3330c7 [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
joshualitt6065b882015-02-24 13:20:59 -080011#include "GrBufferAllocPool.h"
joshualitt4d8da812015-01-28 12:53:54 -080012#include "GrPendingProgramElement.h"
joshualitt7bc18b72015-02-03 16:41:41 -080013#include "GrPipeline.h"
joshualitt4d8da812015-01-28 12:53:54 -080014#include "GrGpu.h"
15#include "GrTRecorder.h"
16
17/*
18 * GrBatch instances use this object to allocate space for their geometry and to issue the draws
19 * that render their batch.
20 */
21
joshualitt7bc18b72015-02-03 16:41:41 -080022class GrIndexBufferAllocPool;
23class GrVertexBufferAllocPool;
24
joshualitt4d8da812015-01-28 12:53:54 -080025class GrBatchTarget : public SkNoncopyable {
26public:
27 GrBatchTarget(GrGpu* gpu,
28 GrVertexBufferAllocPool* vpool,
29 GrIndexBufferAllocPool* ipool)
30 : fGpu(gpu)
31 , fVertexPool(vpool)
32 , fIndexPool(ipool)
33 , fFlushBuffer(kFlushBufferInitialSizeInBytes)
joshualitt7bc18b72015-02-03 16:41:41 -080034 , fIter(fFlushBuffer)
35 , fNumberOfDraws(0) {}
joshualitt4d8da812015-01-28 12:53:54 -080036
37 typedef GrDrawTarget::DrawInfo DrawInfo;
38 void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
39 GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
joshualitt7bc18b72015-02-03 16:41:41 -080040 fNumberOfDraws++;
joshualitt4d8da812015-01-28 12:53:54 -080041 }
42
43 void draw(const GrDrawTarget::DrawInfo& draw) {
44 fFlushBuffer.back().fDraws.push_back(draw);
45 }
46
47 // TODO this is temporary until batch is everywhere
48 //void flush();
joshualitt7bc18b72015-02-03 16:41:41 -080049 void resetNumberOfDraws() { fNumberOfDraws = 0; }
50 int numberOfDraws() const { return fNumberOfDraws; }
joshualitt4d8da812015-01-28 12:53:54 -080051 void preFlush() { fIter = FlushBuffer::Iter(fFlushBuffer); }
joshualitt7bc18b72015-02-03 16:41:41 -080052 void flushNext(int n) {
53 for (; n > 0; n--) {
54 SkDEBUGCODE(bool verify =) fIter.next();
55 SkASSERT(verify);
56 GrProgramDesc desc;
57 BufferedFlush* bf = fIter.get();
58 const GrPipeline* pipeline = bf->fPipeline;
59 const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get();
bsalomon50785a32015-02-06 07:02:37 -080060 fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker);
joshualitt7bc18b72015-02-03 16:41:41 -080061
62 GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
63
64 int drawCount = bf->fDraws.count();
65 const SkSTArray<1, DrawInfo, true>& draws = bf->fDraws;
66 for (int i = 0; i < drawCount; i++) {
67 fGpu->draw(args, draws[i]);
68 }
69 }
70 }
joshualitt4d8da812015-01-28 12:53:54 -080071 void postFlush() { SkASSERT(!fIter.next()); fFlushBuffer.reset(); }
72
73 // TODO This goes away when everything uses batch
74 GrBatchTracker* currentBatchTracker() {
75 SkASSERT(!fFlushBuffer.empty());
76 return &fFlushBuffer.back().fBatchTracker;
77 }
78
joshualitt7bc18b72015-02-03 16:41:41 -080079 const GrDrawTargetCaps& caps() const { return *fGpu->caps(); }
80
joshualitt4d8da812015-01-28 12:53:54 -080081 GrVertexBufferAllocPool* vertexPool() { return fVertexPool; }
82 GrIndexBufferAllocPool* indexPool() { return fIndexPool; }
83
joshualitt76e7fb62015-02-11 08:52:27 -080084 const GrIndexBuffer* quadIndexBuffer() const { return fGpu->getQuadIndexBuffer(); }
85
joshualitt6065b882015-02-24 13:20:59 -080086 // A helper for draws which overallocate and then return data to the pool
87 void putBackIndices(size_t indices) { fIndexPool->putBack(indices * sizeof(uint16_t)); }
88
89 void putBackVertices(size_t vertices, size_t vertexStride) {
90 fVertexPool->putBack(vertices * vertexStride);
91 }
92
joshualitt4d8da812015-01-28 12:53:54 -080093private:
94 GrGpu* fGpu;
95 GrVertexBufferAllocPool* fVertexPool;
96 GrIndexBufferAllocPool* fIndexPool;
97
98 typedef void* TBufferAlign; // This wouldn't be enough align if a command used long double.
99
100 struct BufferedFlush {
101 BufferedFlush(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline)
102 : fPrimitiveProcessor(primProc)
joshualitt7bc18b72015-02-03 16:41:41 -0800103 , fPipeline(pipeline) {}
joshualitt4d8da812015-01-28 12:53:54 -0800104 typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
105 ProgramPrimitiveProcessor fPrimitiveProcessor;
106 const GrPipeline* fPipeline;
107 GrBatchTracker fBatchTracker;
joshualitt7bc18b72015-02-03 16:41:41 -0800108 SkSTArray<1, DrawInfo, true> fDraws;
joshualitt4d8da812015-01-28 12:53:54 -0800109 };
110
111 enum {
112 kFlushBufferInitialSizeInBytes = 8 * sizeof(BufferedFlush),
joshualitt4d8da812015-01-28 12:53:54 -0800113 };
114
115 typedef GrTRecorder<BufferedFlush, TBufferAlign> FlushBuffer;
116
117 FlushBuffer fFlushBuffer;
118 // TODO this is temporary
119 FlushBuffer::Iter fIter;
joshualitt7bc18b72015-02-03 16:41:41 -0800120 int fNumberOfDraws;
joshualitt4d8da812015-01-28 12:53:54 -0800121};
122
123#endif