aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl')
-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
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