reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * Copyright 2011 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. |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 8 | #ifndef GrInOrderDrawBuffer_DEFINED |
| 9 | #define GrInOrderDrawBuffer_DEFINED |
| 10 | |
bsalomon | 371bcbc | 2014-12-01 08:19:34 -0800 | [diff] [blame] | 11 | #include "GrFlushToGpuDrawTarget.h" |
robertphillips | 193ea93 | 2015-03-03 12:40:49 -0800 | [diff] [blame] | 12 | #include "GrTargetCommands.h" |
robertphillips | 9888b22 | 2015-02-27 08:50:34 -0800 | [diff] [blame] | 13 | #include "SkChunkAlloc.h" |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 14 | |
| 15 | /** |
| 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 |
| 23 | * store geometry. |
| 24 | */ |
| 25 | class GrInOrderDrawBuffer : public GrFlushToGpuDrawTarget { |
| 26 | public: |
| 27 | |
| 28 | /** |
| 29 | * Creates a GrInOrderDrawBuffer |
| 30 | * |
| 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. |
| 36 | */ |
| 37 | GrInOrderDrawBuffer(GrGpu* gpu, |
| 38 | GrVertexBufferAllocPool* vertexPool, |
| 39 | GrIndexBufferAllocPool* indexPool); |
| 40 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 41 | ~GrInOrderDrawBuffer() override; |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 42 | |
| 43 | // tracking for draws |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 44 | DrawToken getCurrentDrawToken() override { return DrawToken(this, fDrawID); } |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 45 | |
| 46 | void clearStencilClip(const SkIRect& rect, |
| 47 | bool insideClip, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 48 | GrRenderTarget* renderTarget) override; |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 49 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 50 | void discard(GrRenderTarget*) override; |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 51 | |
| 52 | protected: |
| 53 | void willReserveVertexAndIndexSpace(int vertexCount, |
| 54 | size_t vertexStride, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 55 | int indexCount) override; |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 56 | |
| 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); |
| 65 | |
| 66 | const int xformBytes = GrPathRendering::PathTransformSize(transformType) * sizeof(float); |
| 67 | *xformsLocation = NULL; |
| 68 | |
| 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); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | bool canConcatToIndexBuffer(const GrIndexBuffer** ib) { |
| 78 | const GrDrawTarget::GeometrySrcState& geomSrc = this->getGeomSrc(); |
| 79 | |
| 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) { |
| 85 | return false; |
| 86 | } |
| 87 | |
| 88 | *ib = geomSrc.fIndexBuffer; |
| 89 | return true; |
| 90 | } |
| 91 | |
| 92 | private: |
| 93 | friend class GrTargetCommands; |
| 94 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 95 | void onReset() override; |
| 96 | void onFlush() override; |
bsalomon | 371bcbc | 2014-12-01 08:19:34 -0800 | [diff] [blame] | 97 | |
bsalomon@google.com | 25fb21f | 2011-06-21 18:17:25 +0000 | [diff] [blame] | 98 | // overrides from GrDrawTarget |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 99 | void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) override; |
| 100 | void onDrawBatch(GrBatch*, const PipelineInfo&) override; |
egdaniel | 8dd688b | 2015-01-22 10:16:09 -0800 | [diff] [blame] | 101 | void onDrawRect(GrPipelineBuilder*, |
joshualitt | 2e3b3e3 | 2014-12-09 13:31:14 -0800 | [diff] [blame] | 102 | GrColor, |
joshualitt | 8059eb9 | 2014-12-29 15:10:07 -0800 | [diff] [blame] | 103 | const SkMatrix& viewMatrix, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 104 | const SkRect& rect, |
| 105 | const SkRect* localRect, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 106 | const SkMatrix* localMatrix) override; |
commit-bot@chromium.org | 32184d8 | 2013-10-09 15:14:18 +0000 | [diff] [blame] | 107 | |
egdaniel | 8dd688b | 2015-01-22 10:16:09 -0800 | [diff] [blame] | 108 | void onStencilPath(const GrPipelineBuilder&, |
joshualitt | 56995b5 | 2014-12-11 15:44:02 -0800 | [diff] [blame] | 109 | const GrPathProcessor*, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 110 | const GrPath*, |
bsalomon | 3e79124 | 2014-12-17 13:43:13 -0800 | [diff] [blame] | 111 | const GrScissorState&, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 112 | const GrStencilSettings&) override; |
egdaniel | e36914c | 2015-02-13 09:00:33 -0800 | [diff] [blame] | 113 | void onDrawPath(const GrPathProcessor*, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 114 | const GrPath*, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 115 | const GrStencilSettings&, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 116 | const PipelineInfo&) override; |
egdaniel | e36914c | 2015-02-13 09:00:33 -0800 | [diff] [blame] | 117 | void onDrawPaths(const GrPathProcessor*, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 118 | const GrPathRange*, |
cdalton | 55b24af | 2014-11-25 11:00:56 -0800 | [diff] [blame] | 119 | const void* indices, |
| 120 | PathIndexType, |
| 121 | const float transformValues[], |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 122 | PathTransformType, |
cdalton | 55b24af | 2014-11-25 11:00:56 -0800 | [diff] [blame] | 123 | int count, |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 124 | const GrStencilSettings&, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 125 | const PipelineInfo&) override; |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 126 | void onClear(const SkIRect* rect, |
| 127 | GrColor color, |
| 128 | bool canIgnoreRect, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 129 | GrRenderTarget* renderTarget) override; |
bsalomon | f90a02b | 2014-11-26 12:28:00 -0800 | [diff] [blame] | 130 | bool onCopySurface(GrSurface* dst, |
| 131 | GrSurface* src, |
| 132 | const SkIRect& srcRect, |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 133 | const SkIPoint& dstPoint) override; |
bsalomon@google.com | 116ad84 | 2013-04-09 15:38:19 +0000 | [diff] [blame] | 134 | |
bsalomon@google.com | d62e88e | 2013-02-01 14:19:27 +0000 | [diff] [blame] | 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. |
egdaniel | e36914c | 2015-02-13 09:00:33 -0800 | [diff] [blame] | 137 | int concatInstancedDraw(const DrawInfo&); |
bsalomon@google.com | 1c13c96 | 2011-02-14 16:51:21 +0000 | [diff] [blame] | 138 | |
bsalomon | 838f62d | 2014-08-05 07:15:57 -0700 | [diff] [blame] | 139 | // We lazily record clip changes in order to skip clips that have no effect. |
cdalton | 6819df3 | 2014-10-15 13:43:48 -0700 | [diff] [blame] | 140 | void recordClipIfNecessary(); |
robertphillips | 7f966f4 | 2015-03-02 06:40:12 -0800 | [diff] [blame] | 141 | // Records any trace markers for a command |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 142 | void recordTraceMarkersIfNecessary(GrTargetCommands::Cmd*); |
robertphillips | 7f966f4 | 2015-03-02 06:40:12 -0800 | [diff] [blame] | 143 | SkString getCmdString(int index) const { |
| 144 | SkASSERT(index < fGpuCmdMarkers.count()); |
| 145 | return fGpuCmdMarkers[index].toString(); |
| 146 | } |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame^] | 147 | bool isIssued(uint32_t drawID) override { return drawID != fDrawID; } |
bsalomon@google.com | 934c570 | 2012-03-20 21:17:58 +0000 | [diff] [blame] | 148 | |
bsalomon@google.com | 116ad84 | 2013-04-09 15:38:19 +0000 | [diff] [blame] | 149 | // TODO: Use a single allocator for commands and records |
bsalomon@google.com | 4b90c62 | 2011-09-28 17:52:15 +0000 | [diff] [blame] | 150 | enum { |
cdalton | 55b24af | 2014-11-25 11:00:56 -0800 | [diff] [blame] | 151 | kPathIdxBufferMinReserve = 2 * 64, // 64 uint16_t's |
| 152 | kPathXformBufferMinReserve = 2 * 64, // 64 two-float transforms |
bsalomon@google.com | 4b90c62 | 2011-09-28 17:52:15 +0000 | [diff] [blame] | 153 | }; |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 154 | |
robertphillips | dad7794 | 2015-03-03 09:28:16 -0800 | [diff] [blame] | 155 | GrTargetCommands fCommands; |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 156 | SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers; |
robertphillips | 9888b22 | 2015-02-27 08:50:34 -0800 | [diff] [blame] | 157 | SkChunkAlloc fPathIndexBuffer; |
| 158 | SkChunkAlloc fPathTransformBuffer; |
bsalomon | ae59b77 | 2014-11-19 08:23:49 -0800 | [diff] [blame] | 159 | uint32_t fDrawID; |
robertphillips@google.com | c82a8b7 | 2012-06-21 20:15:48 +0000 | [diff] [blame] | 160 | |
bsalomon | 371bcbc | 2014-12-01 08:19:34 -0800 | [diff] [blame] | 161 | typedef GrFlushToGpuDrawTarget INHERITED; |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 162 | }; |
| 163 | |
| 164 | #endif |