summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-11-14 12:11:53 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-11-15 13:55:08 -0800
commit58877d1b3ddf0e4521d680b85e31b7a4c6287302 (patch)
treef844c8a12f82e40b1777ae79fe416c1eaa714470 /src
parent0fe8d8d7b4bbf136e8fb0f972cc31a94ddc4b67e (diff)
downloadqtlocation-mapboxgl-58877d1b3ddf0e4521d680b85e31b7a4c6287302.tar.gz
[core] Assign attribute locations sequentially
Two reasons to prefer explicit sequential location assignment, rather than relying on the GLSL linker to assign locations: * For data-driven properties, we want to have the option to use glDisableVertexAttribArray plus glVertexAttrib*. In order to use glDisableVertexAttribArray, we must avoid using attribute location 0, which cannot be disabled. * We want to use the same VAO in cases where, say, a fill layer might be rendered with FillProgram at first, and then FillPatternProgram later. VAOs do not store the program binding, only the attribute bindings, so as long as the two programs have the same attributes and attribute locations, only a single VAO (per segment) is needed.
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/gl/attribute.cpp5
-rw-r--r--src/mbgl/gl/attribute.hpp7
-rw-r--r--src/mbgl/gl/context.cpp17
-rw-r--r--src/mbgl/gl/context.hpp1
-rw-r--r--src/mbgl/gl/program.hpp2
5 files changed, 21 insertions, 11 deletions
diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp
index 51fdd1dd12..7432fff590 100644
--- a/src/mbgl/gl/attribute.cpp
+++ b/src/mbgl/gl/attribute.cpp
@@ -4,8 +4,9 @@
namespace mbgl {
namespace gl {
-AttributeLocation attributeLocation(ProgramID id, const char* name) {
- return MBGL_CHECK_ERROR(glGetAttribLocation(id, name));
+AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) {
+ MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name));
+ return location;
}
void bindAttribute(AttributeLocation location,
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
index df469fc6a2..e45014127b 100644
--- a/src/mbgl/gl/attribute.hpp
+++ b/src/mbgl/gl/attribute.hpp
@@ -17,6 +17,9 @@ public:
class State {
public:
+ explicit State(AttributeLocation location_)
+ : location(location_) {}
+
AttributeLocation location;
static constexpr std::size_t count = N;
static constexpr DataType type = DataTypeOf<T>::value;
@@ -130,7 +133,7 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {
} // namespace detail
-AttributeLocation attributeLocation(ProgramID, const char * name);
+AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name);
void bindAttribute(AttributeLocation location,
std::size_t count,
@@ -149,7 +152,7 @@ public:
static constexpr std::size_t Index = TypeIndex<A, As...>::value;
static State state(const ProgramID& id) {
- return State { { attributeLocation(id, As::name) }... };
+ return State { typename As::State(bindAttributeLocation(id, Index<As>, As::name))... };
}
static std::function<void (std::size_t)> binder(const State& state) {
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index c4485ad0fd..3251be0c87 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -68,19 +68,24 @@ UniqueProgram Context::createProgram(ShaderID vertexShader, ShaderID fragmentSha
MBGL_CHECK_ERROR(glAttachShader(result, vertexShader));
MBGL_CHECK_ERROR(glAttachShader(result, fragmentShader));
- MBGL_CHECK_ERROR(glLinkProgram(result));
+
+ return result;
+}
+
+void Context::linkProgram(ProgramID program_) {
+ MBGL_CHECK_ERROR(glLinkProgram(program_));
GLint status;
- MBGL_CHECK_ERROR(glGetProgramiv(result, GL_LINK_STATUS, &status));
- if (status != 0) {
- return result;
+ MBGL_CHECK_ERROR(glGetProgramiv(program_, GL_LINK_STATUS, &status));
+ if (status == GL_TRUE) {
+ return;
}
GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(result, GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &logLength));
const auto log = std::make_unique<GLchar[]>(logLength);
if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(result, logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program_, logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
}
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 154921a1b9..33b7a555a8 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -38,6 +38,7 @@ public:
UniqueShader createShader(ShaderType type, const std::string& source);
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
+ void linkProgram(ProgramID);
UniqueTexture createTexture();
template <class Vertex, class DrawMode>
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
index 929237037b..44c16ae671 100644
--- a/src/mbgl/gl/program.hpp
+++ b/src/mbgl/gl/program.hpp
@@ -30,7 +30,7 @@ public:
fragmentShader(context.createShader(ShaderType::Fragment, fragmentSource)),
program(context.createProgram(vertexShader, fragmentShader)),
attributesState(Attributes::state(program)),
- uniformsState(Uniforms::state(program)) {}
+ uniformsState((context.linkProgram(program), Uniforms::state(program))) {}
// Indexed drawing.
template <class DrawMode>