void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch) { SkASSERT(pipelineBuilder); // TODO some kind of checkdraw, but not at this level // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreStencil ars; if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, &batch->bounds())) { return; } // Batch bounds are tight, so for dev copies // TODO move this into setupDstReadIfNecessary when paths are in batch SkRect bounds = batch->bounds(); bounds.outset(0.5f, 0.5f); GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, batch, &bounds, this); if (pipelineInfo.mustSkipDraw()) { return; } this->onDrawBatch(batch, pipelineInfo); }
void GrDrawTarget::drawPath(const GrPipelineBuilder& pipelineBuilder, const GrPathProcessor* pathProc, const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path rendering. SkASSERT(path); SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); SkRect devBounds = path->getBounds(); pathProc->viewMatrix().mapRect(&devBounds); // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; GrPipelineBuilder::AutoRestoreStencil ars; if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &devBounds)) { return; } // set stencil settings for path GrStencilSettings stencilSettings; GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds, this); if (pipelineInfo.mustSkipDraw()) { return; } this->onDrawPath(pathProc, path, stencilSettings, pipelineInfo); }
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) { // TODO some kind of checkdraw, but not at this level // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; GrPipelineBuilder::AutoRestoreStencil ars; if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) { return; } // Batch bounds are tight, so for dev copies // TODO move this into setupDstReadIfNecessary when paths are in batch SkRect bounds = batch->bounds(); bounds.outset(0.5f, 0.5f); GrDrawTarget::PipelineInfo pipelineInfo(&pipelineBuilder, &scissorState, batch, &bounds, this); if (!pipelineInfo.valid()) { return; } if (!batch->installPipeline(pipelineInfo.pipelineCreateArgs())) { return; } this->onDrawBatch(batch); }
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::drawPaths(GrPipelineBuilder* pipelineBuilder, const GrPathProcessor* pathProc, const GrPathRange* pathRange, const void* indices, PathIndexType indexType, const float transformValues[], PathTransformType transformType, int count, GrPathRendering::FillType fill) { SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); SkASSERT(pathRange); SkASSERT(indices); SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType)); SkASSERT(transformValues); SkASSERT(pipelineBuilder); // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreStencil ars; if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, NULL)) { return; } // set stencil settings for path GrStencilSettings stencilSettings; GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); // Don't compute a bounding box for dst copy texture, we'll opt // instead for it to just copy the entire dst. Realistically this is a moot // point, because any context that supports NV_path_rendering will also // support NV_blend_equation_advanced. GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, NULL, this); if (pipelineInfo.mustSkipDraw()) { return; } this->onDrawPaths(pathProc, pathRange, indices, indexType, transformValues, transformType, count, stencilSettings, pipelineInfo); }
void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch, const SkRect* devBounds) { SkASSERT(pipelineBuilder); // TODO some kind of checkdraw, but not at this level // Setup clip GrScissorState scissorState; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreStencil ars; if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) { return; } GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, batch, devBounds, this); if (pipelineInfo.mustSkipDraw()) { return; } this->onDrawBatch(batch, pipelineInfo); }
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; } }