| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * Copyright 2014 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 #include "GrFlushToGpuDrawTarget.h" | 
|  | 9 #include "GrContext.h" | 
|  | 10 #include "GrGpu.h" | 
|  | 11 #include "GrTextStrike.h" | 
|  | 12 #include "GrBufferAllocPool.h" | 
|  | 13 | 
|  | 14 GrFlushToGpuDrawTarget::GrFlushToGpuDrawTarget(GrGpu* gpu, | 
|  | 15                                                GrVertexBufferAllocPool* vertexPo
     ol, | 
|  | 16                                                GrIndexBufferAllocPool* indexPool
     ) | 
|  | 17     : INHERITED(gpu->getContext()) | 
|  | 18     , fGpu(SkRef(gpu)) | 
|  | 19     , fVertexPool(vertexPool) | 
|  | 20     , fIndexPool(indexPool) | 
|  | 21     , fFlushing(false) { | 
|  | 22 | 
|  | 23     fCaps.reset(SkRef(fGpu->caps())); | 
|  | 24 | 
|  | 25     SkASSERT(vertexPool); | 
|  | 26     SkASSERT(indexPool); | 
|  | 27 | 
|  | 28     GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); | 
|  | 29     poolState.fUsedPoolVertexBytes = 0; | 
|  | 30     poolState.fUsedPoolIndexBytes = 0; | 
|  | 31 #ifdef SK_DEBUG | 
|  | 32     poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; | 
|  | 33     poolState.fPoolStartVertex = ~0; | 
|  | 34     poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; | 
|  | 35     poolState.fPoolStartIndex = ~0; | 
|  | 36 #endif | 
|  | 37 } | 
|  | 38 | 
|  | 39 GrFlushToGpuDrawTarget::~GrFlushToGpuDrawTarget() { | 
|  | 40     // This must be called by before the GrDrawTarget destructor | 
|  | 41     this->releaseGeometry(); | 
|  | 42 } | 
|  | 43 | 
|  | 44 void GrFlushToGpuDrawTarget::setDrawBuffers(DrawInfo* info, size_t vertexStride)
      { | 
|  | 45     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 46     if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 
|  | 47         info->setVertexBuffer(this->getGeomSrc().fVertexBuffer); | 
|  | 48     } else { | 
|  | 49         // Update the bytes used since the last reserve-geom request. | 
|  | 50         size_t bytes = (info->vertexCount() + info->startVertex()) * vertexStrid
     e; | 
|  | 51         poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, 
     bytes); | 
|  | 52         info->setVertexBuffer(poolState.fPoolVertexBuffer); | 
|  | 53         info->adjustStartVertex(poolState.fPoolStartVertex); | 
|  | 54     } | 
|  | 55 | 
|  | 56     if (info->isIndexed()) { | 
|  | 57         if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 
|  | 58             info->setIndexBuffer(this->getGeomSrc().fIndexBuffer); | 
|  | 59         } else { | 
|  | 60             // Update the bytes used since the last reserve-geom request. | 
|  | 61             size_t bytes = (info->indexCount() + info->startIndex()) * sizeof(ui
     nt16_t); | 
|  | 62             poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes
     , bytes); | 
