diff options
Diffstat (limited to 'src/gpu')
-rwxr-xr-x | src/gpu/GrAADistanceFieldPathRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextContext.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrBatchAtlas.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 12 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 529 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 395 | ||||
-rw-r--r-- | src/gpu/GrFlushToGpuDrawTarget.cpp | 196 | ||||
-rw-r--r-- | src/gpu/GrFlushToGpuDrawTarget.h | 36 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 17 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 24 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrTargetCommands.cpp | 96 | ||||
-rw-r--r-- | src/gpu/GrTessellatingPathRenderer.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrTest.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrTest.h | 2 | ||||
-rw-r--r-- | src/gpu/GrTestBatch.h | 1 | ||||
-rw-r--r-- | src/gpu/effects/GrDashingEffect.cpp | 1 |
22 files changed, 22 insertions, 1302 deletions
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 95aa3aa6bb..48427fa083 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -16,6 +16,7 @@ #include "GrSurfacePriv.h" #include "GrSWMaskHelper.h" #include "GrTexturePriv.h" +#include "GrVertexBuffer.h" #include "effects/GrDistanceFieldGeoProc.h" #include "SkDistanceFieldGen.h" diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index a9bc9f2f63..477385467e 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -18,6 +18,7 @@ #include "GrPathUtils.h" #include "GrPipelineBuilder.h" #include "GrProcessor.h" +#include "GrVertexBuffer.h" #include "SkGeometry.h" #include "SkStroke.h" #include "SkTemplates.h" diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 83c1d91ec8..e82852485a 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -13,6 +13,7 @@ #include "GrGeometryProcessor.h" #include "GrGpu.h" #include "GrInvariantOutput.h" +#include "GrVertexBuffer.h" #include "SkColorPriv.h" #include "gl/GrGLProcessor.h" #include "gl/GrGLGeometryProcessor.h" diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index c2c76edec3..dee3be7635 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -16,6 +16,7 @@ #include "GrStrokeInfo.h" #include "GrTextBlobCache.h" #include "GrTexturePriv.h" +#include "GrVertexBuffer.h" #include "SkAutoKern.h" #include "SkColorPriv.h" diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp index b983438900..7d67f19233 100644 --- a/src/gpu/GrBatchAtlas.cpp +++ b/src/gpu/GrBatchAtlas.cpp @@ -10,6 +10,7 @@ #include "GrGpu.h" #include "GrRectanizer.h" #include "GrTracing.h" +#include "GrVertexBuffer.h" static inline void adjust_for_offset(SkIPoint16* loc, const SkIPoint16& offset) { loc->fX += offset.fX; diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 2a778bd9af..945d6bee83 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -376,7 +376,6 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder, GrTexture* target, const SkClipStack::Element* element, GrPathRenderer* pr) { - GrDrawTarget::AutoGeometryPush agp(fClipTarget); pipelineBuilder->setRenderTarget(target->asRenderTarget()); @@ -478,8 +477,6 @@ void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, GrTextureDomain::MakeTexelDomain(srcMask, srcBound), GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode))->unref(); - // We need this AGP until everything is in GrBatch - GrDrawTarget::AutoGeometryPush agp(fClipTarget); // The color passed in here does not matter since the coverageSetOpXP won't read it. fClipTarget->drawSimpleRect(pipelineBuilder, @@ -673,8 +670,6 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, 0xffff); backgroundPipelineBuilder.setStencil(kDrawOutsideElement); - // We need this AGP until everything is in GrBatch - GrDrawTarget::AutoGeometryPush agp(fClipTarget); // The color passed in here does not matter since the coverageSetOpXP won't read it. fClipTarget->drawSimpleRect(&backgroundPipelineBuilder, GrColor_WHITE, translate, clipSpaceIBounds); @@ -813,14 +808,12 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, *pipelineBuilder.stencil() = gDrawToStencil; // We need this AGP until everything is in GrBatch - GrDrawTarget::AutoGeometryPush agp(fClipTarget); fClipTarget->drawSimpleRect(&pipelineBuilder, GrColor_WHITE, viewMatrix, element->getRect()); } else { if (!clipPath.isEmpty()) { - GrDrawTarget::AutoGeometryPush agp(fClipTarget); if (canRenderDirectToStencil) { *pipelineBuilder.stencil() = gDrawToStencil; pr->drawPath(fClipTarget, &pipelineBuilder, GrColor_WHITE, @@ -843,20 +836,15 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, if (canDrawDirectToClip) { if (Element::kRect_Type == element->getType()) { // We need this AGP until everything is in GrBatch - GrDrawTarget::AutoGeometryPush agp(fClipTarget); fClipTarget->drawSimpleRect(&pipelineBuilderCopy, GrColor_WHITE, viewMatrix, element->getRect()); } else { - GrDrawTarget::AutoGeometryPush agp(fClipTarget); pr->drawPath(fClipTarget, &pipelineBuilderCopy, GrColor_WHITE, viewMatrix, clipPath, stroke, false); } } else { - // We need this AGP until everything is in GrBatch - GrDrawTarget::AutoGeometryPush agp(fClipTarget); - // The view matrix is setup to do clip space -> stencil space translation, so // draw rect in clip space. fClipTarget->drawSimpleRect(&pipelineBuilderCopy, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 7d315eb32b..4547aadfb1 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1111,7 +1111,6 @@ void GrContext::drawVertices(GrRenderTarget* rt, RETURN_IF_ABANDONED AutoCheckFlush acf(this); GrPipelineBuilder pipelineBuilder; - GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); if (NULL == target) { @@ -1596,7 +1595,6 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, if (!drawTarget) { return false; } - GrDrawTarget::AutoGeometryPush agp(drawTarget); GrPipelineBuilder pipelineBuilder; pipelineBuilder.addColorProcessor(fp); @@ -1719,7 +1717,6 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target, // clear to the caller that a draw operation (i.e., drawSimpleRect) // can be invoked in this method { - GrDrawTarget::AutoGeometryPush agp(fDrawBuffer); GrPipelineBuilder pipelineBuilder; SkASSERT(fp); pipelineBuilder.addColorProcessor(fp); diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 88834bb80c..acc18715c2 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -14,6 +14,7 @@ #include "GrDefaultGeoProcFactory.h" #include "GrPathUtils.h" #include "GrPipelineBuilder.h" +#include "GrVertexBuffer.h" #include "SkGeometry.h" #include "SkString.h" #include "SkStrokeRec.h" @@ -691,7 +692,6 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, } else { bounds = path.getBounds(); } - GrDrawTarget::AutoGeometryPush agp(target); const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix; target->drawRect(pipelineBuilder, color, viewM, bounds, NULL, &localMatrix); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index bca347dbea..d6fbbc24fd 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -50,43 +50,6 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { return *this; } -#ifdef SK_DEBUG -bool GrDrawTarget::DrawInfo::isInstanced() const { - if (fInstanceCount > 0) { - SkASSERT(0 == fIndexCount % fIndicesPerInstance); - SkASSERT(0 == fVertexCount % fVerticesPerInstance); - SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount); - SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount); - // there is no way to specify a non-zero start index to drawIndexedInstances(). - SkASSERT(0 == fStartIndex); - return true; - } else { - SkASSERT(!fVerticesPerInstance); - SkASSERT(!fIndicesPerInstance); - return false; - } -} -#endif - -void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) { - SkASSERT(this->isInstanced()); - SkASSERT(instanceOffset + fInstanceCount >= 0); - fInstanceCount += instanceOffset; - fVertexCount = fVerticesPerInstance * fInstanceCount; - fIndexCount = fIndicesPerInstance * fInstanceCount; -} - -void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) { - fStartVertex += vertexOffset; - SkASSERT(fStartVertex >= 0); -} - -void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) { - SkASSERT(this->isIndexed()); - fStartIndex += indexOffset; - SkASSERT(fStartIndex >= 0); -} - //////////////////////////////////////////////////////////////////////////////// #define DEBUG_INVAL_BUFFER 0xdeadcafe @@ -96,288 +59,10 @@ GrDrawTarget::GrDrawTarget(GrContext* context) : fContext(context) , fGpuTraceMarkerCount(0) { SkASSERT(context); - GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); -#ifdef SK_DEBUG - geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; - geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; - geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; - geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; -#endif - geoSrc.fVertexSrc = kNone_GeometrySrcType; - geoSrc.fIndexSrc = kNone_GeometrySrcType; -} - -GrDrawTarget::~GrDrawTarget() { - SkASSERT(1 == fGeoSrcStateStack.count()); - SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back()); - SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc); - SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc); -} - -void GrDrawTarget::releaseGeometry() { - int popCnt = fGeoSrcStateStack.count() - 1; - while (popCnt) { - this->popGeometrySource(); - --popCnt; - } - this->resetVertexSource(); - this->resetIndexSource(); -} - -bool GrDrawTarget::reserveVertexSpace(size_t vertexSize, - int vertexCount, - void** vertices) { - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - bool acquired = false; - if (vertexCount > 0) { - SkASSERT(vertices); - this->releasePreviousVertexSource(); - geoSrc.fVertexSrc = kNone_GeometrySrcType; - - acquired = this->onReserveVertexSpace(vertexSize, - vertexCount, - vertices); - } - if (acquired) { - geoSrc.fVertexSrc = kReserved_GeometrySrcType; - geoSrc.fVertexCount = vertexCount; - geoSrc.fVertexSize = vertexSize; - } else if (vertices) { - *vertices = NULL; - } - return acquired; -} - -bool GrDrawTarget::reserveIndexSpace(int indexCount, - void** indices) { - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - bool acquired = false; - if (indexCount > 0) { - SkASSERT(indices); - this->releasePreviousIndexSource(); - geoSrc.fIndexSrc = kNone_GeometrySrcType; - - acquired = this->onReserveIndexSpace(indexCount, indices); - } - if (acquired) { - geoSrc.fIndexSrc = kReserved_GeometrySrcType; - geoSrc.fIndexCount = indexCount; - } else if (indices) { - *indices = NULL; - } - return acquired; - -} - -bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount, - void** vertices, - void** indices) { - this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount); - if (vertexCount) { - if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) { - if (indexCount) { - this->resetIndexSource(); - } - return false; - } - } - if (indexCount) { - if (!this->reserveIndexSpace(indexCount, indices)) { - if (vertexCount) { - this->resetVertexSource(); - } - return false; - } - } - return true; -} - -bool GrDrawTarget::geometryHints(size_t vertexStride, - int32_t* vertexCount, - int32_t* indexCount) const { - if (vertexCount) { - *vertexCount = -1; - } - if (indexCount) { - *indexCount = -1; - } - return false; -} - -void GrDrawTarget::releasePreviousVertexSource() { - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - switch (geoSrc.fVertexSrc) { - case kNone_GeometrySrcType: - break; - case kReserved_GeometrySrcType: - this->releaseReservedVertexSpace(); - break; - case kBuffer_GeometrySrcType: - geoSrc.fVertexBuffer->unref(); -#ifdef SK_DEBUG - geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; -#endif - break; - default: - SkFAIL("Unknown Vertex Source Type."); - break; - } -} - -void GrDrawTarget::releasePreviousIndexSource() { - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - switch (geoSrc.fIndexSrc) { - case kNone_GeometrySrcType: // these two don't require - break; - case kReserved_GeometrySrcType: - this->releaseReservedIndexSpace(); - break; - case kBuffer_GeometrySrcType: - geoSrc.fIndexBuffer->unref(); -#ifdef SK_DEBUG - geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; -#endif - break; - default: - SkFAIL("Unknown Index Source Type."); - break; - } -} - -void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) { - this->releasePreviousVertexSource(); - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - geoSrc.fVertexSrc = kBuffer_GeometrySrcType; - geoSrc.fVertexBuffer = buffer; - buffer->ref(); - geoSrc.fVertexSize = vertexStride; -} - -void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { - this->releasePreviousIndexSource(); - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - geoSrc.fIndexSrc = kBuffer_GeometrySrcType; - geoSrc.fIndexBuffer = buffer; - buffer->ref(); -} - -void GrDrawTarget::resetVertexSource() { - this->releasePreviousVertexSource(); - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - geoSrc.fVertexSrc = kNone_GeometrySrcType; -} - -void GrDrawTarget::resetIndexSource() { - this->releasePreviousIndexSource(); - GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - geoSrc.fIndexSrc = kNone_GeometrySrcType; -} - -void GrDrawTarget::pushGeometrySource() { - this->geometrySourceWillPush(); - GeometrySrcState& newState = fGeoSrcStateStack.push_back(); - newState.fIndexSrc = kNone_GeometrySrcType; - newState.fVertexSrc = kNone_GeometrySrcType; -#ifdef SK_DEBUG - newState.fVertexCount = ~0; - newState.fVertexBuffer = (GrVertexBuffer*)~0; - newState.fIndexCount = ~0; - newState.fIndexBuffer = (GrIndexBuffer*)~0; -#endif -} - -void GrDrawTarget::popGeometrySource() { - // if popping last element then pops are unbalanced with pushes - SkASSERT(fGeoSrcStateStack.count() > 1); - - this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); - this->releasePreviousVertexSource(); - this->releasePreviousIndexSource(); - fGeoSrcStateStack.pop_back(); } //////////////////////////////////////////////////////////////////////////////// -bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder, - const GrGeometryProcessor* gp, - GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) const { -#ifdef SK_DEBUG - const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); - int maxVertex = startVertex + vertexCount; - int maxValidVertex; - switch (geoSrc.fVertexSrc) { - case kNone_GeometrySrcType: - SkFAIL("Attempting to draw without vertex src."); - case kReserved_GeometrySrcType: // fallthrough - maxValidVertex = geoSrc.fVertexCount; - break; - case kBuffer_GeometrySrcType: - maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() / - geoSrc.fVertexSize); - break; - } - if (maxVertex > maxValidVertex) { - SkFAIL("Drawing outside valid vertex range."); - } - if (indexCount > 0) { - int maxIndex = startIndex + indexCount; - int maxValidIndex; - switch (geoSrc.fIndexSrc) { - case kNone_GeometrySrcType: - SkFAIL("Attempting to draw indexed geom without index src."); - case kReserved_GeometrySrcType: // fallthrough - maxValidIndex = geoSrc.fIndexCount; - break; - case kBuffer_GeometrySrcType: - maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() / - sizeof(uint16_t)); - break; - } - if (maxIndex > maxValidIndex) { - SkFAIL("Index reads outside valid index range."); - } - } - - SkASSERT(pipelineBuilder.getRenderTarget()); - - if (gp) { - int numTextures = gp->numTextures(); - for (int t = 0; t < numTextures; ++t) { - GrTexture* texture = gp->texture(t); - SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget()); - } - } - - for (int s = 0; s < pipelineBuilder.numColorFragmentStages(); ++s) { - const GrProcessor* effect = pipelineBuilder.getColorFragmentStage(s).processor(); - int numTextures = effect->numTextures(); - for (int t = 0; t < numTextures; ++t) { - GrTexture* texture = effect->texture(t); - SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget()); - } - } - for (int s = 0; s < pipelineBuilder.numCoverageFragmentStages(); ++s) { - const GrProcessor* effect = pipelineBuilder.getCoverageFragmentStage(s).processor(); - int numTextures = effect->numTextures(); - for (int t = 0; t < numTextures; ++t) { - GrTexture* texture = effect->texture(t); - SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget()); - } - } - -#endif - if (NULL == pipelineBuilder.getRenderTarget()) { - return false; - } - return true; -} - bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder, const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, @@ -429,100 +114,6 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil } } -void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder, - const GrGeometryProcessor* gp, - GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount, - const SkRect* devBounds) { - SkASSERT(pipelineBuilder); - if (indexCount > 0 && - this->checkDraw(*pipelineBuilder, gp, type, startVertex, startIndex, vertexCount, - indexCount)) { - - // Setup clip - GrScissorState scissorState; - GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; - GrPipelineBuilder::AutoRestoreStencil ars; - if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) { - return; - } - - DrawInfo info; - info.fPrimitiveType = type; - info.fStartVertex = startVertex; - info.fStartIndex = startIndex; - info.fVertexCount = vertexCount; - info.fIndexCount = indexCount; - - info.fInstanceCount = 0; - info.fVerticesPerInstance = 0; - info.fIndicesPerInstance = 0; - - if (devBounds) { - info.setDevBounds(*devBounds); - } - - GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, - this); - if (pipelineInfo.mustSkipDraw()) { - return; - } - - this->setDrawBuffers(&info, gp->getVertexStride()); - - this->onDraw(gp, info, pipelineInfo); - } -} - -void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, - const GrGeometryProcessor* gp, - GrPrimitiveType type, - int startVertex, - int vertexCount, - const SkRect* devBounds) { - SkASSERT(pipelineBuilder); - if (vertexCount > 0 && this->checkDraw(*pipelineBuilder, gp, type, startVertex, -1, vertexCount, - -1)) { - - // Setup clip - GrScissorState scissorState; - GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; - GrPipelineBuilder::AutoRestoreStencil ars; - if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) { - return; - } - - DrawInfo info; - info.fPrimitiveType = type; - info.fStartVertex = startVertex; - info.fStartIndex = 0; - info.fVertexCount = vertexCount; - info.fIndexCount = 0; - - info.fInstanceCount = 0; - info.fVerticesPerInstance = 0; - info.fIndicesPerInstance = 0; - - if (devBounds) { - info.setDevBounds(*devBounds); - } - - GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, - this); - if (pipelineInfo.mustSkipDraw()) { - return; - } - - this->setDrawBuffers(&info, gp->getVertexStride()); - - this->onDraw(gp, info, pipelineInfo); - } -} - - void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch, const SkRect* devBounds) { @@ -750,126 +341,6 @@ void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { //////////////////////////////////////////////////////////////////////////////// -void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder, - const GrGeometryProcessor* gp, - GrPrimitiveType type, - int instanceCount, - int verticesPerInstance, - int indicesPerInstance, - const SkRect* devBounds) { - SkASSERT(pipelineBuilder); - - if (!verticesPerInstance || !indicesPerInstance) { - return; - } - - int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance; - if (!maxInstancesPerDraw) { - return; - } - - // Setup clip - GrScissorState scissorState; - GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; - GrPipelineBuilder::AutoRestoreStencil ars; - if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) { - return; - } - - DrawInfo info; - info.fPrimitiveType = type; - info.fStartIndex = 0; - info.fStartVertex = 0; - info.fIndicesPerInstance = indicesPerInstance; - info.fVerticesPerInstance = verticesPerInstance; - - // Set the same bounds for all the draws. - if (devBounds) { - info.setDevBounds(*devBounds); - } - - while (instanceCount) { - info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); - info.fVertexCount = info.fInstanceCount * verticesPerInstance; - info.fIndexCount = info.fInstanceCount * indicesPerInstance; - - if (this->checkDraw(*pipelineBuilder, - gp, - type, - info.fStartVertex, - info.fStartIndex, - info.fVertexCount, - info.fIndexCount)) { - - GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, - this); - if (pipelineInfo.mustSkipDraw()) { - return; - } - - this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(gp, info, pipelineInfo); - } - info.fStartVertex += info.fVertexCount; - instanceCount -= info.fInstanceCount; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( - GrDrawTarget* target, - int vertexCount, - size_t vertexStride, - int indexCount) { - fTarget = NULL; - this->set(target, vertexCount, vertexStride, indexCount); -} - -GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { - fTarget = NULL; -} - -GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { - this->reset(); -} - -bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, - int vertexCount, - size_t vertexStride, - int indexCount) { - this->reset(); - fTarget = target; - bool success = true; - if (fTarget) { - success = target->reserveVertexAndIndexSpace(vertexCount, - vertexStride, - indexCount, - &fVertices, - &fIndices); - if (!success) { - fTarget = NULL; - this->reset(); - } - } - SkASSERT(success == SkToBool(fTarget)); - return success; -} - -void GrDrawTarget::AutoReleaseGeometry::reset() { - if (fTarget) { - if (fVertices) { - fTarget->resetVertexSource(); - } - if (fIndices) { - fTarget->resetIndexSource(); - } - fTarget = NULL; - } - fVertices = NULL; - fIndices = NULL; -} - namespace { // returns true if the read/written rect intersects the src/dst and false if not. bool clip_srcrect_and_dstpoint(const GrSurface* dst, diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 1d07b9eec2..8706702866 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -31,7 +31,6 @@ class GrBatch; class GrClip; class GrDrawTargetCaps; -class GrGeometryProcessor; class GrPath; class GrPathRange; class GrPipeline; @@ -48,205 +47,13 @@ public: // The context may not be fully constructed and should not be used during GrDrawTarget // construction. GrDrawTarget(GrContext* context); - virtual ~GrDrawTarget(); + virtual ~GrDrawTarget() {} /** * Gets the capabilities of the draw target. */ const GrDrawTargetCaps* caps() const { return fCaps.get(); } - /** - * There are two types of "sources" of geometry (vertices and indices) for - * draw calls made on the target. When performing an indexed draw, the - * indices and vertices can use different source types. Once a source is - * specified it can be used for multiple draws. However, the time at which - * the geometry data is no longer editable depends on the source type. - * - * Sometimes it is necessary to perform a draw while upstack code has - * already specified geometry that it isn't finished with. So there are push - * and pop methods. This allows the client to push the sources, draw - * something using alternate sources, and then pop to restore the original - * sources. - * - * Aside from pushes and pops, a source remains valid until another source - * is set or resetVertexSource / resetIndexSource is called. Drawing from - * a reset source is an error. - * - * The two types of sources are: - * - * 1. Reserve. This is most useful when the caller has data it must - * transform before drawing and is not long-lived. The caller requests - * that the draw target make room for some amount of vertex and/or index - * data. The target provides ptrs to hold the vertex and/or index data. - * - * The data is writable up until the next drawIndexed, drawNonIndexed, - * drawIndexedInstances, drawRect, copySurface, or pushGeometrySource. At - * this point the data is frozen and the ptrs are no longer valid. - * - * Where the space is allocated and how it is uploaded to the GPU is - * subclass-dependent. - * - * 2. Vertex and Index Buffers. This is most useful for geometry that will - * is long-lived. When the data in the buffer is consumed depends on the - * GrDrawTarget subclass. For deferred subclasses the caller has to - * guarantee that the data is still available in the buffers at playback. - * (TODO: Make this more automatic as we have done for read/write pixels) - */ - - /** - * Reserves space for vertices and/or indices. Zero can be specifed as - * either the vertex or index count if the caller desires to only reserve - * space for only indices or only vertices. If zero is specifed for - * vertexCount then the vertex source will be unmodified and likewise for - * indexCount. - * - * If the function returns true then the reserve suceeded and the vertices - * and indices pointers will point to the space created. - * - * If the target cannot make space for the request then this function will - * return false. If vertexCount was non-zero then upon failure the vertex - * source is reset and likewise for indexCount. - * - * The pointers to the space allocated for vertices and indices remain valid - * until a drawIndexed, drawNonIndexed, drawIndexedInstances, drawRect, - * copySurface, or push/popGeomtrySource is called. At that point logically a - * snapshot of the data is made and the pointers are invalid. - * - * @param vertexCount the number of vertices to reserve space for. Can be - * 0. Vertex size is queried from the current GrPipelineBuilder. - * @param indexCount the number of indices to reserve space for. Can be 0. - * @param vertices will point to reserved vertex space if vertexCount is - * non-zero. Illegal to pass NULL if vertexCount > 0. - * @param indices will point to reserved index space if indexCount is - * non-zero. Illegal to pass NULL if indexCount > 0. - */ - bool reserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount, - void** vertices, - void** indices); - - /** - * Provides hints to caller about the number of vertices and indices - * that can be allocated cheaply. This can be useful if caller is reserving - * space but doesn't know exactly how much geometry is needed. - * - * Also may hint whether the draw target should be flushed first. This is - * useful for deferred targets. - * - * @param vertexCount in: hint about how many vertices the caller would - * like to allocate. Vertex size is queried from the - * current GrPipelineBuilder. - * out: a hint about the number of vertices that can be - * allocated cheaply. Negative means no hint. - * Ignored if NULL. - * @param indexCount in: hint about how many indices the caller would - * like to allocate. - * out: a hint about the number of indices that can be - * allocated cheaply. Negative means no hint. - * Ignored if NULL. - * - * @return true if target should be flushed based on the input values. - */ - virtual bool geometryHints(size_t vertexStride, int* vertexCount, int* indexCount) const; - - /** - * Sets source of vertex data for the next draw. Data does not have to be - * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances. - * - * @param buffer vertex buffer containing vertex data. Must be - * unlocked before draw call. Vertex size is queried - * from current GrPipelineBuilder. - */ - void setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride); - - /** - * Sets source of index data for the next indexed draw. Data does not have - * to be in the buffer until drawIndexed. - * - * @param buffer index buffer containing indices. Must be unlocked - * before indexed draw call. - */ - void setIndexSourceToBuffer(const GrIndexBuffer* buffer); - - /** - * Resets vertex source. Drawing from reset vertices is illegal. Set vertex - * source to reserved, array, or buffer before next draw. May be able to free - * up temporary storage allocated by setVertexSourceToArray or - * reserveVertexSpace. - */ - void resetVertexSource(); - - /** - * Resets index source. Indexed Drawing from reset indices is illegal. Set - * index source to reserved, array, or buffer before next indexed draw. May - * be able to free up temporary storage allocated by setIndexSourceToArray - * or reserveIndexSpace. - */ - void resetIndexSource(); - - /** - * Query to find out if the vertex or index source is reserved. - */ - bool hasReservedVerticesOrIndices() const { - return kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc || - kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; - } - - /** - * Pushes and resets the vertex/index sources. Any reserved vertex / index - * data is finalized (i.e. cannot be updated after the matching pop but can - * be drawn from). Must be balanced by a pop. - */ - void pushGeometrySource(); - - /** - * Pops the vertex / index sources from the matching push. - */ - void popGeometrySource(); - - /** - * Draws indexed geometry using the current state and current vertex / index - * sources. - * - * @param type The type of primitives to draw. - * @param startVertex the vertex in the vertex array/buffer corresponding - * to index 0 - * @param startIndex first index to read from index src. - * @param vertexCount one greater than the max index. - * @param indexCount the number of index elements to read. The index count - * is effectively trimmed to the last completely - * specified primitive. - * @param devBounds optional bounds hint. This is a promise from the caller, - * not a request for clipping. - */ - void drawIndexed(GrPipelineBuilder*, - const GrGeometryProcessor*, - GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount, - const SkRect* devBounds = NULL); - - /** - * Draws non-indexed geometry using the current state and current vertex - * sources. - * - * @param type The type of primitives to draw. - * @param startVertex the vertex in the vertex array/buffer corresponding - * to index 0 - * @param vertexCount one greater than the max index. - * @param devBounds optional bounds hint. This is a promise from the caller, - * not a request for clipping. - */ - void drawNonIndexed(GrPipelineBuilder*, - const GrGeometryProcessor*, - GrPrimitiveType type, - int startVertex, - int vertexCount, - const SkRect* devBounds = NULL); - // TODO devbounds should live on the batch void drawBatch(GrPipelineBuilder*, GrBatch*, const SkRect* devBounds = NULL); @@ -290,8 +97,7 @@ public: GrPathRendering::FillType fill); /** - * Helper function for drawing rects. It performs a geometry src push and pop - * and thus will finalize any reserved geometry. + * Helper function for drawing rects. * * @param rect the rect to draw * @param localRect optional rect that specifies local coords to map onto @@ -323,43 +129,6 @@ public: this->drawRect(ds, color, viewM, rect, NULL, NULL); } - /** - * This call is used to draw multiple instances of some geometry with a - * given number of vertices (V) and indices (I) per-instance. The indices in - * the index source must have the form i[k+I] == i[k] + V. Also, all indices - * i[kI] ... i[(k+1)I-1] must be elements of the range kV ... (k+1)V-1. As a - * concrete example, the following index buffer for drawing a series of - * quads each as two triangles each satisfies these conditions with V=4 and - * I=6: - * (0,1,2,0,2,3, 4,5,6,4,6,7, 8,9,10,8,10,11, ...) - * - * The call assumes that the pattern of indices fills the entire index - * source. The size of the index buffer limits the number of instances that - * can be drawn by the GPU in a single draw. However, the caller may specify - * any (positive) number for instanceCount and if necessary multiple GPU - * draws will be issued. Moreover, when drawIndexedInstances is called - * multiple times it may be possible for GrDrawTarget to group them into a - * single GPU draw. - * - * @param type the type of primitives to draw - * @param instanceCount the number of instances to draw. Each instance - * consists of verticesPerInstance vertices indexed by - * indicesPerInstance indices drawn as the primitive - * type specified by type. - * @param verticesPerInstance The number of vertices in each instance (V - * in the above description). - * @param indicesPerInstance The number of indices in each instance (I - * in the above description). - * @param devBounds optional bounds hint. This is a promise from the caller, - * not a request for clipping. - */ - void drawIndexedInstances(GrPipelineBuilder*, - const GrGeometryProcessor*, - GrPrimitiveType type, - int instanceCount, - int verticesPerInstance, - int indicesPerInstance, - const SkRect* devBounds = NULL); /** * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole @@ -425,55 +194,6 @@ public: */ virtual void purgeResources() {}; - //////////////////////////////////////////////////////////////////////////// - - class AutoReleaseGeometry : public ::SkNoncopyable { - public: - AutoReleaseGeometry(GrDrawTarget* target, - int vertexCount, - size_t vertexStride, - int indexCount); - AutoReleaseGeometry(); - ~AutoReleaseGeometry(); - bool set(GrDrawTarget* target, - int vertexCount, - size_t vertexStride, - int indexCount); - bool succeeded() const { return SkToBool(fTarget); } - void* vertices() const { SkASSERT(this->succeeded()); return fVertices; } - void* indices() const { SkASSERT(this->succeeded()); return fIndices; } - SkPoint* positions() const { - return static_cast<SkPoint*>(this->vertices()); - } - - private: - void reset(); - - GrDrawTarget* fTarget; - void* fVertices; - void* fIndices; - }; - - //////////////////////////////////////////////////////////////////////////// - - /** - * Saves the geometry src state at construction and restores in the destructor. It also saves - * and then restores the vertex attrib state. - */ - class AutoGeometryPush : public ::SkNoncopyable { - public: - AutoGeometryPush(GrDrawTarget* target) { - SkASSERT(target); - fTarget = target; - target->pushGeometrySource(); - } - - ~AutoGeometryPush() { fTarget->popGeometrySource(); } - - private: - GrDrawTarget* fTarget; - }; - /////////////////////////////////////////////////////////////////////////// // Draw execution tracking (for font atlases and other resources) class DrawToken { @@ -528,10 +248,16 @@ public: // adds or remove instances void adjustInstanceCount(int instanceOffset); // shifts the start vertex - void adjustStartVertex(int vertexOffset); + void adjustStartVertex(int vertexOffset) { + fStartVertex += vertexOffset; + SkASSERT(fStartVertex >= 0); + } // shifts the start index - void adjustStartIndex(int indexOffset); - + void adjustStartIndex(int indexOffset) { + SkASSERT(this->isIndexed()); + fStartIndex += indexOffset; + SkASSERT(fStartIndex >= 0); + } void setDevBounds(const SkRect& bounds) { fDevBoundsStorage = bounds; fDevBounds = &fDevBoundsStorage; @@ -567,73 +293,14 @@ public: GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer; }; - /** - * Used to populate the vertex and index buffer on the draw info before onDraw is called. - */ - virtual void setDrawBuffers(DrawInfo*, size_t vertexStride) = 0; bool programUnitTest(int maxStages); protected: friend class GrTargetCommands; // for PipelineInfo - enum GeometrySrcType { - kNone_GeometrySrcType, //<! src has not been specified - kReserved_GeometrySrcType, //<! src was set using reserve*Space - kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer - }; - - struct GeometrySrcState { - GeometrySrcType fVertexSrc; - union { - // valid if src type is buffer - const GrVertexBuffer* fVertexBuffer; - // valid if src type is reserved or array - int fVertexCount; - }; - - GeometrySrcType fIndexSrc; - union { - // valid if src type is buffer - const GrIndexBuffer* fIndexBuffer; - // valid if src type is reserved or array - int fIndexCount; - }; - - size_t fVertexSize; - }; - - int indexCountInCurrentSource() const { - const GeometrySrcState& src = this->getGeomSrc(); - switch (src.fIndexSrc) { - case kNone_GeometrySrcType: - return 0; - case kReserved_GeometrySrcType: - return src.fIndexCount; - case kBuffer_GeometrySrcType: - return static_cast<int>(src.fIndexBuffer->gpuMemorySize() / sizeof(uint16_t)); - default: - SkFAIL("Unexpected Index Source."); - return 0; - } - } - GrContext* getContext() { return fContext; } const GrContext* getContext() const { return fContext; } - // subclasses must call this in their destructors to ensure all vertex - // and index sources have been released (including those held by - // pushGeometrySource()) - void releaseGeometry(); - - // accessors for derived classes - const GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); } - // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert. - size_t getVertexSize() const { - // the vertex layout is only valid if a vertex source has been specified. - SkASSERT(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType); - return this->getGeomSrc().fVertexSize; - } - // Subclass must initialize this in its constructor. SkAutoTUnref<const GrDrawTargetCaps> fCaps; @@ -674,12 +341,6 @@ protected: void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline); - // A subclass can optionally overload this function to be notified before - // vertex and index space is reserved. - virtual void willReserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount) {} - private: /** * This will be called before allocating a texture as a dst for copySurface. This function @@ -700,17 +361,6 @@ private: const SkIRect& clippedSrcRect, const SkIPoint& clippedDstRect); - // implemented by subclass to allocate space for reserved geom - virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0; - virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0; - // implemented by subclass to handle release of reserved geom space - virtual void releaseReservedVertexSpace() = 0; - virtual void releaseReservedIndexSpace() = 0; - // subclass overrides to be notified just before geo src state is pushed/popped. - virtual void geometrySourceWillPush() = 0; - virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; - // subclass called to perform drawing - virtual void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) = 0; virtual void onDrawBatch(GrBatch*, const PipelineInfo&) = 0; // TODO copy in order drawbuffer onDrawRect to here virtual void onDrawRect(GrPipelineBuilder*, @@ -766,25 +416,6 @@ private: */ virtual bool onInitCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* dstDesc) = 0; - // helpers for reserving vertex and index space. - bool reserveVertexSpace(size_t vertexSize, - int vertexCount, - void** vertices); - bool reserveIndexSpace(int indexCount, void** indices); - - // called by drawIndexed and drawNonIndexed. Use a negative indexCount to - // indicate non-indexed drawing. - bool checkDraw(const GrPipelineBuilder&, - const GrGeometryProcessor*, - GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) const; - // called when setting a new vert/idx source to unref prev vb/ib - void releasePreviousVertexSource(); - void releasePreviousIndexSource(); - // Check to see if this set of draw commands has been sent out virtual bool isIssued(uint32_t drawID) { return true; } void getPathStencilSettingsForFilltype(GrPathRendering::FillType, @@ -797,10 +428,6 @@ private: GrScissorState*, const SkRect* devBounds) = 0; - enum { - kPreallocGeoSrcStateStackCnt = 4, - }; - SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack; // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget. GrContext* fContext; // To keep track that we always have at least as many debug marker adds as removes diff --git a/src/gpu/GrFlushToGpuDrawTarget.cpp b/src/gpu/GrFlushToGpuDrawTarget.cpp index 1ccb25d881..416051d549 100644 --- a/src/gpu/GrFlushToGpuDrawTarget.cpp +++ b/src/gpu/GrFlushToGpuDrawTarget.cpp @@ -24,52 +24,9 @@ GrFlushToGpuDrawTarget::GrFlushToGpuDrawTarget(GrGpu* gpu, SkASSERT(vertexPool); SkASSERT(indexPool); - GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); - poolState.fUsedPoolVertexBytes = 0; - poolState.fUsedPoolIndexBytes = 0; -#ifdef SK_DEBUG - poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; - poolState.fPoolStartVertex = ~0; - poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; - poolState.fPoolStartIndex = ~0; -#endif -} - -GrFlushToGpuDrawTarget::~GrFlushToGpuDrawTarget() { - // This must be called by before the GrDrawTarget destructor - this->releaseGeometry(); -} - -void GrFlushToGpuDrawTarget::setDrawBuffers(DrawInfo* info, size_t vertexStride) { - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { - info->setVertexBuffer(this->getGeomSrc().fVertexBuffer); - } else { - // Update the bytes used since the last reserve-geom request. - size_t bytes = (info->vertexCount() + info->startVertex()) * vertexStride; - poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes); - info->setVertexBuffer(poolState.fPoolVertexBuffer); - info->adjustStartVertex(poolState.fPoolStartVertex); - } - - if (info->isIndexed()) { - if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { - info->setIndexBuffer(this->getGeomSrc().fIndexBuffer); - } else { - // Update the bytes used since the last reserve-geom request. - size_t bytes = (info->indexCount() + info->startIndex()) * sizeof(uint16_t); - poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes); - info->setIndexBuffer(poolState.fPoolIndexBuffer); - info->adjustStartIndex(poolState.fPoolStartIndex); - } - } } void GrFlushToGpuDrawTarget::reset() { - SkASSERT(1 == fGeoPoolStateStack.count()); - this->resetVertexSource(); - this->resetIndexSource(); - fVertexPool->reset(); fIndexPool->reset(); @@ -77,9 +34,6 @@ void GrFlushToGpuDrawTarget::reset() { } void GrFlushToGpuDrawTarget::flush() { - SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); - SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); - if (fFlushing) { return; } @@ -95,156 +49,6 @@ void GrFlushToGpuDrawTarget::flush() { this->reset(); } -void GrFlushToGpuDrawTarget::willReserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount) { - // We use geometryHints() to know whether to flush the draw buffer. We - // can't flush if we are inside an unbalanced pushGeometrySource. - // Moreover, flushing blows away vertex and index data that was - // previously reserved. So if the vertex or index data is pulled from - // reserved space and won't be released by this request then we can't - // flush. - bool insideGeoPush = fGeoPoolStateStack.count() > 1; - - bool unreleasedVertexSpace = - !vertexCount && - kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; - - bool unreleasedIndexSpace = - !indexCount && - kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; - - int vcount = vertexCount; - int icount = indexCount; - - if (!insideGeoPush && - !unreleasedVertexSpace && - !unreleasedIndexSpace && - this->geometryHints(vertexStride, &vcount, &icount)) { - this->flush(); - } -} - -bool GrFlushToGpuDrawTarget::geometryHints(size_t vertexStride, - int* vertexCount, - int* indexCount) const { - // we will recommend a flush if the data could fit in a single - // preallocated buffer but none are left and it can't fit - // in the current buffer (which may not be prealloced). - bool flush = false; - if (indexCount) { - int32_t currIndices = fIndexPool->currentBufferIndices(); - if (*indexCount > currIndices && - (!fIndexPool->preallocatedBuffersRemaining() && - *indexCount <= fIndexPool->preallocatedBufferIndices())) { - - flush = true; - } - *indexCount = currIndices; - } - if (vertexCount) { - int32_t currVertices = fVertexPool->currentBufferVertices(vertexStride); - if (*vertexCount > currVertices && - (!fVertexPool->preallocatedBuffersRemaining() && - *vertexCount <= fVertexPool->preallocatedBufferVertices(vertexStride))) { - - flush = true; - } - *vertexCount = currVertices; - } - return flush; -} - -bool GrFlushToGpuDrawTarget::onReserveVertexSpace(size_t vertexSize, - int vertexCount, - void** vertices) { - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - SkASSERT(vertexCount > 0); - SkASSERT(vertices); - SkASSERT(0 == poolState.fUsedPoolVertexBytes); - - *vertices = fVertexPool->makeSpace(vertexSize, - vertexCount, - &poolState.fPoolVertexBuffer, - &poolState.fPoolStartVertex); - return SkToBool(*vertices); -} - -bool GrFlushToGpuDrawTarget::onReserveIndexSpace(int indexCount, void** indices) { - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - SkASSERT(indexCount > 0); - SkASSERT(indices); - SkASSERT(0 == poolState.fUsedPoolIndexBytes); - - *indices = fIndexPool->makeSpace(indexCount, - &poolState.fPoolIndexBuffer, - &poolState.fPoolStartIndex); - return SkToBool(*indices); -} - -void GrFlushToGpuDrawTarget::releaseReservedVertexSpace() { - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - const GeometrySrcState& geoSrc = this->getGeomSrc(); - - // If we get a release vertex space call then our current source should either be reserved - // or array (which we copied into reserved space). - SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc); - - // When the caller reserved vertex buffer space we gave it back a pointer - // provided by the vertex buffer pool. At each draw we tracked the largest - // offset into the pool's pointer that was referenced. Now we return to the - // pool any portion at the tail of the allocation that no draw referenced. - size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount; - fVertexPool->putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes); - poolState.fUsedPoolVertexBytes = 0; - poolState.fPoolVertexBuffer = NULL; - poolState.fPoolStartVertex = 0; -} - -void GrFlushToGpuDrawTarget::releaseReservedIndexSpace() { - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - const GeometrySrcState& geoSrc = this->getGeomSrc(); - - // If we get a release index space call then our current source should either be reserved - // or array (which we copied into reserved space). - SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc); - - // Similar to releaseReservedVertexSpace we return any unused portion at - // the tail - size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; - fIndexPool->putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); - poolState.fUsedPoolIndexBytes = 0; - poolState.fPoolIndexBuffer = NULL; - poolState.fPoolStartIndex = 0; -} - -void GrFlushToGpuDrawTarget::geometrySourceWillPush() { - GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); - poolState.fUsedPoolVertexBytes = 0; - poolState.fUsedPoolIndexBytes = 0; -#ifdef SK_DEBUG - poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; - poolState.fPoolStartVertex = ~0; - poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; - poolState.fPoolStartIndex = ~0; -#endif -} - -void GrFlushToGpuDrawTarget::geometrySourceWillPop(const GeometrySrcState& restoredState) { - SkASSERT(fGeoPoolStateStack.count() > 1); - fGeoPoolStateStack.pop_back(); - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - // we have to assume that any slack we had in our vertex/index data - // is now unreleasable because data may have been appended later in the - // pool. - if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { - poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount; - } - if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { - poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexCount; - } -} - bool GrFlushToGpuDrawTarget::onCanCopySurface(const GrSurface* dst, const GrSurface* src, const SkIRect& srcRect, diff --git a/src/gpu/GrFlushToGpuDrawTarget.h b/src/gpu/GrFlushToGpuDrawTarget.h index fa0ff4aa9c..b379f2e0a7 100644 --- a/src/gpu/GrFlushToGpuDrawTarget.h +++ b/src/gpu/GrFlushToGpuDrawTarget.h @@ -24,8 +24,6 @@ class GrFlushToGpuDrawTarget : public GrClipTarget { public: GrFlushToGpuDrawTarget(GrGpu*, GrVertexBufferAllocPool*,GrIndexBufferAllocPool*); - ~GrFlushToGpuDrawTarget() override; - /** * Empties the draw buffer of any queued up draws. This must not be called while inside an * unbalanced pushGeometrySource(). @@ -40,8 +38,6 @@ public: */ void flush(); - bool geometryHints(size_t vertexStride, int* vertexCount, int* indexCount) const override; - protected: GrGpu* getGpu() { return fGpu; } const GrGpu* getGpu() const{ return fGpu; } @@ -49,49 +45,17 @@ protected: GrVertexBufferAllocPool* getVertexAllocPool() { return fVertexPool; } GrIndexBufferAllocPool* getIndexAllocPool() { return fIndexPool; } - // TODO all of this goes away when batch is everywhere - enum { - kGeoPoolStatePreAllocCnt = 4, - }; - - struct GeometryPoolState { - const GrVertexBuffer* fPoolVertexBuffer; - int fPoolStartVertex; - const GrIndexBuffer* fPoolIndexBuffer; - int fPoolStartIndex; - // caller may conservatively over reserve vertices / indices. - // we release unused space back to allocator if possible - // can only do this if there isn't an intervening pushGeometrySource() - size_t fUsedPoolVertexBytes; - size_t fUsedPoolIndexBytes; - }; - - typedef SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> GeoPoolStateStack; - const GeoPoolStateStack& getGeoPoolStateStack() const { return fGeoPoolStateStack; } - - void willReserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount) override; - private: virtual void onReset() = 0; virtual void onFlush() = 0; - void setDrawBuffers(DrawInfo*, size_t stride) override; - bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) override; - bool onReserveIndexSpace(int indexCount, void** indices) override; - void releaseReservedVertexSpace() override; - void releaseReservedIndexSpace() override; - void geometrySourceWillPush() override; - void geometrySourceWillPop(const GeometrySrcState& restoredState) override; bool onCanCopySurface(const GrSurface* dst, const GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; bool onInitCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override; - GeoPoolStateStack fGeoPoolStateStack; SkAutoTUnref<GrGpu> fGpu; GrVertexBufferAllocPool* fVertexPool; GrIndexBufferAllocPool* fIndexPool; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index aaf3fd3f0e..82c8840c22 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -297,13 +297,6 @@ void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder, this->drawBatch(pipelineBuilder, batch, &bounds); } -void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp, - const DrawInfo& info, - const PipelineInfo& pipelineInfo) { - GrTargetCommands::Cmd* cmd = fCommands.recordDraw(this, gp, info, pipelineInfo); - this->recordTraceMarkersIfNecessary(cmd); -} - void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, const PipelineInfo& pipelineInfo) { GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipelineInfo); @@ -407,13 +400,3 @@ void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c } } } - -void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount) { -#ifndef USE_BITMAP_TEXTBLOBS - fCommands.closeBatch(); -#endif - - this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount); -} diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index ac1b79cd55..11558f8ffc 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -50,10 +50,6 @@ public: void discard(GrRenderTarget*) override; protected: - void willReserveVertexAndIndexSpace(int vertexCount, - size_t vertexStride, - int indexCount) override; - void appendIndicesAndTransforms(const void* indexValues, PathIndexType indexType, const float* transformValues, PathTransformType transformType, int count, char** indicesLocation, float** xformsLocation) { @@ -74,21 +70,6 @@ protected: } } - bool canConcatToIndexBuffer(const GrIndexBuffer** ib) { - const GrDrawTarget::GeometrySrcState& geomSrc = this->getGeomSrc(); - - // we only attempt to concat 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 false; - } - - *ib = geomSrc.fIndexBuffer; - return true; - } - private: friend class GrTargetCommands; @@ -96,7 +77,6 @@ private: void onFlush() override; // overrides from GrDrawTarget - void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) override; void onDrawBatch(GrBatch*, const PipelineInfo&) override; void onDrawRect(GrPipelineBuilder*, GrColor, @@ -132,10 +112,6 @@ private: const SkIRect& srcRect, const SkIPoint& dstPoint) override; - // Attempts to concat instances from info onto the previous draw. info must represent an - // instanced draw. The caller must have already recorded a new draw state and clip if necessary. - int concatInstancedDraw(const DrawInfo&); - // We lazily record clip changes in order to skip clips that have no effect. void recordClipIfNecessary(); // Records any trace markers for a command diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index d22b4628bb..fe15532b75 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -16,6 +16,7 @@ #include "GrInvariantOutput.h" #include "GrPipelineBuilder.h" #include "GrProcessor.h" +#include "GrVertexBuffer.h" #include "SkRRect.h" #include "SkStrokeRec.h" #include "SkTLazy.h" diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 0cc3de7a5e..34a1af1b52 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -9,6 +9,7 @@ #include "GrSoftwarePathRenderer.h" #include "GrContext.h" #include "GrSWMaskHelper.h" +#include "GrVertexBuffer.h" //////////////////////////////////////////////////////////////////////////////// bool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*, diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp index d3c924d368..69ef53bd45 100644 --- a/src/gpu/GrTargetCommands.cpp +++ b/src/gpu/GrTargetCommands.cpp @@ -13,15 +13,6 @@ #include "GrTemplates.h" #include "SkPoint.h" -void GrTargetCommands::closeBatch() { - if (fDrawBatch) { - fBatchTarget.resetNumberOfDraws(); - fDrawBatch->execute(NULL, fPrevState); - fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); - fDrawBatch = NULL; - } -} - static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) { static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face; bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); @@ -35,79 +26,6 @@ static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin return isWinding; } -int GrTargetCommands::concatInstancedDraw(GrInOrderDrawBuffer* iodb, - const GrDrawTarget::DrawInfo& info) { - SkASSERT(!fCmdBuffer.empty()); - SkASSERT(info.isInstanced()); - - const GrIndexBuffer* ib; - if (!iodb->canConcatToIndexBuffer(&ib)) { - 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 (Cmd::kDraw_CmdType != fCmdBuffer.back().type()) { - return 0; - } - - Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); - - if (!draw->fInfo.isInstanced() || - draw->fInfo.primitiveType() != info.primitiveType() || - draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || - draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || - draw->fInfo.vertexBuffer() != info.vertexBuffer() || - draw->fInfo.indexBuffer() != ib) { - return 0; - } - if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) { - return 0; - } - - // how many instances can be concat'ed onto draw given the size of the index buffer - int instancesToConcat = iodb->indexCountInCurrentSource() / info.indicesPerInstance(); - instancesToConcat -= draw->fInfo.instanceCount(); - instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); - - draw->fInfo.adjustInstanceCount(instancesToConcat); - - // update last fGpuCmdMarkers to include any additional trace markers that have been added - iodb->recordTraceMarkersIfNecessary(draw); - return instancesToConcat; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordDraw( - GrInOrderDrawBuffer* iodb, - const GrGeometryProcessor* gp, - const GrDrawTarget::DrawInfo& info, - const GrDrawTarget::PipelineInfo& pipelineInfo) { -#ifdef USE_BITMAP_TEXTBLOBS - SkFAIL("Non-batch no longer supported\n"); -#endif - SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); - CLOSE_BATCH - - if (!this->setupPipelineAndShouldDraw(iodb, gp, pipelineInfo)) { - return NULL; - } - - Draw* draw; - if (info.isInstanced()) { - int instancesConcated = this->concatInstancedDraw(iodb, info); - if (info.instanceCount() > instancesConcated) { - draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); - draw->fInfo.adjustInstanceCount(-instancesConcated); - } else { - return NULL; - } - } else { - draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); - } - - return draw; -} - GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( GrInOrderDrawBuffer* iodb, GrBatch* batch, @@ -124,7 +42,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( SkASSERT(&fCmdBuffer.back() == fDrawBatch); if (!fDrawBatch->fBatch->combineIfPossible(batch)) { - CLOSE_BATCH fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget)); } @@ -138,8 +55,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( const GrPath* path, const GrScissorState& scissorState, const GrStencilSettings& stencilSettings) { - CLOSE_BATCH - StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path, pipelineBuilder.getRenderTarget())); @@ -156,8 +71,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( const GrPath* path, const GrStencilSettings& stencilSettings, const GrDrawTarget::PipelineInfo& pipelineInfo) { - CLOSE_BATCH - // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering? if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { return NULL; @@ -181,7 +94,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( SkASSERT(pathRange); SkASSERT(indexValues); SkASSERT(transformValues); - CLOSE_BATCH if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { return NULL; @@ -237,7 +149,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb, bool canIgnoreRect, GrRenderTarget* renderTarget) { SkASSERT(renderTarget); - CLOSE_BATCH SkIRect r; if (NULL == rect) { @@ -260,7 +171,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf bool insideClip, GrRenderTarget* renderTarget) { SkASSERT(renderTarget); - CLOSE_BATCH ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget)); clr->fRect = rect; @@ -271,7 +181,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb, GrRenderTarget* renderTarget) { SkASSERT(renderTarget); - CLOSE_BATCH Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); clr->fColor = GrColor_ILLEGAL; @@ -289,9 +198,6 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { return; } - // TODO this is temporary while batch is being rolled out - CLOSE_BATCH - // Updated every time we find a set state cmd to reflect the current state in the playback // stream. SetState* currentState = NULL; @@ -441,7 +347,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer* const SkIRect& srcRect, const SkIPoint& dstPoint) { if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) { - CLOSE_BATCH CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src)); cs->fSrcRect = srcRect; cs->fDstPoint = dstPoint; @@ -494,7 +399,6 @@ bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { fCmdBuffer.pop_back(); } else { - CLOSE_BATCH fPrevState = ss; iodb->recordTraceMarkersIfNecessary(ss); } diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp index cc6e2a2609..e00792e5f8 100644 --- a/src/gpu/GrTessellatingPathRenderer.cpp +++ b/src/gpu/GrTessellatingPathRenderer.cpp @@ -11,6 +11,7 @@ #include "GrBatchTarget.h" #include "GrDefaultGeoProcFactory.h" #include "GrPathUtils.h" +#include "GrVertexBuffer.h" #include "SkChunkAlloc.h" #include "SkGeometry.h" diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp index 44be4bfe97..3c5d3dd790 100644 --- a/src/gpu/GrTest.cpp +++ b/src/gpu/GrTest.cpp @@ -18,8 +18,6 @@ void GrTestTarget::init(GrContext* ctx, GrDrawTarget* target) { fContext.reset(SkRef(ctx)); fDrawTarget.reset(SkRef(target)); - - SkNEW_IN_TLAZY(&fAGP, GrDrawTarget::AutoGeometryPush, (target)); } void GrContext::getTestTarget(GrTestTarget* tar) { diff --git a/src/gpu/GrTest.h b/src/gpu/GrTest.h index 47122c598f..cf9a53ec77 100644 --- a/src/gpu/GrTest.h +++ b/src/gpu/GrTest.h @@ -24,8 +24,6 @@ public: GrDrawTarget* target() { return fDrawTarget.get(); } private: - SkTLazy<GrDrawTarget::AutoGeometryPush> fAGP; - SkAutoTUnref<GrDrawTarget> fDrawTarget; SkAutoTUnref<GrContext> fContext; }; diff --git a/src/gpu/GrTestBatch.h b/src/gpu/GrTestBatch.h index 716912dc76..8e16f52946 100644 --- a/src/gpu/GrTestBatch.h +++ b/src/gpu/GrTestBatch.h @@ -9,6 +9,7 @@ #define GrTestBatch_DEFINED #include "GrBatch.h" +#include "GrVertexBuffer.h" /* * A simple batch only for testing purposes which actually doesn't batch at all, but can fit into diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index b6dbbd6e0e..0a9be3c311 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -19,6 +19,7 @@ #include "GrInvariantOutput.h" #include "GrProcessor.h" #include "GrStrokeInfo.h" +#include "GrVertexBuffer.h" #include "SkGr.h" #include "gl/GrGLGeometryProcessor.h" #include "gl/GrGLProcessor.h" |