diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 111 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 37 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.h | 9 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 34 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 6 |
8 files changed, 165 insertions, 94 deletions
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 |