diff options
32 files changed, 370 insertions, 313 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index d912392e15..4ebb2a878d 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -73,8 +73,6 @@ set(MBGL_CORE_FILES src/mbgl/gl/program.hpp src/mbgl/gl/program_binary_extension.hpp src/mbgl/gl/renderbuffer.hpp - src/mbgl/gl/segment.cpp - src/mbgl/gl/segment.hpp src/mbgl/gl/state.hpp src/mbgl/gl/stencil_mode.cpp src/mbgl/gl/stencil_mode.hpp @@ -84,6 +82,8 @@ set(MBGL_CORE_FILES src/mbgl/gl/uniform.hpp src/mbgl/gl/value.cpp src/mbgl/gl/value.hpp + src/mbgl/gl/vertex_array.cpp + src/mbgl/gl/vertex_array.hpp src/mbgl/gl/vertex_array_extension.hpp src/mbgl/gl/vertex_buffer.hpp @@ -154,6 +154,8 @@ set(MBGL_CORE_FILES src/mbgl/programs/programs.hpp src/mbgl/programs/raster_program.cpp src/mbgl/programs/raster_program.hpp + src/mbgl/programs/segment.cpp + src/mbgl/programs/segment.hpp src/mbgl/programs/symbol_program.cpp src/mbgl/programs/symbol_program.hpp src/mbgl/programs/uniforms.hpp @@ -611,8 +613,8 @@ set(MBGL_CORE_FILES src/mbgl/util/stopwatch.cpp src/mbgl/util/stopwatch.hpp src/mbgl/util/string.cpp - src/mbgl/util/thread_local.hpp src/mbgl/util/thread.hpp + src/mbgl/util/thread_local.hpp src/mbgl/util/throttler.cpp src/mbgl/util/throttler.hpp src/mbgl/util/tile_coordinate.hpp diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 5583cfd916..bb5b2ddc34 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -1,16 +1,14 @@ #include <mbgl/gl/attribute.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/gl/gl.hpp> -#include <cstring> - namespace mbgl { namespace gl { -AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { - assert(location < 8); +void bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + if (location >= MAX_ATTRIBUTES) { + throw gl::Error("too many vertex attributes"); + } MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); - return location; } std::set<std::string> getActiveAttributes(ProgramID id) { @@ -37,58 +35,5 @@ std::set<std::string> getActiveAttributes(ProgramID id) { return activeAttributes; } -void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); -} - -template <class T> -constexpr DataType DataTypeOf() { - return std::is_same<T, int8_t>::value ? DataType::Byte : - std::is_same<T, uint8_t>::value ? DataType::UnsignedByte : - std::is_same<T, int16_t>::value ? DataType::Short : - std::is_same<T, uint16_t>::value ? DataType::UnsignedShort : - std::is_same<T, int32_t>::value ? DataType::Integer : - std::is_same<T, uint32_t>::value ? DataType::UnsignedInteger : - std::is_same<T, float>::value ? DataType::Float : static_cast<DataType>(0); -} - -template <class T, std::size_t N> -void AttributeBinding<T, N>::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { - // FillProgram will attempt to bind at location -1 because it includes - // a fill-outline-color paint property but does not use it or have an - // a_outline_color shader attribute - in this case, we have nothing to bind. - if (location == -1) return; - - context.vertexBuffer = vertexBuffer; - MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttribPointer( - location, - static_cast<GLint>(attributeSize), - static_cast<GLenum>(DataTypeOf<T>()), - static_cast<GLboolean>(false), - static_cast<GLsizei>(vertexSize), - reinterpret_cast<GLvoid*>(attributeOffset + (vertexSize * vertexOffset)))); -} - -template class AttributeBinding<uint8_t, 1>; -template class AttributeBinding<uint8_t, 2>; -template class AttributeBinding<uint8_t, 3>; -template class AttributeBinding<uint8_t, 4>; - -template class AttributeBinding<uint16_t, 1>; -template class AttributeBinding<uint16_t, 2>; -template class AttributeBinding<uint16_t, 3>; -template class AttributeBinding<uint16_t, 4>; - -template class AttributeBinding<int16_t, 1>; -template class AttributeBinding<int16_t, 2>; -template class AttributeBinding<int16_t, 3>; -template class AttributeBinding<int16_t, 4>; - -template class AttributeBinding<float, 1>; -template class AttributeBinding<float, 2>; -template class AttributeBinding<float, 3>; -template class AttributeBinding<float, 4>; - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index bc02b54bd2..1f60c8c980 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -1,59 +1,51 @@ #pragma once #include <mbgl/gl/types.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/util/ignore.hpp> #include <mbgl/util/indexed_tuple.hpp> -#include <mbgl/util/variant.hpp> +#include <mbgl/util/optional.hpp> #include <cstddef> #include <vector> #include <set> #include <functional> +#include <string> +#include <array> namespace mbgl { namespace gl { -class DisabledAttribute { -public: - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; +static constexpr std::size_t MAX_ATTRIBUTES = 8; - friend bool operator==(const DisabledAttribute&, - const DisabledAttribute&) { - return true; - } -}; +template <class> struct DataTypeOf; +template <> struct DataTypeOf< int8_t> : std::integral_constant<DataType, DataType::Byte> {}; +template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {}; +template <> struct DataTypeOf< int16_t> : std::integral_constant<DataType, DataType::Short> {}; +template <> struct DataTypeOf<uint16_t> : std::integral_constant<DataType, DataType::UnsignedShort> {}; +template <> struct DataTypeOf< int32_t> : std::integral_constant<DataType, DataType::Integer> {}; +template <> struct DataTypeOf<uint32_t> : std::integral_constant<DataType, DataType::UnsignedInteger> {}; +template <> struct DataTypeOf<float> : std::integral_constant<DataType, DataType::Float> {}; -template <class T, std::size_t N> class AttributeBinding { public: - AttributeBinding(BufferID vertexBuffer_, - std::size_t vertexSize_, - std::size_t attributeOffset_, - std::size_t attributeSize_ = N) - : vertexBuffer(vertexBuffer_), - vertexSize(vertexSize_), - attributeOffset(attributeOffset_), - attributeSize(attributeSize_) - {} - - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; + DataType attributeType; + std::size_t attributeSize; + std::size_t attributeOffset; + + BufferID vertexBuffer; + std::size_t vertexSize; + std::size_t vertexOffset; friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) { - return lhs.vertexBuffer == rhs.vertexBuffer - && lhs.vertexSize == rhs.vertexSize - && lhs.attributeOffset == rhs.attributeOffset - && lhs.attributeSize == rhs.attributeSize; + return std::tie(lhs.attributeType, lhs.attributeSize, lhs.attributeOffset, lhs.vertexBuffer, lhs.vertexSize, lhs.vertexOffset) + == std::tie(rhs.attributeType, rhs.attributeSize, rhs.attributeOffset, rhs.vertexBuffer, rhs.vertexSize, rhs.vertexOffset); } - -private: - BufferID vertexBuffer; - std::size_t vertexSize; - std::size_t attributeOffset; - std::size_t attributeSize; }; +using AttributeBindingArray = std::array<optional<AttributeBinding>, MAX_ATTRIBUTES>; + /* gl::Attribute<T,N> manages the binding of a vertex buffer to a GL program attribute. - T is the underlying primitive type (exposed as Attribute<T,N>::ValueType) @@ -67,10 +59,7 @@ public: using Value = std::array<T, N>; using Location = AttributeLocation; - - using Binding = variant< - DisabledAttribute, - AttributeBinding<T, N>>; + using Binding = AttributeBinding; /* Create a binding for this attribute. The `attributeSize` parameter may be used to @@ -82,28 +71,24 @@ public: std::size_t attributeIndex, std::size_t attributeSize = N) { static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout"); - return AttributeBinding<T, N> { + return AttributeBinding { + DataTypeOf<T>::value, + attributeSize, + Vertex::attributeOffsets[attributeIndex], buffer.buffer, sizeof(Vertex), - Vertex::attributeOffsets[attributeIndex], - attributeSize + 0, }; } - static void bind(Context& context, - const Location& location, - Binding& oldBinding, - const Binding& newBinding, - std::size_t vertexOffset) { - if (oldBinding == newBinding) { - return; + static optional<Binding> offsetBinding(const optional<Binding>& binding, std::size_t vertexOffset) { + if (binding) { + AttributeBinding result = *binding; + result.vertexOffset = vertexOffset; + return result; + } else { + return binding; } - - Binding::visit(newBinding, [&] (const auto& binding) { - binding.bind(context, location, vertexOffset); - }); - - oldBinding = newBinding; } }; @@ -223,7 +208,7 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = { } // namespace detail -AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +void bindAttributeLocation(ProgramID, AttributeLocation, const char * name); std::set<std::string> getActiveAttributes(ProgramID); template <class... As> @@ -232,10 +217,10 @@ public: using Types = TypeList<As...>; using Locations = IndexedTuple< TypeList<As...>, - TypeList<typename As::Type::Location...>>; + TypeList<optional<typename As::Type::Location>...>>; using Bindings = IndexedTuple< TypeList<As...>, - TypeList<typename As::Type::Binding...>>; + TypeList<optional<typename As::Type::Binding>...>>; using NamedLocations = std::vector<std::pair<const std::string, AttributeLocation>>; using Vertex = detail::Vertex<typename As::Type...>; @@ -243,13 +228,17 @@ public: static Locations bindLocations(const ProgramID& id) { std::set<std::string> activeAttributes = getActiveAttributes(id); - AttributeLocation location = -1; - auto bindAndIncrement = [&](const char* name) { - location++; - return bindAttributeLocation(id, location, name); + AttributeLocation location = 0; + auto maybeBindLocation = [&](const char* name) -> optional<AttributeLocation> { + if (activeAttributes.count(name)) { + bindAttributeLocation(id, location, name); + return location++; + } else { + return {}; + } }; - return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) - : -1)... }; + + return Locations { maybeBindLocation(As::name())... }; } template <class Program> @@ -258,7 +247,17 @@ public: } static NamedLocations getNamedLocations(const Locations& locations) { - return NamedLocations{ { As::name(), locations.template get<As>() }... }; + NamedLocations result; + + auto maybeAddLocation = [&] (const std::string& name, const optional<AttributeLocation>& location) { + if (location) { + result.emplace_back(name, *location); + } + }; + + util::ignore({ (maybeAddLocation(As::name(), locations.template get<As>()), 0)... }); + + return result; } template <class DrawMode> @@ -266,16 +265,23 @@ public: return Bindings { As::Type::binding(buffer, TypeIndex<As, As...>::value)... }; } - static void bind(Context& context, - const Locations& locations, - Bindings& oldBindings, - const Bindings& newBindings, - std::size_t vertexOffset) { - util::ignore({ (As::Type::bind(context, - locations.template get<As>(), - oldBindings.template get<As>(), - newBindings.template get<As>(), - vertexOffset), 0)... }); + static Bindings offsetBindings(const Bindings& bindings, std::size_t vertexOffset) { + return Bindings { As::Type::offsetBinding(bindings.template get<As>(), vertexOffset)... }; + } + + static AttributeBindingArray toBindingArray(const Locations& locations, const Bindings& bindings) { + AttributeBindingArray result; + + auto maybeAddBinding = [&] (const optional<AttributeLocation>& location, + const optional<AttributeBinding>& binding) { + if (location) { + result.at(*location) = binding; + } + }; + + util::ignore({ (maybeAddBinding(locations.template get<As>(), bindings.template get<As>()), 0)... }); + + return result; } }; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 86ca9c0607..f7d210d52e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -229,8 +229,8 @@ UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; - vertexArrayObject = 0; - elementBuffer = result; + bindVertexArray = 0; + globalVertexArrayState.indexBuffer = result; MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); return result; } @@ -281,11 +281,16 @@ optional<std::pair<BinaryProgramFormat, std::string>> Context::getBinaryProgram( } #endif -UniqueVertexArray Context::createVertexArray() { - assert(supportsVertexArrays()); - VertexArrayID id = 0; - MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return UniqueVertexArray(std::move(id), { this }); +VertexArray Context::createVertexArray() { + if (supportsVertexArrays()) { + VertexArrayID id = 0; + MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); + return { std::make_unique<VertexArrayState>(UniqueVertexArray(std::move(id), { this }), *this) }; + } else { + // On GL implementations which do not support vertex arrays, attribute bindings are global state. + // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. + return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + } } UniqueFramebuffer Context::createFramebuffer() { @@ -553,8 +558,8 @@ void Context::setDirtyState() { tex.setDirty(); } vertexBuffer.setDirty(); - elementBuffer.setDirty(); - vertexArrayObject.setDirty(); + bindVertexArray.setDirty(); + globalVertexArrayState.setDirty(); } void Context::clear(optional<mbgl::Color> color, @@ -673,8 +678,8 @@ void Context::performCleanup() { for (const auto id : abandonedBuffers) { if (vertexBuffer == id) { vertexBuffer.setDirty(); - } else if (elementBuffer == id) { - elementBuffer.setDirty(); + } else if (globalVertexArrayState.indexBuffer == id) { + globalVertexArrayState.indexBuffer.setDirty(); } } MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); @@ -694,8 +699,8 @@ void Context::performCleanup() { if (!abandonedVertexArrays.empty()) { assert(supportsVertexArrays()); for (const auto id : abandonedVertexArrays) { - if (vertexArrayObject == id) { - vertexArrayObject.setDirty(); + if (bindVertexArray == id) { + bindVertexArray.setDirty(); } } MBGL_CHECK_ERROR(vertexArray->deleteVertexArrays(int(abandonedVertexArrays.size()), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 2e594618d2..0dd67d2ed7 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -9,6 +9,7 @@ #include <mbgl/gl/framebuffer.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/types.hpp> #include <mbgl/gl/draw_mode.hpp> #include <mbgl/gl/depth_mode.hpp> @@ -53,9 +54,7 @@ public: void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createTexture(); - - bool supportsVertexArrays() const; - UniqueVertexArray createVertexArray(); + VertexArray createVertexArray(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; @@ -207,10 +206,11 @@ public: State<value::Viewport> viewport; State<value::ScissorTest> scissorTest; std::array<State<value::BindTexture>, 2> texture; - State<value::BindVertexArray, const Context&> vertexArrayObject { *this }; State<value::Program> program; State<value::BindVertexBuffer> vertexBuffer; - State<value::BindElementBuffer> elementBuffer; + + State<value::BindVertexArray, const Context&> bindVertexArray { *this }; + VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }), *this }; State<value::PixelStorePack> pixelStorePack; State<value::PixelStoreUnpack> pixelStoreUnpack; @@ -257,6 +257,8 @@ private: void drawPixels(Size size, const void* data, TextureFormat); #endif // MBGL_USE_GLES2 + bool supportsVertexArrays() const; + friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index e2d476e0c0..2c5f1bca1f 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -33,7 +33,9 @@ void TextureDeleter::operator()(TextureID id) const { void VertexArrayDeleter::operator()(VertexArrayID id) const { assert(context); - context->abandonedVertexArrays.push_back(id); + if (id != 0) { + context->abandonedVertexArrays.push_back(id); + } } void FramebufferDeleter::operator()(FramebufferID id) const { diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index ce2b5a335b..9d8b0a5b04 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -5,6 +5,7 @@ #include <mbgl/gl/context.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> @@ -116,10 +117,12 @@ public: DepthMode depthMode, StencilMode stencilMode, ColorMode colorMode, - UniformValues&& uniformValues, - AttributeBindings&& attributeBindings, + const UniformValues& uniformValues, + VertexArray& vertexArray, + const AttributeBindings& attributeBindings, const IndexBuffer<DrawMode>& indexBuffer, - const SegmentVector<Attributes>& segments) { + std::size_t indexOffset, + std::size_t indexLength) { static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::value, "incompatible draw mode"); context.setDrawMode(drawMode); @@ -129,18 +132,15 @@ public: context.program = program; - Uniforms::bind(uniformsState, std::move(uniformValues)); + Uniforms::bind(uniformsState, uniformValues); - for (const auto& segment : segments) { - segment.bind(context, - indexBuffer.buffer, - attributeLocations, - attributeBindings); + vertexArray.bind(context, + indexBuffer.buffer, + Attributes::toBindingArray(attributeLocations, attributeBindings)); - context.draw(drawMode.primitiveType, - segment.indexOffset, - segment.indexLength); - } + context.draw(drawMode.primitiveType, + indexOffset, + indexLength); } private: diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp deleted file mode 100644 index fe0658bf8e..0000000000 --- a/src/mbgl/gl/segment.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include <mbgl/gl/context.hpp> -#include <mbgl/gl/vertex_buffer.hpp> -#include <mbgl/util/optional.hpp> -#include <mbgl/util/logging.hpp> - -#include <cstddef> -#include <vector> - -namespace mbgl { -namespace gl { - -template <class Attributes> -class Segment { -public: - Segment(std::size_t vertexOffset_, - std::size_t indexOffset_, - std::size_t vertexLength_ = 0, - std::size_t indexLength_ = 0) - : vertexOffset(vertexOffset_), - indexOffset(indexOffset_), - vertexLength(vertexLength_), - indexLength(indexLength_) {} - - const std::size_t vertexOffset; - const std::size_t indexOffset; - - std::size_t vertexLength; - std::size_t indexLength; - - void bind(Context& context, - BufferID indexBuffer_, - const typename Attributes::Locations& attributeLocations, - const typename Attributes::Bindings& attributeBindings_) const { - if (context.supportsVertexArrays()) { - if (!vao) { - vao = context.createVertexArray(); - context.vertexBuffer.setDirty(); - } - context.vertexArrayObject = *vao; - if (indexBuffer != indexBuffer_) { - indexBuffer = indexBuffer_; - context.elementBuffer.setDirty(); - context.elementBuffer = indexBuffer_; - } - } else { - // No VAO support. Force attributes to be rebound. - context.elementBuffer = indexBuffer_; - attributeBindings = {}; - } - - Attributes::bind(context, - attributeLocations, - attributeBindings, - attributeBindings_, - vertexOffset); - } - -private: - mutable optional<UniqueVertexArray> vao; - mutable optional<BufferID> indexBuffer; - mutable typename Attributes::Bindings attributeBindings; -}; - -template <class Attributes> -class SegmentVector : public std::vector<Segment<Attributes>> { -public: - SegmentVector() = default; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 1fce878c6f..058bc226b8 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -15,7 +15,7 @@ using VertexArrayID = uint32_t; using FramebufferID = uint32_t; using RenderbufferID = uint32_t; -using AttributeLocation = int32_t; +using AttributeLocation = uint32_t; using UniformLocation = int32_t; using TextureUnit = uint8_t; diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 4ed2419764..5a78068fc8 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -115,7 +115,7 @@ public: return NamedLocations{ { Us::name(), state.template get<Us>().location }... }; } - static void bind(State& state, Values&& values) { + static void bind(State& state, const Values& values) { util::ignore({ (state.template get<Us>() = values.template get<Us>(), 0)... }); } }; diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp index 2b825fb2bd..89014fe6bc 100644 --- a/src/mbgl/gl/value.cpp +++ b/src/mbgl/gl/value.cpp @@ -365,6 +365,24 @@ BindVertexArray::Type BindVertexArray::Get(const Context& context) { return binding; } +const optional<AttributeBinding> VertexAttribute::Default {}; + +void VertexAttribute::Set(const optional<AttributeBinding>& binding, Context& context, AttributeLocation location) { + if (binding) { + context.vertexBuffer = binding->vertexBuffer; + MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); + MBGL_CHECK_ERROR(glVertexAttribPointer( + location, + static_cast<GLint>(binding->attributeSize), + static_cast<GLenum>(binding->attributeType), + static_cast<GLboolean>(false), + static_cast<GLsizei>(binding->vertexSize), + reinterpret_cast<GLvoid*>(binding->attributeOffset + (binding->vertexSize * binding->vertexOffset)))); + } else { + MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); + } +} + const constexpr PixelStorePack::Type PixelStorePack::Default; void PixelStorePack::Set(const Type& value) { diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp index d4c7b5cdc3..19e9af194f 100644 --- a/src/mbgl/gl/value.hpp +++ b/src/mbgl/gl/value.hpp @@ -4,6 +4,7 @@ #include <mbgl/gl/depth_mode.hpp> #include <mbgl/gl/stencil_mode.hpp> #include <mbgl/gl/color_mode.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/size.hpp> #include <mbgl/util/range.hpp> @@ -239,6 +240,12 @@ struct BindVertexArray { static Type Get(const Context&); }; +struct VertexAttribute { + using Type = optional<gl::AttributeBinding>; + static const Type Default; + static void Set(const Type&, Context&, AttributeLocation); +}; + struct PixelStorePack { using Type = PixelStorageType; static const constexpr Type Default = { 4 }; diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp new file mode 100644 index 0000000000..68a500ac45 --- /dev/null +++ b/src/mbgl/gl/vertex_array.cpp @@ -0,0 +1,18 @@ +#include <mbgl/gl/vertex_array.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/gl.hpp> + +namespace mbgl { +namespace gl { + +void VertexArray::bind(Context& context, BufferID indexBuffer, const AttributeBindingArray& bindings) { + context.bindVertexArray = state->vertexArray; + state->indexBuffer = indexBuffer; + + for (AttributeLocation location = 0; location < MAX_ATTRIBUTES; ++location) { + state->bindings[location] = bindings[location]; + } +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp new file mode 100644 index 0000000000..9ccf48d9bd --- /dev/null +++ b/src/mbgl/gl/vertex_array.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include <mbgl/gl/object.hpp> +#include <mbgl/gl/attribute.hpp> +#include <mbgl/gl/state.hpp> +#include <mbgl/gl/value.hpp> + +#include <array> +#include <memory> + +namespace mbgl { +namespace gl { + +class Context; + +class VertexArrayState { +public: + VertexArrayState(UniqueVertexArray vertexArray_, Context& context) + : vertexArray(std::move(vertexArray_)), + bindings(makeBindings(context, std::make_index_sequence<MAX_ATTRIBUTES>())) { + } + + void setDirty() { + indexBuffer.setDirty(); + for (auto& binding : bindings) { + binding.setDirty(); + } + } + + UniqueVertexArray vertexArray; + State<value::BindElementBuffer> indexBuffer; + + using AttributeState = State<value::VertexAttribute, Context&, AttributeLocation>; + std::array<AttributeState, MAX_ATTRIBUTES> bindings; + +private: + template <std::size_t... I> + std::array<AttributeState, MAX_ATTRIBUTES> makeBindings(Context& context, std::index_sequence<I...>) { + return {{ AttributeState { context, I }... }}; + } +}; + +using UniqueVertexArrayState = std::unique_ptr<VertexArrayState, std::function<void (VertexArrayState*)>>; + +class VertexArray { +public: + VertexArray(UniqueVertexArrayState state_) + : state(std::move(state_)) { + } + + void bind(Context&, BufferID indexBuffer, const AttributeBindingArray&); + +private: + UniqueVertexArrayState state; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/binary_program.cpp b/src/mbgl/programs/binary_program.cpp index 57f2cc0d2c..da629194b4 100644 --- a/src/mbgl/programs/binary_program.cpp +++ b/src/mbgl/programs/binary_program.cpp @@ -98,7 +98,7 @@ std::string BinaryProgram::serialize() const { return data; } -gl::AttributeLocation BinaryProgram::attributeLocation(const std::string& name) const { +optional<gl::AttributeLocation> BinaryProgram::attributeLocation(const std::string& name) const { for (const auto& pair : attributes) { if (pair.first == name) { return pair.second; @@ -113,7 +113,7 @@ gl::UniformLocation BinaryProgram::uniformLocation(const std::string& name) cons return pair.second; } } - return {}; + return -1; } } // namespace mbgl diff --git a/src/mbgl/programs/binary_program.hpp b/src/mbgl/programs/binary_program.hpp index b77cf1a510..8690f3fd6f 100644 --- a/src/mbgl/programs/binary_program.hpp +++ b/src/mbgl/programs/binary_program.hpp @@ -1,6 +1,7 @@ #pragma once #include <mbgl/gl/types.hpp> +#include <mbgl/util/optional.hpp> #include <string> #include <vector> @@ -29,7 +30,8 @@ public: const std::string& identifier() const { return binaryIdentifier; } - gl::AttributeLocation attributeLocation(const std::string& name) const; + + optional<gl::AttributeLocation> attributeLocation(const std::string& name) const; gl::UniformLocation uniformLocation(const std::string& name) const; private: diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 3a38f30a86..0199752b06 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -2,6 +2,7 @@ #include <mbgl/gl/program.hpp> #include <mbgl/gl/features.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/binary_program.hpp> #include <mbgl/programs/attributes.hpp> #include <mbgl/programs/program_parameters.hpp> @@ -51,26 +52,37 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer, const gl::IndexBuffer<DrawMode>& indexBuffer, - const gl::SegmentVector<Attributes>& segments, + const SegmentVector<Attributes>& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/gl/segment.cpp b/src/mbgl/programs/segment.cpp index aabdc83cd4..bb09843e21 100644 --- a/src/mbgl/gl/segment.cpp +++ b/src/mbgl/programs/segment.cpp @@ -1,4 +1,4 @@ -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> namespace mbgl { namespace gl { diff --git a/src/mbgl/programs/segment.hpp b/src/mbgl/programs/segment.hpp new file mode 100644 index 0000000000..d8cc9679d7 --- /dev/null +++ b/src/mbgl/programs/segment.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/vertex_array.hpp> +#include <mbgl/util/optional.hpp> + +#include <cstddef> +#include <vector> +#include <map> + +namespace mbgl { + +template <class Attributes> +class Segment { +public: + Segment(std::size_t vertexOffset_, + std::size_t indexOffset_, + std::size_t vertexLength_ = 0, + std::size_t indexLength_ = 0) + : vertexOffset(vertexOffset_), + indexOffset(indexOffset_), + vertexLength(vertexLength_), + indexLength(indexLength_) {} + + const std::size_t vertexOffset; + const std::size_t indexOffset; + + std::size_t vertexLength; + std::size_t indexLength; + + mutable optional<gl::VertexArray> vertexArray; +}; + +template <class Attributes> +class SegmentVector : public std::vector<Segment<Attributes>> { +public: + SegmentVector() = default; +}; + +} // namespace mbgl diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index c74837b121..8c59cfd5a2 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -7,6 +7,7 @@ #include <mbgl/programs/attributes.hpp> #include <mbgl/programs/uniforms.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/shaders/symbol_icon.hpp> #include <mbgl/shaders/symbol_sdf.hpp> #include <mbgl/util/geometry.hpp> @@ -306,30 +307,41 @@ public: gl::DepthMode depthMode, gl::StencilMode stencilMode, gl::ColorMode colorMode, - UniformValues&& uniformValues, + const UniformValues& uniformValues, const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer, const gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>& dynamicLayoutVertexBuffer, const SymbolSizeBinder& symbolSizeBinder, const gl::IndexBuffer<DrawMode>& indexBuffer, - const gl::SegmentVector<Attributes>& segments, + const SegmentVector<Attributes>& segments, const PaintPropertyBinders& paintPropertyBinders, const typename PaintProperties::PossiblyEvaluated& currentProperties, float currentZoom) { - program.draw( - context, - std::move(drawMode), - std::move(depthMode), - std::move(stencilMode), - std::move(colorMode), - uniformValues - .concat(symbolSizeBinder.uniformValues(currentZoom)) - .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)), - LayoutAttributes::bindings(layoutVertexBuffer) - .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer)) - .concat(paintPropertyBinders.attributeBindings(currentProperties)), - indexBuffer, - segments - ); + typename AllUniforms::Values allUniformValues = uniformValues + .concat(symbolSizeBinder.uniformValues(currentZoom)) + .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); + + typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer) + .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer)) + .concat(paintPropertyBinders.attributeBindings(currentProperties)); + + for (auto& segment : segments) { + if (!segment.vertexArray) { + segment.vertexArray = context.createVertexArray(); + } + + program.draw( + context, + std::move(drawMode), + std::move(depthMode), + std::move(stencilMode), + std::move(colorMode), + allUniformValues, + *segment.vertexArray, + Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), + indexBuffer, + segment.indexOffset, + segment.indexLength); + } } }; diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index b048fd7675..0f27e2a7e3 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -5,7 +5,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/circle_program.hpp> #include <mbgl/style/layers/circle_layer_properties.hpp> @@ -29,7 +29,7 @@ public: gl::VertexVector<CircleLayoutVertex> vertices; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<CircleAttributes> segments; + SegmentVector<CircleAttributes> segments; optional<gl::VertexBuffer<CircleLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; diff --git a/src/mbgl/renderer/buckets/debug_bucket.hpp b/src/mbgl/renderer/buckets/debug_bucket.hpp index 756e58a6de..fc3128e944 100644 --- a/src/mbgl/renderer/buckets/debug_bucket.hpp +++ b/src/mbgl/renderer/buckets/debug_bucket.hpp @@ -33,7 +33,7 @@ public: const optional<Timestamp> expires; const MapDebugOptions debugMode; - gl::SegmentVector<DebugAttributes> segments; + SegmentVector<DebugAttributes> segments; optional<gl::VertexBuffer<DebugLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Lines>> indexBuffer; }; diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 421d8b332b..d3cd92d451 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -4,7 +4,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/fill_program.hpp> #include <mbgl/style/layers/fill_layer_properties.hpp> @@ -30,8 +30,8 @@ public: gl::VertexVector<FillLayoutVertex> vertices; gl::IndexVector<gl::Lines> lines; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<FillAttributes> lineSegments; - gl::SegmentVector<FillAttributes> triangleSegments; + SegmentVector<FillAttributes> lineSegments; + SegmentVector<FillAttributes> triangleSegments; optional<gl::VertexBuffer<FillLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Lines>> lineIndexBuffer; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index c54805d743..d1e695c5a3 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -4,7 +4,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/fill_extrusion_program.hpp> #include <mbgl/style/layers/fill_extrusion_layer_properties.hpp> @@ -27,7 +27,7 @@ public: gl::VertexVector<FillExtrusionLayoutVertex> vertices; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<FillExtrusionAttributes> triangleSegments; + SegmentVector<FillExtrusionAttributes> triangleSegments; optional<gl::VertexBuffer<FillExtrusionLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 34d8935953..c0a0614d33 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -4,7 +4,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/line_program.hpp> #include <mbgl/style/layers/line_layer_properties.hpp> @@ -34,7 +34,7 @@ public: gl::VertexVector<LineLayoutVertex> vertices; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<LineAttributes> segments; + SegmentVector<LineAttributes> segments; optional<gl::VertexBuffer<LineLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index b5cf7997d5..44b9111b81 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -31,7 +31,7 @@ public: // Raster Tile Sources use the default buffers from Painter gl::VertexVector<RasterLayoutVertex> vertices; gl::IndexVector<gl::Triangles> indices; - gl::SegmentVector<RasterAttributes> segments; + SegmentVector<RasterAttributes> segments; optional<gl::VertexBuffer<RasterLayoutVertex>> vertexBuffer; optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index ffa22e9021..424c9d0f74 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -4,7 +4,7 @@ #include <mbgl/map/mode.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/programs/segment.hpp> #include <mbgl/programs/symbol_program.hpp> #include <mbgl/programs/collision_box_program.hpp> #include <mbgl/text/glyph_range.hpp> @@ -63,7 +63,7 @@ public: gl::VertexVector<SymbolLayoutVertex> vertices; gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<SymbolTextAttributes> segments; + SegmentVector<SymbolTextAttributes> segments; std::vector<PlacedSymbol> placedSymbols; optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer; @@ -77,7 +77,7 @@ public: gl::VertexVector<SymbolLayoutVertex> vertices; gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices; gl::IndexVector<gl::Triangles> triangles; - gl::SegmentVector<SymbolIconAttributes> segments; + SegmentVector<SymbolIconAttributes> segments; std::vector<PlacedSymbol> placedSymbols; PremultipliedImage atlasImage; @@ -89,7 +89,7 @@ public: struct CollisionBoxBuffer { gl::VertexVector<CollisionBoxVertex> vertices; gl::IndexVector<gl::Lines> lines; - gl::SegmentVector<CollisionBoxAttributes> segments; + SegmentVector<CollisionBoxAttributes> segments; optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer; optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer; diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index 4d6084075d..81b8ac301b 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -48,7 +48,7 @@ void RenderCustomLayer::render(Painter& painter, PaintParameters& paintParameter const TransformState& state = painter.state; // Reset GL state to a known state so the CustomLayer always has a clean slate. - context.vertexArrayObject = 0; + context.bindVertexArray = 0; context.setDepthMode(painter.depthModeForSublayer(0, gl::DepthMode::ReadOnly)); context.setStencilMode(gl::StencilMode::disabled()); context.setColorMode(painter.colorModeForRenderPass()); diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index f78147fc87..652948c8df 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -3,6 +3,7 @@ #include <mbgl/programs/attributes.hpp> #include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> +#include <mbgl/gl/context.hpp> #include <mbgl/util/type_list.hpp> #include <mbgl/renderer/possibly_evaluated_property_value.hpp> #include <mbgl/renderer/paint_property_statistics.hpp> @@ -81,7 +82,7 @@ public: virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0; virtual void upload(gl::Context& context) = 0; - virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0; + virtual optional<AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0; virtual float interpolationFactor(float currentZoom) const = 0; virtual T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0; @@ -103,8 +104,8 @@ public: void populateVertexVector(const GeometryTileFeature&, std::size_t) override {} void upload(gl::Context&) override {} - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const override { - return gl::DisabledAttribute(); + optional<AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const override { + return {}; } float interpolationFactor(float) const override { @@ -147,9 +148,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + optional<AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0, BaseAttribute::Dimensions); } @@ -208,9 +209,9 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + optional<AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { - return gl::DisabledAttribute(); + return {}; } else { return Attribute::binding(*vertexBuffer, 0); } diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index a3decdb603..35d03e7cb4 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -262,7 +262,7 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) { context.activeTexture = 0; context.texture[0] = 0; - context.vertexArrayObject = 0; + context.bindVertexArray = 0; } } diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 7e966adefa..0b6ee3497e 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -172,10 +172,10 @@ public: gl::IndexBuffer<gl::Triangles> quadTriangleIndexBuffer; gl::IndexBuffer<gl::LineStrip> tileBorderIndexBuffer; - gl::SegmentVector<FillAttributes> tileTriangleSegments; - gl::SegmentVector<DebugAttributes> tileBorderSegments; - gl::SegmentVector<RasterAttributes> rasterSegments; - gl::SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments; + SegmentVector<FillAttributes> tileTriangleSegments; + SegmentVector<DebugAttributes> tileBorderSegments; + SegmentVector<RasterAttributes> rasterSegments; + SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments; }; } // namespace mbgl diff --git a/test/programs/binary_program.test.cpp b/test/programs/binary_program.test.cpp index ce544e7652..a5cf7b6e39 100644 --- a/test/programs/binary_program.test.cpp +++ b/test/programs/binary_program.test.cpp @@ -14,12 +14,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram.format()); EXPECT_EQ("binary code", binaryProgram.code()); EXPECT_EQ("identifier", binaryProgram.identifier()); - EXPECT_EQ(1, binaryProgram.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram.uniformLocation("a_data")); auto serialized = binaryProgram.serialize(); @@ -28,12 +28,12 @@ TEST(BinaryProgram, ObtainValues) { EXPECT_EQ(42u, binaryProgram2.format()); EXPECT_EQ("binary code", binaryProgram2.code()); EXPECT_EQ("identifier", binaryProgram2.identifier()); - EXPECT_EQ(1, binaryProgram2.attributeLocation("a_pos")); - EXPECT_EQ(0, binaryProgram2.attributeLocation("u_world")); - EXPECT_EQ(4, binaryProgram2.attributeLocation("a_data")); + EXPECT_EQ(1u, binaryProgram2.attributeLocation("a_pos")); + EXPECT_FALSE(binaryProgram2.attributeLocation("u_world")); + EXPECT_EQ(4u, binaryProgram2.attributeLocation("a_data")); EXPECT_EQ(1, binaryProgram2.uniformLocation("u_world")); EXPECT_EQ(3, binaryProgram2.uniformLocation("u_ratio")); - EXPECT_EQ(0, binaryProgram2.uniformLocation("a_data")); + EXPECT_EQ(-1, binaryProgram2.uniformLocation("a_data")); EXPECT_THROW(BinaryProgram(""), std::runtime_error); } |