2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrInOrderDrawBuffer_DEFINED
9 #define GrInOrderDrawBuffer_DEFINED
11 #include "GrFlushToGpuDrawTarget.h"
12 #include "GrTargetCommands.h"
13 #include "SkChunkAlloc.h"
16 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
17 * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
18 * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
19 * references to the buffers. It is the callers responsibility to ensure that the data is still
20 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
21 * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
22 * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
25 class GrInOrderDrawBuffer : public GrFlushToGpuDrawTarget {
29 * Creates a GrInOrderDrawBuffer
31 * @param gpu the gpu object that this draw buffer flushes to.
32 * @param vertexPool pool where vertices for queued draws will be saved when
33 * the vertex source is either reserved or array.
34 * @param indexPool pool where indices for queued draws will be saved when
35 * the index source is either reserved or array.
37 GrInOrderDrawBuffer(GrGpu* gpu,
38 GrVertexBufferAllocPool* vertexPool,
39 GrIndexBufferAllocPool* indexPool);
41 ~GrInOrderDrawBuffer() override;
44 DrawToken getCurrentDrawToken() override { return DrawToken(this, fDrawID); }
46 void clearStencilClip(const SkIRect& rect,
48 GrRenderTarget* renderTarget) override;
50 void discard(GrRenderTarget*) override;
53 void willReserveVertexAndIndexSpace(int vertexCount,
55 int indexCount) override;
57 void appendIndicesAndTransforms(const void* indexValues, PathIndexType indexType,
58 const float* transformValues, PathTransformType transformType,
59 int count, char** indicesLocation, float** xformsLocation) {
60 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
61 *indicesLocation = (char*) fPathIndexBuffer.alloc(count * indexBytes,
62 SkChunkAlloc::kThrow_AllocFailType);
63 SkASSERT(SkIsAlign4((uintptr_t)*indicesLocation));
64 memcpy(*indicesLocation, reinterpret_cast<const char*>(indexValues), count * indexBytes);
66 const int xformBytes = GrPathRendering::PathTransformSize(transformType) * sizeof(float);
67 *xformsLocation = NULL;
69 if (0 != xformBytes) {
70 *xformsLocation = (float*) fPathTransformBuffer.alloc(count * xformBytes,
71 SkChunkAlloc::kThrow_AllocFailType);
72 SkASSERT(SkIsAlign4((uintptr_t)*xformsLocation));
73 memcpy(*xformsLocation, transformValues, count * xformBytes);
77 bool canConcatToIndexBuffer(const GrIndexBuffer** ib) {
78 const GrDrawTarget::GeometrySrcState& geomSrc = this->getGeomSrc();
80 // we only attempt to concat when reserved verts are used with a client-specified
81 // index buffer. To make this work with client-specified VBs we'd need to know if the VB
82 // was updated between draws.
83 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
84 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
88 *ib = geomSrc.fIndexBuffer;
93 friend class GrTargetCommands;
95 void onReset() override;
96 void onFlush() override;
98 // overrides from GrDrawTarget
99 void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) override;
100 void onDrawBatch(GrBatch*, const PipelineInfo&) override;
101 void onDrawRect(GrPipelineBuilder*,
103 const SkMatrix& viewMatrix,
105 const SkRect* localRect,
106 const SkMatrix* localMatrix) override;
108 void onStencilPath(const GrPipelineBuilder&,
109 const GrPathProcessor*,
111 const GrScissorState&,
112 const GrStencilSettings&) override;
113 void onDrawPath(const GrPathProcessor*,
115 const GrStencilSettings&,
116 const PipelineInfo&) override;
117 void onDrawPaths(const GrPathProcessor*,
121 const float transformValues[],
124 const GrStencilSettings&,
125 const PipelineInfo&) override;
126 void onClear(const SkIRect* rect,
129 GrRenderTarget* renderTarget) override;
130 bool onCopySurface(GrSurface* dst,
132 const SkIRect& srcRect,
133 const SkIPoint& dstPoint) override;
135 // Attempts to concat instances from info onto the previous draw. info must represent an
136 // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
137 int concatInstancedDraw(const DrawInfo&);
139 // We lazily record clip changes in order to skip clips that have no effect.
140 void recordClipIfNecessary();
141 // Records any trace markers for a command
142 void recordTraceMarkersIfNecessary(GrTargetCommands::Cmd*);
143 SkString getCmdString(int index) const {
144 SkASSERT(index < fGpuCmdMarkers.count());
145 return fGpuCmdMarkers[index].toString();
147 bool isIssued(uint32_t drawID) override { return drawID != fDrawID; }
149 // TODO: Use a single allocator for commands and records
151 kPathIdxBufferMinReserve = 2 * 64, // 64 uint16_t's
152 kPathXformBufferMinReserve = 2 * 64, // 64 two-float transforms
155 GrTargetCommands fCommands;
156 SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
157 SkChunkAlloc fPathIndexBuffer;
158 SkChunkAlloc fPathTransformBuffer;
161 typedef GrFlushToGpuDrawTarget INHERITED;