diff options
25 files changed, 276 insertions, 192 deletions
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h index 84461836f0..71871a0020 100644 --- a/include/private/GrTypesPriv.h +++ b/include/private/GrTypesPriv.h @@ -100,6 +100,11 @@ static constexpr bool GrPrimTypeRequiresGeometryShaderSupport(GrPrimitiveType ty return GrPrimitiveType::kLinesAdjacency == type; } +enum class GrPrimitiveRestart : bool { + kNo = false, + kYes = true +}; + /** * Formats for masks, used by the font cache. Important that these are 0-based. */ diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp index 4dfc334d7a..13ae6c9844 100644 --- a/src/gpu/GrGpuCommandBuffer.cpp +++ b/src/gpu/GrGpuCommandBuffer.cpp @@ -34,7 +34,6 @@ bool GrGpuRTCommandBuffer::draw(const GrPipeline& pipeline, const SkRect& bounds) { #ifdef SK_DEBUG SkASSERT(!primProc.hasInstanceAttribs() || this->gpu()->caps()->instanceAttribSupport()); - SkASSERT(!primProc.willUsePrimitiveRestart() || this->gpu()->caps()->usePrimitiveRestart()); for (int i = 0; i < meshCount; ++i) { SkASSERT(!GrPrimTypeRequiresGeometryShaderSupport(meshes[i].primitiveType()) || this->gpu()->caps()->shaderCaps()->geometryShaderSupport()); diff --git a/src/gpu/GrMesh.h b/src/gpu/GrMesh.h index bdb62f5f0f..1c9fac4425 100644 --- a/src/gpu/GrMesh.h +++ b/src/gpu/GrMesh.h @@ -28,6 +28,7 @@ public: } GrPrimitiveType primitiveType() const { return fPrimitiveType; } + bool isIndexed() const { return SkToBool(fIndexBuffer.get()); } bool isInstanced() const { return SkToBool(fInstanceBuffer.get()); } bool hasVertexData() const { return SkToBool(fVertexBuffer.get()); } @@ -35,55 +36,56 @@ public: void setNonIndexedNonInstanced(int vertexCount); void setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex, - uint16_t minIndexValue, uint16_t maxIndexValue); + uint16_t minIndexValue, uint16_t maxIndexValue, GrPrimitiveRestart); void setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount, int vertexCount, int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer); void setInstanced(const GrBuffer* instanceBuffer, int instanceCount, int baseInstance, int vertexCount); void setIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, - const GrBuffer* instanceBuffer, int instanceCount, int baseInstance=0); + const GrBuffer* instanceBuffer, int instanceCount, int baseInstance, + GrPrimitiveRestart); void setVertexData(const GrBuffer* vertexBuffer, int baseVertex = 0); class SendToGpuImpl { public: - virtual void sendMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* vertexBuffer, int vertexCount, + virtual void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) = 0; - virtual void sendIndexedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* indexBuffer, int indexCount, - int baseIndex, uint16_t minIndexValue, + virtual void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, + int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, const GrBuffer* vertexBuffer, - int baseVertex) = 0; + int baseVertex, GrPrimitiveRestart) = 0; - virtual void sendInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* vertexBuffer, int vertexCount, - int baseVertex, const GrBuffer* instanceBuffer, - int instanceCount, int baseInstance) = 0; + virtual void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, + int vertexCount, int baseVertex, + const GrBuffer* instanceBuffer, int instanceCount, + int baseInstance) = 0; - virtual void sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* indexBuffer, int indexCount, - int baseIndex, const GrBuffer* vertexBuffer, - int baseVertex, const GrBuffer* instanceBuffer, - int instanceCount, int baseInstance) = 0; + virtual void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, + int indexCount, int baseIndex, + const GrBuffer* vertexBuffer, int baseVertex, + const GrBuffer* instanceBuffer, + int instanceCount, int baseInstance, + GrPrimitiveRestart) = 0; virtual ~SendToGpuImpl() {} }; - void sendToGpu(const GrPrimitiveProcessor&, SendToGpuImpl*) const; + void sendToGpu(SendToGpuImpl*) const; struct PatternBatch; private: using PendingBuffer = GrPendingIOResource<const GrBuffer, kRead_GrIOType>; - GrPrimitiveType fPrimitiveType; - PendingBuffer fIndexBuffer; - PendingBuffer fInstanceBuffer; - PendingBuffer fVertexBuffer; - int fBaseVertex; + GrPrimitiveType fPrimitiveType; + PendingBuffer fIndexBuffer; + PendingBuffer fInstanceBuffer; + PendingBuffer fVertexBuffer; + int fBaseVertex; + GrPrimitiveRestart fPrimitiveRestart; union { struct { // When fIndexBuffer == nullptr and fInstanceBuffer == nullptr. @@ -133,10 +135,12 @@ inline void GrMesh::setNonIndexedNonInstanced(int vertexCount) { fIndexBuffer.reset(nullptr); fInstanceBuffer.reset(nullptr); fNonIndexNonInstanceData.fVertexCount = vertexCount; + fPrimitiveRestart = GrPrimitiveRestart::kNo; } inline void GrMesh::setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex, - uint16_t minIndexValue, uint16_t maxIndexValue) { + uint16_t minIndexValue, uint16_t maxIndexValue, + GrPrimitiveRestart primitiveRestart) { SkASSERT(indexBuffer); SkASSERT(indexCount >= 1); SkASSERT(baseIndex >= 0); @@ -148,6 +152,7 @@ inline void GrMesh::setIndexed(const GrBuffer* indexBuffer, int indexCount, int fNonPatternIndexData.fBaseIndex = baseIndex; fNonPatternIndexData.fMinIndexValue = minIndexValue; fNonPatternIndexData.fMaxIndexValue = maxIndexValue; + fPrimitiveRestart = primitiveRestart; } inline void GrMesh::setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount, @@ -164,6 +169,7 @@ inline void GrMesh::setIndexedPatterned(const GrBuffer* indexBuffer, int indexCo fIndexData.fPatternRepeatCount = patternRepeatCount; fPatternData.fVertexCount = vertexCount; fPatternData.fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer; + fPrimitiveRestart = GrPrimitiveRestart::kNo; } inline void GrMesh::setInstanced(const GrBuffer* instanceBuffer, int instanceCount, @@ -176,11 +182,12 @@ inline void GrMesh::setInstanced(const GrBuffer* instanceBuffer, int instanceCou fInstanceData.fInstanceCount = instanceCount; fInstanceData.fBaseInstance = baseInstance; fInstanceNonIndexData.fVertexCount = vertexCount; + fPrimitiveRestart = GrPrimitiveRestart::kNo; } inline void GrMesh::setIndexedInstanced(const GrBuffer* indexBuffer, int indexCount, const GrBuffer* instanceBuffer, int instanceCount, - int baseInstance) { + int baseInstance, GrPrimitiveRestart primitiveRestart) { SkASSERT(indexBuffer); SkASSERT(indexCount >= 1); SkASSERT(instanceBuffer); @@ -191,6 +198,7 @@ inline void GrMesh::setIndexedInstanced(const GrBuffer* indexBuffer, int indexCo fInstanceData.fInstanceCount = instanceCount; fInstanceData.fBaseInstance = baseInstance; fInstanceIndexData.fIndexCount = indexCount; + fPrimitiveRestart = primitiveRestart; } inline void GrMesh::setVertexData(const GrBuffer* vertexBuffer, int baseVertex) { @@ -199,36 +207,35 @@ inline void GrMesh::setVertexData(const GrBuffer* vertexBuffer, int baseVertex) fBaseVertex = baseVertex; } -inline void GrMesh::sendToGpu(const GrPrimitiveProcessor& primProc, SendToGpuImpl* impl) const { +inline void GrMesh::sendToGpu(SendToGpuImpl* impl) const { if (this->isInstanced()) { if (!this->isIndexed()) { - impl->sendInstancedMeshToGpu(primProc, fPrimitiveType, fVertexBuffer.get(), + impl->sendInstancedMeshToGpu(fPrimitiveType, fVertexBuffer.get(), fInstanceNonIndexData.fVertexCount, fBaseVertex, fInstanceBuffer.get(), fInstanceData.fInstanceCount, fInstanceData.fBaseInstance); } else { - impl->sendIndexedInstancedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(), - fInstanceIndexData.fIndexCount, 0, - fVertexBuffer.get(), fBaseVertex, - fInstanceBuffer.get(), fInstanceData.fInstanceCount, - fInstanceData.fBaseInstance); + impl->sendIndexedInstancedMeshToGpu( + fPrimitiveType, fIndexBuffer.get(), fInstanceIndexData.fIndexCount, 0, + fVertexBuffer.get(), fBaseVertex, fInstanceBuffer.get(), + fInstanceData.fInstanceCount, fInstanceData.fBaseInstance, fPrimitiveRestart); } return; } if (!this->isIndexed()) { SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0); - impl->sendMeshToGpu(primProc, fPrimitiveType, fVertexBuffer.get(), + impl->sendMeshToGpu(fPrimitiveType, fVertexBuffer.get(), fNonIndexNonInstanceData.fVertexCount, fBaseVertex); return; } if (0 == fIndexData.fPatternRepeatCount) { - impl->sendIndexedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(), - fIndexData.fIndexCount, fNonPatternIndexData.fBaseIndex, + impl->sendIndexedMeshToGpu(fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount, + fNonPatternIndexData.fBaseIndex, fNonPatternIndexData.fMinIndexValue, fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(), - fBaseVertex); + fBaseVertex, fPrimitiveRestart); return; } @@ -240,10 +247,11 @@ inline void GrMesh::sendToGpu(const GrPrimitiveProcessor& primProc, SendToGpuImp // A patterned index buffer must contain indices in the range [0..vertexCount]. int minIndexValue = 0; int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1; - impl->sendIndexedMeshToGpu(primProc, fPrimitiveType, fIndexBuffer.get(), - fIndexData.fIndexCount * repeatCount, 0, minIndexValue, - maxIndexValue, fVertexBuffer.get(), - fBaseVertex + fPatternData.fVertexCount * baseRepetition); + SkASSERT(fPrimitiveRestart == GrPrimitiveRestart::kNo); + impl->sendIndexedMeshToGpu( + fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount * repeatCount, 0, + minIndexValue, maxIndexValue, fVertexBuffer.get(), + fBaseVertex + fPatternData.fVertexCount * baseRepetition, GrPrimitiveRestart::kNo); baseRepetition += repeatCount; } while (baseRepetition < fIndexData.fPatternRepeatCount); } diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h index c4303da4a6..c75f13c496 100644 --- a/src/gpu/GrPrimitiveProcessor.h +++ b/src/gpu/GrPrimitiveProcessor.h @@ -99,8 +99,6 @@ public: // we put these calls on the base class to prevent having to cast virtual bool willUseGeoShader() const = 0; - bool willUsePrimitiveRestart() const { return fWillUsePrimitiveRestart; } - /** * Computes a transformKey from an array of coord transforms. Will only look at the first * <numCoords> transforms in the array. @@ -150,8 +148,6 @@ protected: return fAttribs.back(); } - void setWillUsePrimitiveRestart() { fWillUsePrimitiveRestart = true; } - private: void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); } void removeRefs() const override { GrResourceIOProcessor::removeRefs(); } @@ -161,7 +157,6 @@ private: SkSTArray<8, Attribute> fAttribs; int fVertexStride = 0; int fInstanceStride = 0; - bool fWillUsePrimitiveRestart = false; typedef GrProcessor INHERITED; }; diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp index ef2bcd36cb..3c9fe89fbc 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp @@ -522,7 +522,6 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { SkASSERT(sizeof(int32_t) == this->getVertexStride()); if (caps.usePrimitiveRestart()) { - this->setWillUsePrimitiveRestart(); fVSTriangleType = GrPrimitiveType::kTriangleStrip; } else { fVSTriangleType = GrPrimitiveType::kTriangles; @@ -533,8 +532,9 @@ void GrCCCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanceC int baseInstance, SkTArray<GrMesh>* out) const { SkASSERT(Impl::kVertexShader == fImpl); GrMesh& mesh = out->emplace_back(fVSTriangleType); + auto primitiveRestart = GrPrimitiveRestart(GrPrimitiveType::kTriangleStrip == fVSTriangleType); mesh.setIndexedInstanced(fVSIndexBuffer.get(), fVSNumIndicesPerInstance, instanceBuffer, - instanceCount, baseInstance); + instanceCount, baseInstance, primitiveRestart); mesh.setVertexData(fVSVertexBuffer.get(), 0); } diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp index bbc2b811c5..5edc45ff69 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPathProcessor.cpp @@ -100,10 +100,6 @@ GrCCPathProcessor::GrCCPathProcessor(GrResourceProvider* resourceProvider, this->addVertexAttrib("edge_norms", kFloat4_GrVertexAttribType); - if (resourceProvider->caps()->usePrimitiveRestart()) { - this->setWillUsePrimitiveRestart(); - } - fAtlasAccess.instantiate(resourceProvider); this->addTextureSampler(&fAtlasAccess); @@ -146,8 +142,10 @@ void GrCCPathProcessor::drawPaths(GrOpFlushState* flushState, const GrPipeline& ? SK_ARRAY_COUNT(kOctoIndicesAsStrips) : SK_ARRAY_COUNT(kOctoIndicesAsTris); GrMesh mesh(primitiveType); + auto enablePrimitiveRestart = GrPrimitiveRestart(flushState->caps().usePrimitiveRestart()); + mesh.setIndexedInstanced(indexBuffer, numIndicesPerInstance, instanceBuffer, - endInstance - baseInstance, baseInstance); + endInstance - baseInstance, baseInstance, enablePrimitiveRestart); mesh.setVertexData(vertexBuffer); flushState->rtCommandBuffer()->draw(pipeline, *this, &mesh, nullptr, 1, bounds); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 533c6b4a4a..42a8992d4d 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -251,6 +251,7 @@ GrGLGpu::~GrGLGpu() { fMipmapProgramArrayBuffer.reset(); fStencilClipClearArrayBuffer.reset(); + fHWProgram.reset(); if (fHWProgramID) { // detach the current program so there is no confusion on OpenGL's part // that we want it to be deleted @@ -328,6 +329,7 @@ void GrGLGpu::disconnect(DisconnectType type) { } } + fHWProgram.reset(); delete fProgramCache; fProgramCache = nullptr; @@ -496,6 +498,7 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { if (resetBits & kProgram_GrGLBackendState) { fHWProgramID = 0; + fHWProgram.reset(); } } @@ -1695,11 +1698,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso this->flushColorWrite(blendInfo.fWriteColor); this->flushMinSampleShading(primProc.getSampleShading()); - GrGLuint programID = program->programID(); - if (fHWProgramID != programID) { - GL_CALL(UseProgram(programID)); - fHWProgramID = programID; - } + this->flushProgram(std::move(program)); if (blendInfo.fWriteColor) { // Swizzle the blend to match what the shader will output. @@ -1708,7 +1707,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso this->flushBlend(blendInfo, swizzle); } - program->setData(primProc, pipeline); + fHWProgram->setData(primProc, pipeline); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget()); GrStencilSettings stencil; @@ -1730,13 +1729,41 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso return true; } -void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, - const GrBuffer* indexBuffer, +void GrGLGpu::flushProgram(sk_sp<GrGLProgram> program) { + if (!program) { + fHWProgram.reset(); + fHWProgramID = 0; + return; + } + SkASSERT((program == fHWProgram) == (fHWProgramID == program->programID())); + if (program == fHWProgram) { + return; + } + auto id = program->programID(); + SkASSERT(id); + GL_CALL(UseProgram(id)); + fHWProgram = std::move(program); + fHWProgramID = id; +} + +void GrGLGpu::flushProgram(GrGLuint id) { + SkASSERT(id); + if (fHWProgramID == id) { + SkASSERT(!fHWProgram); + return; + } + fHWProgram.reset(); + GL_CALL(UseProgram(id)); + fHWProgramID = id; +} + +void GrGLGpu::setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer, - int baseInstance) { - using EnablePrimitiveRestart = GrGLAttribArrayState::EnablePrimitiveRestart; + int baseInstance, + GrPrimitiveRestart enablePrimitiveRestart) { + SkASSERT((enablePrimitiveRestart == GrPrimitiveRestart::kNo) || indexBuffer); GrGLAttribArrayState* attribState; if (indexBuffer) { @@ -1752,30 +1779,29 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, size_t fBufferOffset; } bindings[2]; - if (int vertexStride = primProc.getVertexStride()) { + if (int vertexStride = fHWProgram->vertexStride()) { SkASSERT(vertexBuffer && !vertexBuffer->isMapped()); bindings[0].fBuffer = vertexBuffer; bindings[0].fStride = vertexStride; bindings[0].fBufferOffset = vertexBuffer->baseOffset() + baseVertex * vertexStride; } - if (int instanceStride = primProc.getInstanceStride()) { + if (int instanceStride = fHWProgram->instanceStride()) { SkASSERT(instanceBuffer && !instanceBuffer->isMapped()); bindings[1].fBuffer = instanceBuffer; bindings[1].fStride = instanceStride; bindings[1].fBufferOffset = instanceBuffer->baseOffset() + baseInstance * instanceStride; } - int numAttribs = primProc.numAttribs(); - auto enableRestart = EnablePrimitiveRestart(primProc.willUsePrimitiveRestart() && indexBuffer); - attribState->enableVertexArrays(this, numAttribs, enableRestart); + auto numAttributes = fHWProgram->numAttributes(); + attribState->enableVertexArrays(this, numAttributes, enablePrimitiveRestart); - for (int i = 0; i < numAttribs; ++i) { + for (int i = 0; i < numAttributes; ++i) { using InputRate = GrPrimitiveProcessor::Attribute::InputRate; - const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(i); - const int divisor = InputRate::kPerInstance == attrib.inputRate() ? 1 : 0; + const GrGLProgram::Attribute& attribute = fHWProgram->attribute(i); + const int divisor = InputRate::kPerInstance == attribute.fInputRate ? 1 : 0; const auto& binding = bindings[divisor]; - attribState->set(this, i, binding.fBuffer, attrib.type(), binding.fStride, - binding.fBufferOffset + attrib.offsetInRecord(), divisor); + attribState->set(this, attribute.fLocation, binding.fBuffer, attribute.fType, + binding.fStride, binding.fBufferOffset + attribute.fOffset, divisor); } } @@ -2242,7 +2268,7 @@ void GrGLGpu::draw(const GrPipeline& pipeline, GL_CALL(Enable(GR_GL_CULL_FACE)); GL_CALL(Disable(GR_GL_CULL_FACE)); } - meshes[i].sendToGpu(primProc, this); + meshes[i].sendToGpu(this); fLastPrimitiveType = meshes[i].primitiveType(); } @@ -2279,14 +2305,14 @@ static GrGLenum gr_primitive_type_to_gl_mode(GrPrimitiveType primitiveType) { return GR_GL_TRIANGLES; } -void GrGLGpu::sendMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType primitiveType, - const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) { +void GrGLGpu::sendMeshToGpu(GrPrimitiveType primitiveType, const GrBuffer* vertexBuffer, + int vertexCount, int baseVertex) { const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); if (this->glCaps().drawArraysBaseVertexIsBroken()) { - this->setupGeometry(primProc, nullptr, vertexBuffer, baseVertex, nullptr, 0); + this->setupGeometry(nullptr, vertexBuffer, baseVertex, nullptr, 0, GrPrimitiveRestart::kNo); GL_CALL(DrawArrays(glPrimType, 0, vertexCount)); } else { - this->setupGeometry(primProc, nullptr, vertexBuffer, 0, nullptr, 0); + this->setupGeometry(nullptr, vertexBuffer, 0, nullptr, 0, GrPrimitiveRestart::kNo); GL_CALL(DrawArrays(glPrimType, baseVertex, vertexCount)); } if (this->glCaps().requiresFlushBetweenNonAndInstancedDraws()) { @@ -2295,16 +2321,15 @@ void GrGLGpu::sendMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveTyp fStats.incNumDraws(); } -void GrGLGpu::sendIndexedMeshToGpu(const GrPrimitiveProcessor& primProc, - GrPrimitiveType primitiveType, const GrBuffer* indexBuffer, +void GrGLGpu::sendIndexedMeshToGpu(GrPrimitiveType primitiveType, const GrBuffer* indexBuffer, int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, const GrBuffer* vertexBuffer, - int baseVertex) { + int baseVertex, GrPrimitiveRestart enablePrimitiveRestart) { const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); GrGLvoid* const indices = reinterpret_cast<void*>(indexBuffer->baseOffset() + sizeof(uint16_t) * baseIndex); - this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex, nullptr, 0); + this->setupGeometry(indexBuffer, vertexBuffer, baseVertex, nullptr, 0, enablePrimitiveRestart); if (this->glCaps().drawRangeElementsSupport()) { GL_CALL(DrawRangeElements(glPrimType, minIndexValue, maxIndexValue, indexCount, @@ -2318,8 +2343,7 @@ void GrGLGpu::sendIndexedMeshToGpu(const GrPrimitiveProcessor& primProc, fStats.incNumDraws(); } -void GrGLGpu::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType - primitiveType, const GrBuffer* vertexBuffer, +void GrGLGpu::sendInstancedMeshToGpu(GrPrimitiveType primitiveType, const GrBuffer* vertexBuffer, int vertexCount, int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, int baseInstance) { @@ -2331,19 +2355,20 @@ void GrGLGpu::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, GrPri GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); int maxInstances = this->glCaps().maxInstancesPerDrawArraysWithoutCrashing(instanceCount); for (int i = 0; i < instanceCount; i += maxInstances) { - this->setupGeometry(primProc, nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i); + this->setupGeometry(nullptr, vertexBuffer, 0, instanceBuffer, baseInstance + i, + GrPrimitiveRestart::kNo); GL_CALL(DrawArraysInstanced(glPrimType, baseVertex, vertexCount, SkTMin(instanceCount - i, maxInstances))); fStats.incNumDraws(); } } -void GrGLGpu::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, - GrPrimitiveType primitiveType, +void GrGLGpu::sendIndexedInstancedMeshToGpu(GrPrimitiveType primitiveType, const GrBuffer* indexBuffer, int indexCount, int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer, - int instanceCount, int baseInstance) { + int instanceCount, int baseInstance, + GrPrimitiveRestart enablePrimitiveRestart) { if (fRequiresFlushBeforeNextInstancedDraw) { SkASSERT(this->glCaps().requiresFlushBetweenNonAndInstancedDraws()); GL_CALL(Flush()); @@ -2352,8 +2377,8 @@ void GrGLGpu::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc const GrGLenum glPrimType = gr_primitive_type_to_gl_mode(primitiveType); GrGLvoid* indices = reinterpret_cast<void*>(indexBuffer->baseOffset() + sizeof(uint16_t) * baseIndex); - this->setupGeometry(primProc, indexBuffer, vertexBuffer, baseVertex, - instanceBuffer, baseInstance); + this->setupGeometry(indexBuffer, vertexBuffer, baseVertex, instanceBuffer, baseInstance, + enablePrimitiveRestart); GL_CALL(DrawElementsInstanced(glPrimType, indexCount, GR_GL_UNSIGNED_SHORT, indices, instanceCount)); fStats.incNumDraws(); @@ -3458,8 +3483,7 @@ void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencil GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget()); this->flushRenderTarget(glRT); - GL_CALL(UseProgram(fStencilClipClearProgram)); - fHWProgramID = fStencilClipClearProgram; + this->flushProgram(fStencilClipClearProgram); fHWVertexArrayState.setVertexArrayID(this, 0); @@ -3571,8 +3595,7 @@ void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g this->flushViewport(dstVP); fHWBoundRenderTargetUniqueID.makeInvalid(); - GL_CALL(UseProgram(fClearColorProgram.fProgram)); - fHWProgramID = fClearColorProgram.fProgram; + this->flushProgram(fClearColorProgram.fProgram); fHWVertexArrayState.setVertexArrayID(this, 0); @@ -3632,8 +3655,7 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); - GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); - fHWProgramID = fCopyPrograms[progIdx].fProgram; + this->flushProgram(fCopyPrograms[progIdx].fProgram); fHWVertexArrayState.setVertexArrayID(this, 0); @@ -3885,8 +3907,7 @@ bool GrGLGpu::generateMipmap(GrGLTexture* texture, GrSurfaceOrigin textureOrigin return false; } } - GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram)); - fHWProgramID = fMipmapPrograms[progIdx].fProgram; + this->flushProgram(fMipmapPrograms[progIdx].fProgram); // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h) const float invWidth = 1.0f / width; diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 7240f9d763..48cd21b426 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -95,24 +95,22 @@ public: // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls. // Marked final as a hint to the compiler to not use virtual dispatch. - void sendMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) final; + void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, + int baseVertex) final; - void sendIndexedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* indexBuffer, int indexCount, int baseIndex, - uint16_t minIndexValue, uint16_t maxIndexValue, - const GrBuffer* vertexBuffer, int baseVertex) final; + void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, + int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, + const GrBuffer* vertexBuffer, int baseVertex, + GrPrimitiveRestart) final; - void sendInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* vertexBuffer, int vertexCount, int baseVertex, - const GrBuffer* instanceBuffer, int instanceCount, + void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, + int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, int baseInstance) final; - void sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* indexBuffer, int indexCount, int baseIndex, - const GrBuffer* vertexBuffer, int baseVertex, + void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, + int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, - int baseInstance) final; + int baseInstance, GrPrimitiveRestart) final; // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. // Thus this is the implementation of the clear call for the corresponding passthrough function @@ -260,13 +258,18 @@ private: // willDrawPoints must be true if point primitives will be rendered after setting the GL state. bool flushGLState(const GrPipeline&, const GrPrimitiveProcessor&, bool willDrawPoints); + void flushProgram(sk_sp<GrGLProgram>); + + // Version for programs that aren't GrGLProgram. + void flushProgram(GrGLuint); + // Sets up vertex/instance attribute pointers and strides. - void setupGeometry(const GrPrimitiveProcessor&, - const GrBuffer* indexBuffer, + void setupGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer, - int baseInstance); + int baseInstance, + GrPrimitiveRestart); void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); @@ -408,7 +411,9 @@ private: ///@name Caching of GL State ///@{ int fHWActiveTextureUnitIdx; + GrGLuint fHWProgramID; + sk_sp<GrGLProgram> fHWProgram; enum TriState { kNo_TriState, diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index ea5c18c4ff..262f0b21c4 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -36,13 +36,21 @@ GrGLProgram::GrGLProgram( std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor, std::unique_ptr<GrGLSLXferProcessor> xferProcessor, std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors, - int fragmentProcessorCnt) + int fragmentProcessorCnt, + std::unique_ptr<Attribute[]> attributes, + int attributeCnt, + int vertexStride, + int instanceStride) : fBuiltinUniformHandles(builtinUniforms) , fProgramID(programID) - , fGeometryProcessor(std::move(geometryProcessor)) + , fPrimitiveProcessor(std::move(geometryProcessor)) , fXferProcessor(std::move(xferProcessor)) , fFragmentProcessors(std::move(fragmentProcessors)) , fFragmentProcessorCnt(fragmentProcessorCnt) + , fAttributes(std::move(attributes)) + , fAttributeCnt(attributeCnt) + , fVertexStride(vertexStride) + , fInstanceStride(instanceStride) , fGpu(gpu) , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) , fNumTextureSamplers(textureSamplers.count()) @@ -76,8 +84,8 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline // Within each group we will bind them in primProc, fragProcs, XP order. int nextTexSamplerIdx = 0; int nextTexelBufferIdx = fNumTextureSamplers; - fGeometryProcessor->setData(fProgramDataManager, primProc, - GrFragmentProcessor::CoordTransformIter(pipeline)); + fPrimitiveProcessor->setData(fProgramDataManager, primProc, + GrFragmentProcessor::CoordTransformIter(pipeline)); this->bindTextures(primProc, &nextTexSamplerIdx, &nextTexelBufferIdx); this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx, &nextTexelBufferIdx); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index a43e4f4294..6ea1f2cbf9 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -10,6 +10,7 @@ #define GrGLProgram_DEFINED #include "GrGLProgramDataManager.h" +#include "GrPrimitiveProcessor.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLUniformHandler.h" @@ -22,16 +23,23 @@ class GrRenderTargetProxy; class GrResourceIOProcessor; /** - * This class manages a GPU program and records per-program information. - * We can specify the attribute locations so that they are constant - * across our shaders. But the driver determines the uniform locations - * at link time. We don't need to remember the sampler uniform location - * because we will bind a texture slot to it and never change it - * Uniforms are program-local so we can't rely on fHWState to hold the - * previous uniform state after a program change. + * This class manages a GPU program and records per-program information. It also records the vertex + * and instance attribute layouts that are to be used with the program. */ class GrGLProgram : public SkRefCnt { public: + /** + * This class has its own Attribute representation as it does not need the name and we don't + * want to worry about copying the name string to memory with life time of GrGLProgram. + * Additionally, these store the attribute location. + */ + struct Attribute { + GrVertexAttribType fType; + int fOffset; + GrGLint fLocation; + GrPrimitiveProcessor::Attribute::InputRate fInputRate; + }; + using UniformHandle = GrGLSLProgramDataManager::UniformHandle; using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray; using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray; @@ -46,7 +54,11 @@ public: std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor, std::unique_ptr<GrGLSLXferProcessor> xferProcessor, std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors, - int fragmentProcessorCnt); + int fragmentProcessorCnt, + std::unique_ptr<Attribute[]>, + int attributeCnt, + int vertexStride, + int instanceStride); ~GrGLProgram(); @@ -109,6 +121,11 @@ public: * ensures that any textures requiring mipmaps have their mipmaps correctly built. */ void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&); + int vertexStride() const { return fVertexStride; } + int instanceStride() const { return fInstanceStride; } + + int numAttributes() const { return fAttributeCnt; } + const Attribute& attribute(int i) const { return fAttributes[i]; } private: // A helper to loop over effects, set the transforms (via subclass) and bind textures @@ -130,11 +147,16 @@ private: GrGLuint fProgramID; // the installed effects - std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor; + std::unique_ptr<GrGLSLPrimitiveProcessor> fPrimitiveProcessor; std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors; int fFragmentProcessorCnt; + std::unique_ptr<Attribute[]> fAttributes; + int fAttributeCnt; + int fVertexStride; + int fInstanceStride; + GrGLGpu* fGpu; GrGLProgramDataManager fProgramDataManager; diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index dbfa0f4f4a..68bcf21e7d 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -150,7 +150,7 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu, } void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount, - EnablePrimitiveRestart enablePrimitiveRestart) { + GrPrimitiveRestart enablePrimitiveRestart) { SkASSERT(enabledCount <= fAttribArrayStates.count()); if (!fEnableStateIsValid || enabledCount != fNumEnabledArrays) { @@ -167,12 +167,12 @@ void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCou fNumEnabledArrays = enabledCount; } - SkASSERT(EnablePrimitiveRestart::kNo == enablePrimitiveRestart || + SkASSERT(GrPrimitiveRestart::kNo == enablePrimitiveRestart || gpu->caps()->usePrimitiveRestart()); if (gpu->caps()->usePrimitiveRestart() && (!fEnableStateIsValid || enablePrimitiveRestart != fPrimitiveRestartEnabled)) { - if (EnablePrimitiveRestart::kYes == enablePrimitiveRestart) { + if (GrPrimitiveRestart::kYes == enablePrimitiveRestart) { GR_GL_CALL(gpu->glInterface(), Enable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX)); } else { GR_GL_CALL(gpu->glInterface(), Disable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX)); diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h index 20b21ae47b..e460c04978 100644 --- a/src/gpu/gl/GrGLVertexArray.h +++ b/src/gpu/gl/GrGLVertexArray.h @@ -45,16 +45,11 @@ public: size_t offsetInBytes, int divisor = 0); - enum class EnablePrimitiveRestart : bool { - kYes = true, - kNo = false - }; - /** * This function enables the first 'enabledCount' vertex arrays and disables the rest. */ void enableVertexArrays(const GrGLGpu*, int enabledCount, - EnablePrimitiveRestart = EnablePrimitiveRestart::kNo); + GrPrimitiveRestart = GrPrimitiveRestart::kNo); void invalidate() { int count = fAttribArrayStates.count(); @@ -90,7 +85,7 @@ private: SkSTArray<16, AttribArrayState, true> fAttribArrayStates; int fNumEnabledArrays; - EnablePrimitiveRestart fPrimitiveRestartEnabled; + GrPrimitiveRestart fPrimitiveRestartEnabled; bool fEnableStateIsValid = false; }; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 86dcfef7a4..0cdc3b5b21 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -66,11 +66,13 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, GrProgramDesc* desc) - : INHERITED(pipeline, primProc, desc) - , fGpu(gpu) - , fVaryingHandler(this) - , fUniformHandler(this) { -} + : INHERITED(pipeline, primProc, desc) + , fGpu(gpu) + , fVaryingHandler(this) + , fUniformHandler(this) + , fAttributeCnt(0) + , fVertexStride(0) + , fInstanceStride(0) {} const GrCaps* GrGLProgramBuilder::caps() const { return fGpu->caps(); @@ -225,9 +227,17 @@ GrGLProgram* GrGLProgramBuilder::finalize() { // NVPR actually requires a vertex shader to compile bool useNvpr = primProc.isPathRendering(); if (!useNvpr) { - int vaCount = primProc.numAttribs(); - for (int i = 0; i < vaCount; i++) { - GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).name())); + fAttributeCnt = primProc.numAttribs(); + fAttributes.reset(new GrGLProgram::Attribute[fAttributeCnt]); + fVertexStride = primProc.getVertexStride(); + fInstanceStride = primProc.getInstanceStride(); + for (int i = 0; i < fAttributeCnt; i++) { + const auto& attr = primProc.getAttrib(i); + fAttributes[i].fInputRate = attr.inputRate(); + fAttributes[i].fType = attr.type(); + fAttributes[i].fOffset = attr.offsetInRecord(); + fAttributes[i].fLocation = i; + GL_CALL(BindAttribLocation(programID, i, attr.name())); } } @@ -379,7 +389,7 @@ void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL } void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { for (int i = 0; i < shaderIDs.count(); ++i) { - GL_CALL(DeleteShader(shaderIDs[i])); + GL_CALL(DeleteShader(shaderIDs[i])); } } @@ -394,5 +404,9 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { std::move(fGeometryProcessor), std::move(fXferProcessor), std::move(fFragmentProcessors), - fFragmentProcessorCnt); + fFragmentProcessorCnt, + std::move(fAttributes), + fAttributeCnt, + fVertexStride, + fInstanceStride); } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 54c91b448b..ea3432bd04 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -9,6 +9,7 @@ #define GrGLProgramBuilder_DEFINED #include "GrPipeline.h" +#include "gl/GrGLProgram.h" #include "gl/GrGLProgramDataManager.h" #include "gl/GrGLUniformHandler.h" #include "gl/GrGLVaryingHandler.h" @@ -79,6 +80,11 @@ private: GrGLVaryingHandler fVaryingHandler; GrGLUniformHandler fUniformHandler; + std::unique_ptr<GrGLProgram::Attribute[]> fAttributes; + int fAttributeCnt; + int fVertexStride; + int fInstanceStride; + // shader pulled from cache. Data is organized as: // SkSL::Program::Inputs inputs // int binaryFormat diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h index fe89b882b6..4c52d3cf09 100644 --- a/src/gpu/glsl/GrGLSLUniformHandler.h +++ b/src/gpu/glsl/GrGLSLUniformHandler.h @@ -30,6 +30,7 @@ public: virtual ~GrGLSLUniformHandler() {} using UniformHandle = GrGLSLProgramDataManager::UniformHandle; + GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle); GR_DEFINE_RESOURCE_HANDLE_CLASS(TexelBufferHandle); diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp index d1fbbc4e7b..f94f527e11 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp @@ -836,7 +836,8 @@ private: fHelper.compatibleWithAlphaAsCoverage()); GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1); + mesh.setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), pipeline, mesh); } @@ -923,7 +924,8 @@ private: for (int j = 0; j < draws.count(); ++j) { const Draw& draw = draws[j]; - mesh.setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0, draw.fVertexCnt - 1); + mesh.setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0, draw.fVertexCnt - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(quadProcessor.get(), pipeline, mesh); firstIndex += draw.fIndexCnt; diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp index 2c1ea50fc3..02520c1df7 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp @@ -229,7 +229,8 @@ private: return; } memcpy(idxs, indices, indexCount * sizeof(uint16_t)); - mesh.setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1); + mesh.setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp, pipeline, mesh); } diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index 1c5acb0a82..91eca931ac 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -269,7 +269,8 @@ private: if (!this->isIndexed()) { fMesh.setNonIndexedNonInstanced(vertexCount); } else { - fMesh.setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1); + fMesh.setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1, + GrPrimitiveRestart::kNo); } fMesh.setVertexData(fVertexBuffer, fFirstVertex); fTarget->draw(fGeometryProcessor, fPipeline, fMesh); diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp index dded70a7f7..112ba8bf2e 100644 --- a/src/gpu/ops/GrDrawVerticesOp.cpp +++ b/src/gpu/ops/GrDrawVerticesOp.cpp @@ -245,7 +245,8 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) { if (!indices) { mesh.setNonIndexedNonInstanced(fVertexCount); } else { - mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1); + mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1, + GrPrimitiveRestart::kNo); } mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), fHelper.makePipeline(target), mesh); diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp index 654daae37a..f6a2a1a087 100644 --- a/src/gpu/ops/GrOvalOpFactory.cpp +++ b/src/gpu/ops/GrOvalOpFactory.cpp @@ -1413,7 +1413,8 @@ private: } GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1); + mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), fHelper.makePipeline(target), mesh); } @@ -1722,7 +1723,8 @@ private: } GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1); + mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), fHelper.makePipeline(target), mesh); } @@ -2646,7 +2648,8 @@ private: } GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1); + mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), fHelper.makePipeline(target), mesh); } diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp index 91c57ce250..8f5e234360 100644 --- a/src/gpu/ops/GrShadowRRectOp.cpp +++ b/src/gpu/ops/GrShadowRRectOp.cpp @@ -626,7 +626,8 @@ private: kPipelineFlags, GrProcessorSet::MakeEmptySet(), target->detachAppliedClip()); GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1); + mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), pipeline, mesh); } diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp index 5493dd9890..dde64f38f6 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp +++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp @@ -520,8 +520,7 @@ void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, con //////////////////////////////////////////////////////////////////////////////// -void GrVkGpuRTCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc, - const GrBuffer* indexBuffer, +void GrVkGpuRTCommandBuffer::bindGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, const GrBuffer* instanceBuffer) { GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf(); @@ -534,7 +533,7 @@ void GrVkGpuRTCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc, // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance. uint32_t binding = 0; - if (primProc.hasVertexAttribs()) { + if (vertexBuffer) { SkASSERT(vertexBuffer); SkASSERT(!vertexBuffer->isCPUBacked()); SkASSERT(!vertexBuffer->isMapped()); @@ -543,7 +542,7 @@ void GrVkGpuRTCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc, static_cast<const GrVkVertexBuffer*>(vertexBuffer)); } - if (primProc.hasInstanceAttribs()) { + if (instanceBuffer) { SkASSERT(instanceBuffer); SkASSERT(!instanceBuffer->isCPUBacked()); SkASSERT(!instanceBuffer->isMapped()); @@ -689,7 +688,7 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPipeline& pipeline, } SkASSERT(pipelineState); - mesh.sendToGpu(primProc, this); + mesh.sendToGpu(this); } cbInfo.fBounds.join(bounds); @@ -701,8 +700,7 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPipeline& pipeline, pipelineState->freeTempResources(fGpu); } -void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, - GrPrimitiveType, +void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, int baseVertex, @@ -710,13 +708,12 @@ void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(const GrPrimitiveProcessor& int instanceCount, int baseInstance) { CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; - this->bindGeometry(primProc, nullptr, vertexBuffer, instanceBuffer); + this->bindGeometry(nullptr, vertexBuffer, instanceBuffer); cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance); fGpu->stats()->incNumDraws(); } -void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc, - GrPrimitiveType, +void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, int baseIndex, @@ -724,11 +721,12 @@ void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(const GrPrimitiveProc int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, - int baseInstance) { + int baseInstance, + GrPrimitiveRestart restart) { + SkASSERT(restart == GrPrimitiveRestart::kNo); CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; - this->bindGeometry(primProc, indexBuffer, vertexBuffer, instanceBuffer); + this->bindGeometry(indexBuffer, vertexBuffer, instanceBuffer); cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount, baseIndex, baseVertex, baseInstance); fGpu->stats()->incNumDraws(); } - diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h index f2d48c7ab0..93990be697 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.h +++ b/src/gpu/vk/GrVkGpuCommandBuffer.h @@ -82,8 +82,7 @@ private: GrGpu* gpu() override; // Bind vertex and index buffers - void bindGeometry(const GrPrimitiveProcessor&, - const GrBuffer* indexBuffer, + void bindGeometry(const GrBuffer* indexBuffer, const GrBuffer* vertexBuffer, const GrBuffer* instanceBuffer); @@ -101,30 +100,30 @@ private: // GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands. // Marked final as a hint to the compiler to not use virtual dispatch. - void sendMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType primType, - const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) final { - this->sendInstancedMeshToGpu(primProc, primType, vertexBuffer, vertexCount, baseVertex, - nullptr, 1, 0); + void sendMeshToGpu(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int vertexCount, + int baseVertex) final { + this->sendInstancedMeshToGpu(primType, vertexBuffer, vertexCount, baseVertex, nullptr, 1, + 0); } - void sendIndexedMeshToGpu(const GrPrimitiveProcessor& primProc, GrPrimitiveType primType, - const GrBuffer* indexBuffer, int indexCount, int baseIndex, - uint16_t /*minIndexValue*/, uint16_t /*maxIndexValue*/, - const GrBuffer* vertexBuffer, int baseVertex) final { - this->sendIndexedInstancedMeshToGpu(primProc, primType, indexBuffer, indexCount, baseIndex, - vertexBuffer, baseVertex, nullptr, 1, 0); + void sendIndexedMeshToGpu(GrPrimitiveType primType, const GrBuffer* indexBuffer, int indexCount, + int baseIndex, uint16_t /*minIndexValue*/, uint16_t /*maxIndexValue*/, + const GrBuffer* vertexBuffer, int baseVertex, + GrPrimitiveRestart restart) final { + SkASSERT(restart == GrPrimitiveRestart::kNo); + this->sendIndexedInstancedMeshToGpu(primType, indexBuffer, indexCount, baseIndex, + vertexBuffer, baseVertex, nullptr, 1, 0, + GrPrimitiveRestart::kNo); } - void sendInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* vertexBuffer, int vertexCount, int baseVertex, - const GrBuffer* instanceBuffer, int instanceCount, + void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, + int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, int baseInstance) final; - void sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType, - const GrBuffer* indexBuffer, int indexCount, int baseIndex, - const GrBuffer* vertexBuffer, int baseVertex, + void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, + int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, - int baseInstance) final; + int baseInstance, GrPrimitiveRestart) final; void onClear(const GrFixedClip&, GrColor color) override; diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp index fb3579cabe..e612fb4b5f 100644 --- a/tests/GrMeshTest.cpp +++ b/tests/GrMeshTest.cpp @@ -172,7 +172,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrMeshTest, reporter, ctxInfo) { GrMesh mesh(GrPrimitiveType::kTriangles); mesh.setIndexed(ibuff.get(), repetitionCount * 6, baseRepetition * 6, - baseRepetition * 4, (baseRepetition + repetitionCount) * 4 - 1); + baseRepetition * 4, (baseRepetition + repetitionCount) * 4 - 1, + GrPrimitiveRestart::kNo); mesh.setVertexData(vbuff.get(), (i - baseRepetition) * 4); helper->drawMesh(mesh); @@ -220,8 +221,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrMeshTest, reporter, ctxInfo) { : GrPrimitiveType::kTriangleStrip); if (indexed) { VALIDATE(idxbuff); - mesh.setIndexedInstanced(idxbuff.get(), 6, - instbuff.get(), kBoxCountX, y * kBoxCountX); + mesh.setIndexedInstanced(idxbuff.get(), 6, instbuff.get(), kBoxCountX, + y * kBoxCountX, GrPrimitiveRestart::kNo); } else { mesh.setInstanced(instbuff.get(), kBoxCountX, y * kBoxCountX, 4); } diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp index 463e44f194..e9e4dd0462 100644 --- a/tests/OnFlushCallbackTest.cpp +++ b/tests/OnFlushCallbackTest.cpp @@ -156,7 +156,7 @@ private: } GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexed(indexBuffer, 6, firstIndex, 0, 3); + mesh.setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo); mesh.setVertexData(vertexBuffer, firstVertex); target->draw(gp.get(), fHelper.makePipeline(target), mesh); |