|  | 63             info->setIndexBuffer(poolState.fPoolIndexBuffer); | 
|  | 64             info->adjustStartIndex(poolState.fPoolStartIndex); | 
|  | 65         } | 
|  | 66     } | 
|  | 67 } | 
|  | 68 | 
|  | 69 void GrFlushToGpuDrawTarget::reset() { | 
|  | 70     SkASSERT(1 == fGeoPoolStateStack.count()); | 
|  | 71     this->resetVertexSource(); | 
|  | 72     this->resetIndexSource(); | 
|  | 73 | 
|  | 74     fVertexPool->reset(); | 
|  | 75     fIndexPool->reset(); | 
|  | 76 | 
|  | 77     this->onReset(); | 
|  | 78 } | 
|  | 79 | 
|  | 80 void GrFlushToGpuDrawTarget::flush() { | 
|  | 81     SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); | 
|  | 82     SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); | 
|  | 83 | 
|  | 84     if (fFlushing) { | 
|  | 85         return; | 
|  | 86     } | 
|  | 87     fFlushing = true; | 
|  | 88 | 
|  | 89     fGpu->getContext()->getFontCache()->updateTextures(); | 
|  | 90     fVertexPool->unmap(); | 
|  | 91     fIndexPool->unmap(); | 
|  | 92 | 
|  | 93     fGpu->saveActiveTraceMarkers(); | 
|  | 94 | 
|  | 95     this->onFlush(); | 
|  | 96 | 
|  | 97     fGpu->restoreActiveTraceMarkers(); | 
|  | 98 | 
|  | 99     fFlushing = false; | 
|  | 100     this->reset(); | 
|  | 101 } | 
|  | 102 | 
|  | 103 void GrFlushToGpuDrawTarget::willReserveVertexAndIndexSpace(int vertexCount, | 
|  | 104                                                             size_t vertexStride, | 
|  | 105                                                             int indexCount) { | 
|  | 106     // We use geometryHints() to know whether to flush the draw buffer. We | 
|  | 107     // can't flush if we are inside an unbalanced pushGeometrySource. | 
|  | 108     // Moreover, flushing blows away vertex and index data that was | 
|  | 109     // previously reserved. So if the vertex or index data is pulled from | 
|  | 110     // reserved space and won't be released by this request then we can't | 
|  | 111     // flush. | 
|  | 112     bool insideGeoPush = fGeoPoolStateStack.count() > 1; | 
|  | 113 | 
|  | 114     bool unreleasedVertexSpace = | 
|  | 115         !vertexCount && | 
|  | 116         kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; | 
|  | 117 | 
|  | 118     bool unreleasedIndexSpace = | 
|  | 119         !indexCount && | 
|  | 120         kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; | 
|  | 121 | 
|  | 122     int vcount = vertexCount; | 
|  | 123     int icount = indexCount; | 
|  | 124 | 
|  | 125     if (!insideGeoPush && | 
|  | 126         !unreleasedVertexSpace && | 
|  | 127         !unreleasedIndexSpace && | 
|  | 128         this->geometryHints(vertexStride, &vcount, &icount)) { | 
|  | 129         this->flush(); | 
|  | 130     } | 
|  | 131 } | 
|  | 132 | 
|  | 133 bool GrFlushToGpuDrawTarget::geometryHints(size_t vertexStride, | 
|  | 134                                            int* vertexCount, | 
|  | 135                                            int* indexCount) const { | 
|  | 136     // we will recommend a flush if the data could fit in a single | 
|  | 137     // preallocated buffer but none are left and it can't fit | 
|  | 138     // in the current buffer (which may not be prealloced). | 
|  | 139     bool flush = false; | 
|  | 140     if (indexCount) { | 
|  | 141         int32_t currIndices = fIndexPool->currentBufferIndices(); | 
|  | 142         if (*indexCount > currIndices && | 
|  | 143             (!fIndexPool->preallocatedBuffersRemaining() && | 
|  | 144              *indexCount <= fIndexPool->preallocatedBufferIndices())) { | 
|  | 145 | 
|  | 146             flush = true; | 
|  | 147         } | 
|  | 148         *indexCount = currIndices; | 
|  | 149     } | 
|  | 150     if (vertexCount) { | 
|  | 151         int32_t currVertices = fVertexPool->currentBufferVertices(vertexStride); | 
|  | 152         if (*vertexCount > currVertices && | 
|  | 153             (!fVertexPool->preallocatedBuffersRemaining() && | 
|  | 154              *vertexCount <= fVertexPool->preallocatedBufferVertices(vertexStrid
     e))) { | 
|  | 155 | 
|  | 156             flush = true; | 
|  | 157         } | 
|  | 158         *vertexCount = currVertices; | 
|  | 159     } | 
|  | 160     return flush; | 
|  | 161 } | 
|  | 162 | 
|  | 163 bool GrFlushToGpuDrawTarget::onReserveVertexSpace(size_t vertexSize, | 
|  | 164                                                   int vertexCount, | 
|  | 165                                                   void** vertices) { | 
|  | 166     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 167     SkASSERT(vertexCount > 0); | 
|  | 168     SkASSERT(vertices); | 
|  | 169     SkASSERT(0 == poolState.fUsedPoolVertexBytes); | 
|  | 170 | 
|  | 171     *vertices = fVertexPool->makeSpace(vertexSize, | 
|  | 172                                        vertexCount, | 
|  | 173                                        &poolState.fPoolVertexBuffer, | 
|  | 174                                        &poolState.fPoolStartVertex); | 
|  | 175     return SkToBool(*vertices); | 
|  | 176 } | 
|  | 177 | 
|  | 178 bool GrFlushToGpuDrawTarget::onReserveIndexSpace(int indexCount, void** indices)
      { | 
|  | 179     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 180     SkASSERT(indexCount > 0); | 
|  | 181     SkASSERT(indices); | 
|  | 182     SkASSERT(0 == poolState.fUsedPoolIndexBytes); | 
|  | 183 | 
|  | 184     *indices = fIndexPool->makeSpace(indexCount, | 
|  | 185                                      &poolState.fPoolIndexBuffer, | 
|  | 186                                      &poolState.fPoolStartIndex); | 
|  | 187     return SkToBool(*indices); | 
|  | 188 } | 
|  | 189 | 
|  | 190 void GrFlushToGpuDrawTarget::releaseReservedVertexSpace() { | 
|  | 191     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 192     const GeometrySrcState& geoSrc = this->getGeomSrc(); | 
|  | 193 | 
|  | 194     // If we get a release vertex space call then our current source should eith
     er be reserved | 
|  | 195     // or array (which we copied into reserved space). | 
|  | 196     SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc); | 
|  | 197 | 
|  | 198     // When the caller reserved vertex buffer space we gave it back a pointer | 
|  | 199     // provided by the vertex buffer pool. At each draw we tracked the largest | 
|  | 200     // offset into the pool's pointer that was referenced. Now we return to the | 
|  | 201     // pool any portion at the tail of the allocation that no draw referenced. | 
|  | 202     size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount; | 
|  | 203     fVertexPool->putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes); | 
|  | 204     poolState.fUsedPoolVertexBytes = 0; | 
|  | 205     poolState.fPoolVertexBuffer = NULL; | 
|  | 206     poolState.fPoolStartVertex = 0; | 
|  | 207 } | 
|  | 208 | 
|  | 209 void GrFlushToGpuDrawTarget::releaseReservedIndexSpace() { | 
|  | 210     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 211     const GeometrySrcState& geoSrc = this->getGeomSrc(); | 
|  | 212 | 
|  | 213     // If we get a release index space call then our current source should eithe
     r be reserved | 
|  | 214     // or array (which we copied into reserved space). | 
|  | 215     SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc); | 
|  | 216 | 
|  | 217     // Similar to releaseReservedVertexSpace we return any unused portion at | 
|  | 218     // the tail | 
|  | 219     size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; | 
|  | 220     fIndexPool->putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); | 
|  | 221     poolState.fUsedPoolIndexBytes = 0; | 
|  | 222     poolState.fPoolIndexBuffer = NULL; | 
|  | 223     poolState.fPoolStartIndex = 0; | 
|  | 224 } | 
|  | 225 | 
|  | 226 void GrFlushToGpuDrawTarget::geometrySourceWillPush() { | 
|  | 227     GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); | 
|  | 228     poolState.fUsedPoolVertexBytes = 0; | 
|  | 229     poolState.fUsedPoolIndexBytes = 0; | 
|  | 230 #ifdef SK_DEBUG | 
|  | 231     poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; | 
|  | 232     poolState.fPoolStartVertex = ~0; | 
|  | 233     poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; | 
|  | 234     poolState.fPoolStartIndex = ~0; | 
|  | 235 #endif | 
|  | 236 } | 
|  | 237 | 
|  | 238 void GrFlushToGpuDrawTarget::geometrySourceWillPop(const GeometrySrcState& resto
     redState) { | 
|  | 239     SkASSERT(fGeoPoolStateStack.count() > 1); | 
|  | 240     fGeoPoolStateStack.pop_back(); | 
|  | 241     GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 
|  | 242     // we have to assume that any slack we had in our vertex/index data | 
|  | 243     // is now unreleasable because data may have been appended later in the | 
|  | 244     // pool. | 
|  | 245     if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { | 
|  | 246         poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
     te.fVertexCount; | 
|  | 247     } | 
|  | 248     if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { | 
|  | 249         poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
     ount; | 
|  | 250     } | 
|  | 251 } | 
| OLD | NEW | 
|---|