int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { GrAssert(info.isInstanced()); const GeometrySrcState& geomSrc = this->getGeomSrc(); const GrDrawState& drawState = this->getDrawState(); // we only attempt to concat the case when reserved verts are used with a client-specified index // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated // between draws. if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { return 0; } // Check if there is a draw info that is compatible that uses the same VB from the pool and // the same IB if (kDraw_Cmd != fCmds.back()) { return 0; } DrawRecord* draw = &fDraws.back(); GeometryPoolState& poolState = fGeoPoolStateStack.back(); const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; if (!draw->isInstanced() || draw->verticesPerInstance() != info.verticesPerInstance() || draw->indicesPerInstance() != info.indicesPerInstance() || draw->fVertexBuffer != vertexBuffer || draw->fIndexBuffer != geomSrc.fIndexBuffer) { return 0; } // info does not yet account for the offset from the start of the pool's VB while the previous // draw record does. int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) { return 0; } GrAssert(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCount()); // how many instances can be concat'ed onto draw given the size of the index buffer int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance(); instancesToConcat -= draw->instanceCount(); instancesToConcat = GrMin(instancesToConcat, info.instanceCount()); // update the amount of reserved vertex data actually referenced in draws size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * drawState.getVertexSize(); poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); draw->adjustInstanceCount(instancesToConcat); return instancesToConcat; }
int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { SkASSERT(!fCmdBuffer.empty()); SkASSERT(info.isInstanced()); const GeometrySrcState& geomSrc = this->getGeomSrc(); const GrDrawState& drawState = this->getDrawState(); // we only attempt to concat the case when reserved verts are used with a client-specified index // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated // between draws. if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { return 0; } // Check if there is a draw info that is compatible that uses the same VB from the pool and // the same IB if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) { return 0; } Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); GeometryPoolState& poolState = fGeoPoolStateStack.back(); const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; if (!draw->fInfo.isInstanced() || draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || draw->vertexBuffer() != vertexBuffer || draw->indexBuffer() != geomSrc.fIndexBuffer) { return 0; } // info does not yet account for the offset from the start of the pool's VB while the previous // draw record does. int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVertex) { return 0; } SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fInfo.vertexCount()); // how many instances can be concat'ed onto draw given the size of the index buffer int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance(); instancesToConcat -= draw->fInfo.instanceCount(); instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); // update the amount of reserved vertex data actually referenced in draws size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * drawState.getVertexStride(); poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes); draw->fInfo.adjustInstanceCount(instancesToConcat); // update last fGpuCmdMarkers to include any additional trace markers that have been added if (this->getActiveTraceMarkers().count() > 0) { if (cmd_has_trace_marker(draw->fType)) { fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); } else { fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); draw->fType = add_trace_bit(draw->fType); } } return instancesToConcat; }