aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/private/GrTypesPriv.h5
-rw-r--r--src/gpu/GrGpuCommandBuffer.cpp1
-rw-r--r--src/gpu/GrMesh.h88
-rw-r--r--src/gpu/GrPrimitiveProcessor.h5
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp4
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.cpp8
-rw-r--r--src/gpu/gl/GrGLGpu.cpp111
-rw-r--r--src/gpu/gl/GrGLGpu.h37
-rw-r--r--src/gpu/gl/GrGLProgram.cpp16
-rw-r--r--src/gpu/gl/GrGLProgram.h40
-rw-r--r--src/gpu/gl/GrGLVertexArray.cpp6
-rw-r--r--src/gpu/gl/GrGLVertexArray.h9
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp34
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h6
-rw-r--r--src/gpu/glsl/GrGLSLUniformHandler.h1
-rw-r--r--src/gpu/ops/GrAAConvexPathRenderer.cpp6
-rw-r--r--src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp3
-rw-r--r--src/gpu/ops/GrDefaultPathRenderer.cpp3
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.cpp3
-rw-r--r--src/gpu/ops/GrOvalOpFactory.cpp9
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp3
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp24
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.h37
-rw-r--r--tests/GrMeshTest.cpp7
-rw-r--r--tests/OnFlushCallbackTest.cpp2
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);