summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp10
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp1
-rw-r--r--src/mbgl/annotation/annotation_tile.cpp2
-rw-r--r--src/mbgl/annotation/annotation_tile.hpp2
-rw-r--r--src/mbgl/geometry/buffer.hpp31
-rw-r--r--src/mbgl/geometry/circle_buffer.cpp2
-rw-r--r--src/mbgl/geometry/collision_box_buffer.cpp2
-rw-r--r--src/mbgl/geometry/debug_font_buffer.cpp2
-rw-r--r--src/mbgl/geometry/fill_buffer.cpp2
-rw-r--r--src/mbgl/geometry/glyph_atlas.cpp21
-rw-r--r--src/mbgl/geometry/glyph_atlas.hpp9
-rw-r--r--src/mbgl/geometry/icon_buffer.cpp2
-rw-r--r--src/mbgl/geometry/line_atlas.cpp29
-rw-r--r--src/mbgl/geometry/line_atlas.hpp14
-rw-r--r--src/mbgl/geometry/line_buffer.cpp2
-rw-r--r--src/mbgl/geometry/static_vertex_buffer.cpp2
-rw-r--r--src/mbgl/geometry/text_buffer.cpp2
-rw-r--r--src/mbgl/geometry/vao.cpp52
-rw-r--r--src/mbgl/geometry/vao.hpp28
-rw-r--r--src/mbgl/gl/debugging.cpp2
-rw-r--r--src/mbgl/gl/gl.cpp (renamed from src/mbgl/platform/gl.cpp)2
-rw-r--r--src/mbgl/gl/gl_config.cpp (renamed from src/mbgl/renderer/gl_config.cpp)0
-rw-r--r--src/mbgl/gl/gl_config.hpp100
-rw-r--r--src/mbgl/gl/gl_object_store.cpp120
-rw-r--r--src/mbgl/gl/gl_object_store.hpp141
-rw-r--r--src/mbgl/gl/texture_pool.cpp41
-rw-r--r--src/mbgl/gl/texture_pool.hpp41
-rw-r--r--src/mbgl/layer/background_layer.hpp6
-rw-r--r--src/mbgl/layer/circle_layer.hpp6
-rw-r--r--src/mbgl/layer/custom_layer.cpp3
-rw-r--r--src/mbgl/layer/custom_layer.hpp5
-rw-r--r--src/mbgl/layer/fill_layer.hpp6
-rw-r--r--src/mbgl/layer/line_layer.cpp2
-rw-r--r--src/mbgl/layer/line_layer.hpp6
-rw-r--r--src/mbgl/layer/raster_layer.hpp6
-rw-r--r--src/mbgl/layer/symbol_layer.hpp8
-rw-r--r--src/mbgl/map/map.cpp5
-rw-r--r--src/mbgl/map/map_context.cpp31
-rw-r--r--src/mbgl/map/map_context.hpp10
-rw-r--r--src/mbgl/map/raster_tile_data.cpp88
-rw-r--r--src/mbgl/map/tile.cpp3
-rw-r--r--src/mbgl/map/tile_id.hpp23
-rw-r--r--src/mbgl/map/transform_state.cpp13
-rw-r--r--src/mbgl/map/transform_state.hpp4
-rw-r--r--src/mbgl/renderer/bucket.hpp8
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp10
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp6
-rw-r--r--src/mbgl/renderer/debug_bucket.cpp14
-rw-r--r--src/mbgl/renderer/debug_bucket.hpp10
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp22
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp10
-rw-r--r--src/mbgl/renderer/gl_config.hpp330
-rw-r--r--src/mbgl/renderer/line_bucket.cpp70
-rw-r--r--src/mbgl/renderer/line_bucket.hpp14
-rw-r--r--src/mbgl/renderer/painter.cpp62
-rw-r--r--src/mbgl/renderer/painter.hpp17
-rw-r--r--src/mbgl/renderer/painter_circle.cpp4
-rw-r--r--src/mbgl/renderer/painter_clipping.cpp39
-rw-r--r--src/mbgl/renderer/painter_debug.cpp20
-rw-r--r--src/mbgl/renderer/painter_fill.cpp18
-rw-r--r--src/mbgl/renderer/painter_line.cpp20
-rw-r--r--src/mbgl/renderer/painter_raster.cpp6
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp48
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp12
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp6
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp28
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp12
-rw-r--r--src/mbgl/shader/box_shader.cpp10
-rw-r--r--src/mbgl/shader/box_shader.hpp4
-rw-r--r--src/mbgl/shader/circle_shader.cpp6
-rw-r--r--src/mbgl/shader/circle_shader.hpp2
-rw-r--r--src/mbgl/shader/dot_shader.cpp5
-rw-r--r--src/mbgl/shader/dot_shader.hpp2
-rw-r--r--src/mbgl/shader/icon_shader.cpp11
-rw-r--r--src/mbgl/shader/icon_shader.hpp2
-rw-r--r--src/mbgl/shader/line_shader.cpp7
-rw-r--r--src/mbgl/shader/line_shader.hpp2
-rw-r--r--src/mbgl/shader/linepattern_shader.cpp8
-rw-r--r--src/mbgl/shader/linepattern_shader.hpp2
-rw-r--r--src/mbgl/shader/linesdf_shader.cpp8
-rw-r--r--src/mbgl/shader/linesdf_shader.hpp2
-rw-r--r--src/mbgl/shader/outline_shader.cpp6
-rw-r--r--src/mbgl/shader/outline_shader.hpp2
-rw-r--r--src/mbgl/shader/pattern_shader.cpp7
-rw-r--r--src/mbgl/shader/pattern_shader.hpp2
-rw-r--r--src/mbgl/shader/plain_shader.cpp5
-rw-r--r--src/mbgl/shader/plain_shader.hpp2
-rw-r--r--src/mbgl/shader/raster_shader.cpp6
-rw-r--r--src/mbgl/shader/raster_shader.hpp2
-rw-r--r--src/mbgl/shader/sdf_shader.cpp11
-rw-r--r--src/mbgl/shader/sdf_shader.hpp4
-rw-r--r--src/mbgl/shader/shader.cpp78
-rw-r--r--src/mbgl/shader/shader.hpp21
-rw-r--r--src/mbgl/shader/uniform.hpp8
-rw-r--r--src/mbgl/source/source.cpp (renamed from src/mbgl/map/source.cpp)210
-rw-r--r--src/mbgl/source/source.hpp (renamed from src/mbgl/map/source.hpp)20
-rw-r--r--src/mbgl/source/source_info.hpp (renamed from src/mbgl/map/source_info.hpp)0
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp23
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp9
-rw-r--r--src/mbgl/sprite/sprite_store.cpp34
-rw-r--r--src/mbgl/sprite/sprite_store.hpp4
-rw-r--r--src/mbgl/storage/http_context_base.hpp1
-rw-r--r--src/mbgl/storage/resource.cpp3
-rw-r--r--src/mbgl/storage/response.cpp23
-rw-r--r--src/mbgl/storage/sqlite_cache.hpp44
-rw-r--r--src/mbgl/style/filter_expression.cpp2
-rw-r--r--src/mbgl/style/function.hpp3
-rw-r--r--src/mbgl/style/style.cpp18
-rw-r--r--src/mbgl/style/style.hpp12
-rw-r--r--src/mbgl/style/style_bucket_parameters.cpp2
-rw-r--r--src/mbgl/style/style_bucket_parameters.hpp2
-rw-r--r--src/mbgl/style/style_layer.hpp27
-rw-r--r--src/mbgl/style/style_parser.cpp31
-rw-r--r--src/mbgl/style/style_parser.hpp7
-rw-r--r--src/mbgl/style/style_update_parameters.hpp10
-rw-r--r--src/mbgl/text/get_anchors.cpp16
-rw-r--r--src/mbgl/text/glyph_pbf.cpp33
-rw-r--r--src/mbgl/text/glyph_pbf.hpp4
-rw-r--r--src/mbgl/text/glyph_store.cpp7
-rw-r--r--src/mbgl/text/glyph_store.hpp4
-rw-r--r--src/mbgl/tile/geojson_tile.hpp2
-rw-r--r--src/mbgl/tile/geometry_tile.cpp (renamed from src/mbgl/map/geometry_tile.cpp)2
-rw-r--r--src/mbgl/tile/geometry_tile.hpp (renamed from src/mbgl/map/geometry_tile.hpp)0
-rw-r--r--src/mbgl/tile/raster_tile_data.cpp83
-rw-r--r--src/mbgl/tile/raster_tile_data.hpp (renamed from src/mbgl/map/raster_tile_data.hpp)10
-rw-r--r--src/mbgl/tile/tile.cpp3
-rw-r--r--src/mbgl/tile/tile.hpp (renamed from src/mbgl/map/tile.hpp)0
-rw-r--r--src/mbgl/tile/tile_cache.cpp (renamed from src/mbgl/map/tile_cache.cpp)3
-rw-r--r--src/mbgl/tile/tile_cache.hpp (renamed from src/mbgl/map/tile_cache.hpp)6
-rw-r--r--src/mbgl/tile/tile_data.cpp (renamed from src/mbgl/map/tile_data.cpp)2
-rw-r--r--src/mbgl/tile/tile_data.hpp (renamed from src/mbgl/map/tile_data.hpp)0
-rw-r--r--src/mbgl/tile/tile_worker.cpp (renamed from src/mbgl/map/tile_worker.cpp)4
-rw-r--r--src/mbgl/tile/tile_worker.hpp (renamed from src/mbgl/map/tile_worker.hpp)2
-rw-r--r--src/mbgl/tile/vector_tile.cpp (renamed from src/mbgl/map/vector_tile.cpp)33
-rw-r--r--src/mbgl/tile/vector_tile.hpp (renamed from src/mbgl/map/vector_tile.hpp)6
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp (renamed from src/mbgl/map/vector_tile_data.cpp)4
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp (renamed from src/mbgl/map/vector_tile_data.hpp)4
-rw-r--r--src/mbgl/util/box.hpp16
-rw-r--r--src/mbgl/util/clip_id.cpp113
-rw-r--r--src/mbgl/util/clip_id.hpp20
-rw-r--r--src/mbgl/util/clip_lines.cpp16
-rw-r--r--src/mbgl/util/constants.cpp76
-rw-r--r--src/mbgl/util/get_geometries.cpp6
-rw-r--r--src/mbgl/util/get_geometries.hpp2
-rw-r--r--src/mbgl/util/gl_object_store.cpp50
-rw-r--r--src/mbgl/util/gl_object_store.hpp35
-rw-r--r--src/mbgl/util/mapbox.cpp93
-rw-r--r--src/mbgl/util/mapbox.hpp9
-rw-r--r--src/mbgl/util/raster.cpp19
-rw-r--r--src/mbgl/util/raster.hpp14
-rw-r--r--src/mbgl/util/texture_pool.cpp53
-rw-r--r--src/mbgl/util/texture_pool.hpp25
-rw-r--r--src/mbgl/util/thread_context.cpp32
-rw-r--r--src/mbgl/util/thread_context.hpp13
-rw-r--r--src/mbgl/util/tile_coordinate.hpp16
-rw-r--r--src/mbgl/util/tile_cover.cpp75
-rw-r--r--src/mbgl/util/tile_cover.hpp12
-rw-r--r--src/mbgl/util/worker.cpp2
-rw-r--r--src/mbgl/util/worker.hpp2
159 files changed, 1672 insertions, 1638 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 52f8b08ad3..5f5feb456a 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -48,6 +48,16 @@ AnnotationManager::addShapeAnnotations(const std::vector<ShapeAnnotation>& shape
return annotationIDs;
}
+void AnnotationManager::updatePointAnnotation(const AnnotationID& id, const PointAnnotation& point, const uint8_t) {
+ auto foundAnnotation = pointAnnotations.find(id);
+ if (foundAnnotation != pointAnnotations.end()) {
+ auto updatedAnnotation = std::make_shared<PointAnnotationImpl>(id, point);
+ pointTree.remove(foundAnnotation->second);
+ pointTree.insert(updatedAnnotation);
+ foundAnnotation->second = updatedAnnotation;
+ }
+}
+
void AnnotationManager::removeAnnotations(const AnnotationIDs& ids) {
for (const auto& id : ids) {
if (pointAnnotations.find(id) != pointAnnotations.end()) {
diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp
index 163c7129c7..11860047c2 100644
--- a/src/mbgl/annotation/annotation_manager.hpp
+++ b/src/mbgl/annotation/annotation_manager.hpp
@@ -28,6 +28,7 @@ public:
AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
AnnotationIDs addShapeAnnotations(const std::vector<ShapeAnnotation>&, const uint8_t maxZoom);
+ void updatePointAnnotation(const AnnotationID&, const PointAnnotation&, const uint8_t maxZoom);
void removeAnnotations(const AnnotationIDs&);
AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&) const;
diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp
index a4590ffe30..3a038cc6eb 100644
--- a/src/mbgl/annotation/annotation_tile.cpp
+++ b/src/mbgl/annotation/annotation_tile.cpp
@@ -10,7 +10,7 @@ AnnotationTileFeature::AnnotationTileFeature(FeatureType type_, GeometryCollecti
std::unordered_map<std::string, std::string> properties_)
: type(type_),
properties(std::move(properties_)),
- geometries(geometries_) {}
+ geometries(std::move(geometries_)) {}
optional<Value> AnnotationTileFeature::getValue(const std::string& key) const {
auto it = properties.find(key);
diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp
index 742a4114a8..b2d98c6a3b 100644
--- a/src/mbgl/annotation/annotation_tile.hpp
+++ b/src/mbgl/annotation/annotation_tile.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_ANNOTATION_TILE
#define MBGL_ANNOTATION_TILE
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/map/tile_id.hpp>
#include <map>
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp
index c7278a1036..143597ed0a 100644
--- a/src/mbgl/geometry/buffer.hpp
+++ b/src/mbgl/geometry/buffer.hpp
@@ -1,12 +1,13 @@
#ifndef MBGL_GEOMETRY_BUFFER
#define MBGL_GEOMETRY_BUFFER
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/platform/log.hpp>
-#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/thread_context.hpp>
+#include <memory>
#include <cstdlib>
#include <cassert>
#include <stdexcept>
@@ -23,10 +24,6 @@ class Buffer : private util::noncopyable {
public:
~Buffer() {
cleanup();
- if (buffer != 0) {
- util::ThreadContext::getGLObjectStore()->abandonBuffer(buffer);
- buffer = 0;
- }
}
// Returns the number of elements in this buffer. This is not the number of
@@ -40,12 +37,12 @@ public:
}
// Transfers this buffer to the GPU and binds the buffer to the GL context.
- void bind() {
+ void bind(gl::GLObjectStore& glObjectStore) {
if (buffer) {
- MBGL_CHECK_ERROR(glBindBuffer(bufferType, buffer));
+ MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
} else {
- MBGL_CHECK_ERROR(glGenBuffers(1, &buffer));
- MBGL_CHECK_ERROR(glBindBuffer(bufferType, buffer));
+ buffer.create(glObjectStore);
+ MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
if (array == nullptr) {
Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
pos = 0;
@@ -64,21 +61,21 @@ public:
}
}
- inline GLuint getID() const {
- return buffer;
+ GLuint getID() const {
+ return buffer.getID();
}
// Uploads the buffer to the GPU to be available when we need it.
- inline void upload() {
+ inline void upload(gl::GLObjectStore& glObjectStore) {
if (!buffer) {
- bind();
+ bind(glObjectStore);
}
}
protected:
// increase the buffer size by at least /required/ bytes.
inline void *addElement() {
- if (buffer != 0) {
+ if (buffer) {
throw std::runtime_error("Can't add elements after buffer was bound to GPU");
}
if (length < pos + itemSize) {
@@ -118,8 +115,8 @@ private:
// Number of bytes that are valid in this buffer.
size_t length = 0;
- // GL buffer ID
- GLuint buffer = 0;
+ // GL buffer object handle.
+ gl::BufferHolder buffer;
};
} // namespace mbgl
diff --git a/src/mbgl/geometry/circle_buffer.cpp b/src/mbgl/geometry/circle_buffer.cpp
index f4b0cddec3..74ccfa8267 100644
--- a/src/mbgl/geometry/circle_buffer.cpp
+++ b/src/mbgl/geometry/circle_buffer.cpp
@@ -1,6 +1,6 @@
#include <mbgl/geometry/circle_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <climits>
diff --git a/src/mbgl/geometry/collision_box_buffer.cpp b/src/mbgl/geometry/collision_box_buffer.cpp
index f4f8075e10..a47267d566 100644
--- a/src/mbgl/geometry/collision_box_buffer.cpp
+++ b/src/mbgl/geometry/collision_box_buffer.cpp
@@ -1,5 +1,5 @@
#include <mbgl/geometry/collision_box_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/math.hpp>
#include <cmath>
diff --git a/src/mbgl/geometry/debug_font_buffer.cpp b/src/mbgl/geometry/debug_font_buffer.cpp
index e4af707660..5df67accd6 100644
--- a/src/mbgl/geometry/debug_font_buffer.cpp
+++ b/src/mbgl/geometry/debug_font_buffer.cpp
@@ -1,7 +1,7 @@
#include <mbgl/geometry/debug_font_buffer.hpp>
#include <mbgl/geometry/debug_font_data.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cmath>
#include <cstring>
diff --git a/src/mbgl/geometry/fill_buffer.cpp b/src/mbgl/geometry/fill_buffer.cpp
index 3392699431..ee70dfc53b 100644
--- a/src/mbgl/geometry/fill_buffer.cpp
+++ b/src/mbgl/geometry/fill_buffer.cpp
@@ -1,6 +1,6 @@
#include <mbgl/geometry/fill_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <climits>
diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp
index b90444e582..24c1b8c8db 100644
--- a/src/mbgl/geometry/glyph_atlas.cpp
+++ b/src/mbgl/geometry/glyph_atlas.cpp
@@ -2,10 +2,10 @@
#include <mbgl/text/font_stack.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/thread_context.hpp>
#include <cassert>
@@ -24,11 +24,6 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_)
GlyphAtlas::~GlyphAtlas() {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
-
- if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
- }
}
void GlyphAtlas::addGlyphs(uintptr_t tileUID,
@@ -151,10 +146,10 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
}
}
-void GlyphAtlas::upload() {
+void GlyphAtlas::upload(gl::GLObjectStore& glObjectStore) {
if (dirty) {
const bool first = !texture;
- bind();
+ bind(glObjectStore);
std::lock_guard<std::mutex> lock(mtx);
@@ -192,10 +187,10 @@ void GlyphAtlas::upload() {
}
}
-void GlyphAtlas::bind() {
+void GlyphAtlas::bind(gl::GLObjectStore& glObjectStore) {
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create(glObjectStore);
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -204,6 +199,6 @@ void GlyphAtlas::bind() {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
};
diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp
index 5b4ae1fc6b..2758ac7cee 100644
--- a/src/mbgl/geometry/glyph_atlas.hpp
+++ b/src/mbgl/geometry/glyph_atlas.hpp
@@ -4,7 +4,8 @@
#include <mbgl/geometry/binpack.hpp>
#include <mbgl/text/glyph_store.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <string>
#include <set>
@@ -27,11 +28,11 @@ public:
void removeGlyphs(uintptr_t tileUID);
// Binds the atlas texture to the GPU, and uploads data if it is out of date.
- void bind();
+ void bind(gl::GLObjectStore&);
// Uploads the texture to the GPU to be available when we need it. This is a lazy operation;
// the texture is only bound when the data is out of date (=dirty).
- void upload();
+ void upload(gl::GLObjectStore&);
const GLsizei width;
const GLsizei height;
@@ -53,7 +54,7 @@ private:
std::map<std::string, std::map<uint32_t, GlyphValue>> index;
const std::unique_ptr<uint8_t[]> data;
std::atomic<bool> dirty;
- GLuint texture = 0;
+ gl::TextureHolder texture;
};
} // namespace mbgl
diff --git a/src/mbgl/geometry/icon_buffer.cpp b/src/mbgl/geometry/icon_buffer.cpp
index 4e6a1c52e7..101132ddbc 100644
--- a/src/mbgl/geometry/icon_buffer.cpp
+++ b/src/mbgl/geometry/icon_buffer.cpp
@@ -1,5 +1,5 @@
#include <mbgl/geometry/icon_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/math.hpp>
#include <cmath>
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index bbda2dce6f..9b133319dc 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -1,8 +1,8 @@
#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/thread_context.hpp>
#include <boost/functional/hash.hpp>
@@ -21,14 +21,9 @@ LineAtlas::LineAtlas(GLsizei w, GLsizei h)
LineAtlas::~LineAtlas() {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
-
- if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
- }
}
-LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round) {
+LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round, gl::GLObjectStore& glObjectStore) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
size_t key = round ? std::numeric_limits<size_t>::min() : std::numeric_limits<size_t>::max();
@@ -39,7 +34,7 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, b
// Note: We're not handling hash collisions here.
const auto it = positions.find(key);
if (it == positions.end()) {
- auto inserted = positions.emplace(key, addDash(dasharray, round));
+ auto inserted = positions.emplace(key, addDash(dasharray, round, glObjectStore));
assert(inserted.second);
return inserted.first->second;
} else {
@@ -47,7 +42,7 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, b
}
}
-LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool round) {
+LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool round, gl::GLObjectStore& glObjectStore) {
int n = round ? 7 : 0;
int dashheight = 2 * n + 1;
@@ -125,31 +120,31 @@ LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool roun
nextRow += dashheight;
dirty = true;
- bind();
+ bind(glObjectStore);
return position;
};
-void LineAtlas::upload() {
+void LineAtlas::upload(gl::GLObjectStore& glObjectStore) {
if (dirty) {
- bind();
+ bind(glObjectStore);
}
}
-void LineAtlas::bind() {
+void LineAtlas::bind(gl::GLObjectStore& glObjectStore) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
bool first = false;
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create(glObjectStore);
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
first = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
if (dirty) {
diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp
index e76a91b61d..e94b399457 100644
--- a/src/mbgl/geometry/line_atlas.hpp
+++ b/src/mbgl/geometry/line_atlas.hpp
@@ -1,11 +1,11 @@
#ifndef MBGL_GEOMETRY_LINE_ATLAS
#define MBGL_GEOMETRY_LINE_ATLAS
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <vector>
#include <map>
-#include <memory>
namespace mbgl {
@@ -21,14 +21,14 @@ public:
~LineAtlas();
// Binds the atlas texture to the GPU, and uploads data if it is out of date.
- void bind();
+ void bind(gl::GLObjectStore&);
// Uploads the texture to the GPU to be available when we need it. This is a lazy operation;
// the texture is only bound when the data is out of date (=dirty).
- void upload();
+ void upload(gl::GLObjectStore&);
- LinePatternPos getDashPosition(const std::vector<float>&, bool);
- LinePatternPos addDash(const std::vector<float> &dasharray, bool round);
+ LinePatternPos getDashPosition(const std::vector<float>&, bool, gl::GLObjectStore&);
+ LinePatternPos addDash(const std::vector<float> &dasharray, bool round, gl::GLObjectStore&);
const GLsizei width;
const GLsizei height;
@@ -36,7 +36,7 @@ public:
private:
const std::unique_ptr<GLbyte[]> data;
bool dirty;
- GLuint texture = 0;
+ gl::TextureHolder texture;
int nextRow = 0;
std::map<size_t, LinePatternPos> positions;
};
diff --git a/src/mbgl/geometry/line_buffer.cpp b/src/mbgl/geometry/line_buffer.cpp
index f775a4589f..b35d3e8f47 100644
--- a/src/mbgl/geometry/line_buffer.cpp
+++ b/src/mbgl/geometry/line_buffer.cpp
@@ -1,5 +1,5 @@
#include <mbgl/geometry/line_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cmath>
diff --git a/src/mbgl/geometry/static_vertex_buffer.cpp b/src/mbgl/geometry/static_vertex_buffer.cpp
index e8dad0ba9b..254b01b6b6 100644
--- a/src/mbgl/geometry/static_vertex_buffer.cpp
+++ b/src/mbgl/geometry/static_vertex_buffer.cpp
@@ -1,5 +1,5 @@
#include <mbgl/geometry/static_vertex_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
namespace mbgl {
diff --git a/src/mbgl/geometry/text_buffer.cpp b/src/mbgl/geometry/text_buffer.cpp
index 530048a6dd..1aa65146a4 100644
--- a/src/mbgl/geometry/text_buffer.cpp
+++ b/src/mbgl/geometry/text_buffer.cpp
@@ -1,5 +1,5 @@
#include <mbgl/geometry/text_buffer.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/math.hpp>
#include <cmath>
diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/geometry/vao.cpp
index d3ad16e64f..8239604264 100644
--- a/src/mbgl/geometry/vao.cpp
+++ b/src/mbgl/geometry/vao.cpp
@@ -1,59 +1,23 @@
#include <mbgl/geometry/vao.hpp>
#include <mbgl/platform/log.hpp>
-#include <mbgl/util/gl_object_store.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/string.hpp>
-#include <mbgl/util/thread_context.hpp>
namespace mbgl {
-static gl::ExtensionFunction<
- void (GLuint array)>
- BindVertexArray({
- {"GL_ARB_vertex_array_object", "glBindVertexArray"},
- {"GL_OES_vertex_array_object", "glBindVertexArrayOES"},
- {"GL_APPLE_vertex_array_object", "glBindVertexArrayAPPLE"}
- });
-
-static gl::ExtensionFunction<
- void (GLsizei n,
- const GLuint* arrays)>
- DeleteVertexArrays({
- {"GL_ARB_vertex_array_object", "glDeleteVertexArrays"},
- {"GL_OES_vertex_array_object", "glDeleteVertexArraysOES"},
- {"GL_APPLE_vertex_array_object", "glDeleteVertexArraysAPPLE"}
- });
-
-static gl::ExtensionFunction<
- void (GLsizei n,
- GLuint* arrays)>
- GenVertexArrays({
- {"GL_ARB_vertex_array_object", "glGenVertexArrays"},
- {"GL_OES_vertex_array_object", "glGenVertexArraysOES"},
- {"GL_APPLE_vertex_array_object", "glGenVertexArraysAPPLE"}
- });
-
void VertexArrayObject::Unbind() {
- if (!BindVertexArray) return;
- MBGL_CHECK_ERROR(BindVertexArray(0));
-}
-
-void VertexArrayObject::Delete(GLsizei n, const GLuint* arrays) {
- MBGL_CHECK_ERROR(DeleteVertexArrays(n, arrays));
+ if (!gl::BindVertexArray) return;
+ MBGL_CHECK_ERROR(gl::BindVertexArray(0));
}
VertexArrayObject::VertexArrayObject() {
}
VertexArrayObject::~VertexArrayObject() {
- if (!DeleteVertexArrays) return;
-
- if (vao) {
- util::ThreadContext::getGLObjectStore()->abandonVAO(vao);
- }
}
-void VertexArrayObject::bindVertexArrayObject() {
- if (!GenVertexArrays || !BindVertexArray) {
+void VertexArrayObject::bindVertexArrayObject(gl::GLObjectStore& glObjectStore) {
+ if (!gl::GenVertexArrays || !gl::BindVertexArray) {
static bool reported = false;
if (!reported) {
Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
@@ -62,10 +26,8 @@ void VertexArrayObject::bindVertexArrayObject() {
return;
}
- if (!vao) {
- MBGL_CHECK_ERROR(GenVertexArrays(1, &vao));
- }
- MBGL_CHECK_ERROR(BindVertexArray(vao));
+ if (!vao) vao.create(glObjectStore);
+ MBGL_CHECK_ERROR(gl::BindVertexArray(vao.getID()));
}
void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer,
diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp
index 2dcc02c76b..dcb66dd41d 100644
--- a/src/mbgl/geometry/vao.hpp
+++ b/src/mbgl/geometry/vao.hpp
@@ -2,26 +2,28 @@
#define MBGL_GEOMETRY_VAO
#include <mbgl/shader/shader.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <stdexcept>
namespace mbgl {
+class Shader;
+
class VertexArrayObject : public util::noncopyable {
public:
static void Unbind();
- static void Delete(GLsizei n, const GLuint* arrays);
VertexArrayObject();
~VertexArrayObject();
template <typename Shader, typename VertexBuffer>
- inline void bind(Shader& shader, VertexBuffer &vertexBuffer, GLbyte *offset) {
- bindVertexArrayObject();
+ inline void bind(Shader& shader, VertexBuffer &vertexBuffer, GLbyte *offset, gl::GLObjectStore& glObjectStore) {
+ bindVertexArrayObject(glObjectStore);
if (bound_shader == 0) {
- vertexBuffer.bind();
+ vertexBuffer.bind(glObjectStore);
shader.bind(offset);
if (vao) {
storeBinding(shader, vertexBuffer.getID(), 0, offset);
@@ -32,11 +34,11 @@ public:
}
template <typename Shader, typename VertexBuffer, typename ElementsBuffer>
- inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, GLbyte *offset) {
- bindVertexArrayObject();
+ inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, GLbyte *offset, gl::GLObjectStore& glObjectStore) {
+ bindVertexArrayObject(glObjectStore);
if (bound_shader == 0) {
- vertexBuffer.bind();
- elementsBuffer.bind();
+ vertexBuffer.bind(glObjectStore);
+ elementsBuffer.bind(glObjectStore);
shader.bind(offset);
if (vao) {
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
@@ -46,16 +48,16 @@ public:
}
}
- inline GLuint getID() const {
- return vao;
+ GLuint getID() const {
+ return vao.getID();
}
private:
- void bindVertexArrayObject();
+ void bindVertexArrayObject(gl::GLObjectStore&);
void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
- GLuint vao = 0;
+ gl::VAOHolder vao;
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
diff --git a/src/mbgl/gl/debugging.cpp b/src/mbgl/gl/debugging.cpp
index fb9e037714..e61de42bc3 100644
--- a/src/mbgl/gl/debugging.cpp
+++ b/src/mbgl/gl/debugging.cpp
@@ -1,5 +1,5 @@
#include <mbgl/gl/debugging.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/event.hpp>
#include <mbgl/platform/log.hpp>
diff --git a/src/mbgl/platform/gl.cpp b/src/mbgl/gl/gl.cpp
index e5495c80dc..c57717aa87 100644
--- a/src/mbgl/platform/gl.cpp
+++ b/src/mbgl/gl/gl.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/platform/log.hpp>
diff --git a/src/mbgl/renderer/gl_config.cpp b/src/mbgl/gl/gl_config.cpp
index 4160ae100e..4160ae100e 100644
--- a/src/mbgl/renderer/gl_config.cpp
+++ b/src/mbgl/gl/gl_config.cpp
diff --git a/src/mbgl/gl/gl_config.hpp b/src/mbgl/gl/gl_config.hpp
new file mode 100644
index 0000000000..af373fc3f8
--- /dev/null
+++ b/src/mbgl/gl/gl_config.hpp
@@ -0,0 +1,100 @@
+#ifndef MBGL_GL_GL_CONFIG
+#define MBGL_GL_GL_CONFIG
+
+#include <cstdint>
+#include <tuple>
+#include <array>
+
+#include <mbgl/gl/gl_values.hpp>
+
+namespace mbgl {
+namespace gl {
+
+template <typename T>
+class Value {
+public:
+ inline void operator=(const typename T::Type& value) {
+ if (dirty || current != value) {
+ dirty = false;
+ current = value;
+ T::Set(current);
+ }
+ }
+
+ inline void reset() {
+ dirty = true;
+ current = T::Default;
+ T::Set(current);
+ }
+
+ inline void setDirty() {
+ dirty = true;
+ }
+
+private:
+ typename T::Type current = T::Default;
+ bool dirty = false;
+};
+
+class Config {
+public:
+ void reset() {
+ stencilFunc.reset();
+ stencilMask.reset();
+ stencilTest.reset();
+ stencilOp.reset();
+ depthRange.reset();
+ depthMask.reset();
+ depthTest.reset();
+ depthFunc.reset();
+ blend.reset();
+ blendFunc.reset();
+ colorMask.reset();
+ clearDepth.reset();
+ clearColor.reset();
+ clearStencil.reset();
+ program.reset();
+ lineWidth.reset();
+ }
+
+ void setDirty() {
+ stencilFunc.setDirty();
+ stencilMask.setDirty();
+ stencilTest.setDirty();
+ stencilOp.setDirty();
+ depthRange.setDirty();
+ depthMask.setDirty();
+ depthTest.setDirty();
+ depthFunc.setDirty();
+ blend.setDirty();
+ blendFunc.setDirty();
+ colorMask.setDirty();
+ clearDepth.setDirty();
+ clearColor.setDirty();
+ clearStencil.setDirty();
+ program.setDirty();
+ lineWidth.setDirty();
+ }
+
+ Value<StencilFunc> stencilFunc;
+ Value<StencilMask> stencilMask;
+ Value<StencilTest> stencilTest;
+ Value<StencilOp> stencilOp;
+ Value<DepthRange> depthRange;
+ Value<DepthMask> depthMask;
+ Value<DepthTest> depthTest;
+ Value<DepthFunc> depthFunc;
+ Value<Blend> blend;
+ Value<BlendFunc> blendFunc;
+ Value<ColorMask> colorMask;
+ Value<ClearDepth> clearDepth;
+ Value<ClearColor> clearColor;
+ Value<ClearStencil> clearStencil;
+ Value<Program> program;
+ Value<LineWidth> lineWidth;
+};
+
+} // namespace gl
+} // namespace mbgl
+
+#endif // MBGL_RENDERER_GL_CONFIG
diff --git a/src/mbgl/gl/gl_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp
new file mode 100644
index 0000000000..4948e20694
--- /dev/null
+++ b/src/mbgl/gl/gl_object_store.cpp
@@ -0,0 +1,120 @@
+#include <mbgl/gl/gl_object_store.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+namespace gl {
+
+void ProgramHolder::create(GLObjectStore& objectStore_) {
+ if (id) return;
+ objectStore = &objectStore_;
+ id = MBGL_CHECK_ERROR(glCreateProgram());
+}
+
+void ProgramHolder::reset() {
+ if (!id) return;
+ objectStore->abandonedPrograms.push_back(id);
+ id = 0;
+}
+
+void ShaderHolder::create(GLObjectStore& objectStore_) {
+ if (id) return;
+ objectStore = &objectStore_;
+ id = MBGL_CHECK_ERROR(glCreateShader(type));
+}
+
+void ShaderHolder::reset() {
+ if (!id) return;
+ objectStore->abandonedShaders.push_back(id);
+ id = 0;
+}
+
+void BufferHolder::create(GLObjectStore& objectStore_) {
+ if (id) return;
+ objectStore = &objectStore_;
+ MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+}
+
+void BufferHolder::reset() {
+ if (!id) return;
+ objectStore->abandonedBuffers.push_back(id);
+ id = 0;
+}
+
+void TextureHolder::create(GLObjectStore& objectStore_) {
+ if (id) return;
+ objectStore = &objectStore_;
+ MBGL_CHECK_ERROR(glGenTextures(1, &id));
+}
+
+void TextureHolder::reset() {
+ if (!id) return;
+ objectStore->abandonedTextures.push_back(id);
+ id = 0;
+}
+
+void TexturePoolHolder::create(GLObjectStore& objectStore_) {
+ if (bool()) return;
+ objectStore = &objectStore_;
+ MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
+}
+
+void TexturePoolHolder::reset() {
+ if (!bool()) return;
+ for (GLuint id : ids) {
+ if (id) {
+ objectStore->abandonedTextures.push_back(id);
+ }
+ }
+ ids.fill(0);
+}
+
+void VAOHolder::create(GLObjectStore& objectStore_) {
+ if (id) return;
+ objectStore = &objectStore_;
+ MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
+}
+
+void VAOHolder::reset() {
+ if (!id) return;
+ objectStore->abandonedVAOs.push_back(id);
+ id = 0;
+}
+
+GLObjectStore::~GLObjectStore() {
+ assert(abandonedPrograms.empty());
+ assert(abandonedShaders.empty());
+ assert(abandonedBuffers.empty());
+ assert(abandonedTextures.empty());
+ assert(abandonedVAOs.empty());
+}
+
+void GLObjectStore::performCleanup() {
+ for (GLuint id : abandonedPrograms) {
+ MBGL_CHECK_ERROR(glDeleteProgram(id));
+ }
+ abandonedPrograms.clear();
+
+ for (GLuint id : abandonedShaders) {
+ MBGL_CHECK_ERROR(glDeleteShader(id));
+ }
+ abandonedShaders.clear();
+
+ if (!abandonedBuffers.empty()) {
+ MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data()));
+ abandonedBuffers.clear();
+ }
+
+ if (!abandonedTextures.empty()) {
+ MBGL_CHECK_ERROR(glDeleteTextures(int(abandonedTextures.size()), abandonedTextures.data()));
+ abandonedTextures.clear();
+ }
+
+ if (!abandonedVAOs.empty()) {
+ MBGL_CHECK_ERROR(gl::DeleteVertexArrays(int(abandonedVAOs.size()), abandonedVAOs.data()));
+ abandonedVAOs.clear();
+ }
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp
new file mode 100644
index 0000000000..832f1d09b3
--- /dev/null
+++ b/src/mbgl/gl/gl_object_store.hpp
@@ -0,0 +1,141 @@
+#ifndef MBGL_MAP_UTIL_GL_OBJECT_STORE
+#define MBGL_MAP_UTIL_GL_OBJECT_STORE
+
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <array>
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+namespace mbgl {
+namespace gl {
+
+class GLObjectStore : private util::noncopyable {
+public:
+ ~GLObjectStore();
+
+ // Actually remove the objects we marked as abandoned with the above methods.
+ // Only call this while the OpenGL context is exclusive to this thread.
+ void performCleanup();
+
+private:
+ friend class ProgramHolder;
+ friend class ShaderHolder;
+ friend class BufferHolder;
+ friend class TextureHolder;
+ friend class TexturePoolHolder;
+ friend class VAOHolder;
+
+ std::vector<GLuint> abandonedPrograms;
+ std::vector<GLuint> abandonedShaders;
+ std::vector<GLuint> abandonedBuffers;
+ std::vector<GLuint> abandonedTextures;
+ std::vector<GLuint> abandonedVAOs;
+};
+
+class GLHolder : private util::noncopyable {
+public:
+ GLHolder() {}
+
+ GLHolder(GLHolder&& o) noexcept : id(o.id) { o.id = 0; }
+ GLHolder& operator=(GLHolder&& o) noexcept { id = o.id; o.id = 0; return *this; }
+
+ explicit operator bool() const { return id; }
+ GLuint getID() const { return id; }
+
+protected:
+ GLuint id = 0;
+ GLObjectStore* objectStore = nullptr;
+};
+
+class ProgramHolder : public GLHolder {
+public:
+ ProgramHolder() = default;
+ ~ProgramHolder() { reset(); }
+
+ ProgramHolder(ProgramHolder&& o) noexcept : GLHolder(std::move(o)) {}
+ ProgramHolder& operator=(ProgramHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+
+ void create(GLObjectStore&);
+ void reset();
+};
+
+class ShaderHolder : public GLHolder {
+public:
+ ShaderHolder(GLenum type_) : type(type_) {}
+ ~ShaderHolder() { reset(); }
+
+ ShaderHolder(ShaderHolder&& o) noexcept : GLHolder(std::move(o)), type(o.type) {}
+ ShaderHolder& operator=(ShaderHolder&& o) noexcept { GLHolder::operator=(std::move(o)); type = o.type; return *this; }
+
+ void create(GLObjectStore&);
+ void reset();
+
+private:
+ GLenum type = 0;
+};
+
+class BufferHolder : public GLHolder {
+public:
+ BufferHolder() = default;
+ ~BufferHolder() { reset(); }
+
+ BufferHolder(BufferHolder&& o) noexcept : GLHolder(std::move(o)) {}
+ BufferHolder& operator=(BufferHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+
+ void create(GLObjectStore&);
+ void reset();
+};
+
+class TextureHolder : public GLHolder {
+public:
+ TextureHolder() = default;
+ ~TextureHolder() { reset(); }
+
+ TextureHolder(TextureHolder&& o) noexcept : GLHolder(std::move(o)) {}
+ TextureHolder& operator=(TextureHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+
+ void create(GLObjectStore&);
+ void reset();
+};
+
+class TexturePoolHolder : private util::noncopyable {
+public:
+ static const GLsizei TextureMax = 64;
+
+ TexturePoolHolder() { ids.fill(0); }
+ ~TexturePoolHolder() { reset(); }
+
+ TexturePoolHolder(TexturePoolHolder&& o) noexcept : ids(std::move(o.ids)) {}
+ TexturePoolHolder& operator=(TexturePoolHolder&& o) noexcept { ids = std::move(o.ids); return *this; }
+
+ explicit operator bool() { return std::none_of(ids.begin(), ids.end(), [](int id) { return id == 0; }); }
+ const std::array<GLuint, TextureMax>& getIDs() const { return ids; }
+ const GLuint& operator[](size_t pos) { return ids[pos]; }
+
+ void create(GLObjectStore&);
+ void reset();
+
+private:
+ std::array<GLuint, TextureMax> ids;
+ GLObjectStore* objectStore = nullptr;
+};
+
+class VAOHolder : public GLHolder {
+public:
+ VAOHolder() = default;
+ ~VAOHolder() { reset(); }
+
+ VAOHolder(VAOHolder&& o) noexcept : GLHolder(std::move(o)) {}
+ VAOHolder& operator=(VAOHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+
+ void create(GLObjectStore&);
+ void reset();
+};
+
+} // namespace gl
+} // namespace mbgl
+
+#endif
diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp
new file mode 100644
index 0000000000..a875f4d579
--- /dev/null
+++ b/src/mbgl/gl/texture_pool.cpp
@@ -0,0 +1,41 @@
+#include <mbgl/gl/texture_pool.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
+
+#include <vector>
+
+namespace mbgl {
+namespace gl {
+
+GLuint TexturePool::getTextureID(gl::GLObjectStore& glObjectStore) {
+ for (auto& impl : pools) {
+ if (impl.ids.empty()) continue;
+ auto it = impl.ids.begin();
+ GLuint id = *it;
+ impl.ids.erase(it);
+ return id;
+ }
+
+ // All texture IDs are in use.
+ pools.emplace_back(Impl(glObjectStore));
+ auto it = pools.back().ids.begin();
+ GLuint id = *it;
+ pools.back().ids.erase(it);
+ return id;
+}
+
+void TexturePool::releaseTextureID(GLuint id) {
+ for (auto it = pools.begin(); it != pools.end(); ++it) {
+ for (GLsizei i = 0; i < gl::TexturePoolHolder::TextureMax; ++i) {
+ if (it->pool[i] == id) {
+ it->ids.push_back(id);
+ if (GLsizei(it->ids.size()) == gl::TexturePoolHolder::TextureMax) {
+ pools.erase(it);
+ }
+ return;
+ }
+ }
+ }
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp
new file mode 100644
index 0000000000..10f63bfac9
--- /dev/null
+++ b/src/mbgl/gl/texture_pool.hpp
@@ -0,0 +1,41 @@
+#ifndef MBGL_UTIL_TEXTUREPOOL
+#define MBGL_UTIL_TEXTUREPOOL
+
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+namespace mbgl {
+namespace gl {
+
+class TexturePool : private util::noncopyable {
+public:
+ GLuint getTextureID(gl::GLObjectStore&);
+ void releaseTextureID(GLuint);
+
+private:
+ class Impl : private util::noncopyable {
+ public:
+ Impl(gl::GLObjectStore& glObjectStore) : ids(gl::TexturePoolHolder::TextureMax) {
+ pool.create(glObjectStore);
+ std::copy(pool.getIDs().begin(), pool.getIDs().end(), ids.begin());
+ }
+
+ Impl(Impl&& o) : pool(std::move(o.pool)), ids(std::move(o.ids)) {}
+ Impl& operator=(Impl&& o) { pool = std::move(o.pool); ids = std::move(o.ids); return *this; }
+
+ gl::TexturePoolHolder pool;
+ std::vector<GLuint> ids;
+ };
+
+ std::vector<Impl> pools;
+};
+
+} // namespace gl
+} // namespace mbgl
+
+#endif
diff --git a/src/mbgl/layer/background_layer.hpp b/src/mbgl/layer/background_layer.hpp
index 063331fade..118bb19053 100644
--- a/src/mbgl/layer/background_layer.hpp
+++ b/src/mbgl/layer/background_layer.hpp
@@ -15,6 +15,7 @@ public:
class BackgroundLayer : public StyleLayer {
public:
+ BackgroundLayer() : StyleLayer(Type::Background) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override {};
@@ -28,6 +29,11 @@ public:
BackgroundPaintProperties paint;
};
+template <>
+inline bool StyleLayer::is<BackgroundLayer>() const {
+ return type == Type::Background;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/circle_layer.hpp b/src/mbgl/layer/circle_layer.hpp
index 03169ca065..036bf79991 100644
--- a/src/mbgl/layer/circle_layer.hpp
+++ b/src/mbgl/layer/circle_layer.hpp
@@ -22,6 +22,7 @@ public:
class CircleLayer : public StyleLayer {
public:
+ CircleLayer() : StyleLayer(Type::Circle) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override {};
@@ -35,6 +36,11 @@ public:
CirclePaintProperties paint;
};
+template <>
+inline bool StyleLayer::is<CircleLayer>() const {
+ return type == Type::Circle;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/custom_layer.cpp b/src/mbgl/layer/custom_layer.cpp
index 39742ecad8..0b6de51e67 100644
--- a/src/mbgl/layer/custom_layer.cpp
+++ b/src/mbgl/layer/custom_layer.cpp
@@ -8,7 +8,8 @@ CustomLayer::CustomLayer(const std::string& id_,
CustomLayerInitializeFunction initializeFn_,
CustomLayerRenderFunction renderFn_,
CustomLayerDeinitializeFunction deinitializeFn_,
- void * context_) {
+ void* context_)
+ : StyleLayer(Type::Custom) {
id = id_;
initializeFn = initializeFn_;
renderFn = renderFn_;
diff --git a/src/mbgl/layer/custom_layer.hpp b/src/mbgl/layer/custom_layer.hpp
index 315d158802..b54ac7481e 100644
--- a/src/mbgl/layer/custom_layer.hpp
+++ b/src/mbgl/layer/custom_layer.hpp
@@ -38,6 +38,11 @@ private:
void* context = nullptr;
};
+template <>
+inline bool StyleLayer::is<CustomLayer>() const {
+ return type == Type::Custom;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/fill_layer.hpp b/src/mbgl/layer/fill_layer.hpp
index ee079a5c8a..3b1c5a84fe 100644
--- a/src/mbgl/layer/fill_layer.hpp
+++ b/src/mbgl/layer/fill_layer.hpp
@@ -19,6 +19,7 @@ public:
class FillLayer : public StyleLayer {
public:
+ FillLayer() : StyleLayer(Type::Fill) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override {};
@@ -32,6 +33,11 @@ public:
FillPaintProperties paint;
};
+template <>
+inline bool StyleLayer::is<FillLayer>() const {
+ return type == Type::Fill;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/line_layer.cpp b/src/mbgl/layer/line_layer.cpp
index 8454eb2664..edf128fd35 100644
--- a/src/mbgl/layer/line_layer.cpp
+++ b/src/mbgl/layer/line_layer.cpp
@@ -69,7 +69,7 @@ bool LineLayer::recalculate(const StyleCalculationParameters& parameters) {
}
std::unique_ptr<Bucket> LineLayer::createBucket(StyleBucketParameters& parameters) const {
- auto bucket = std::make_unique<LineBucket>();
+ auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaling);
bucket->layout = layout;
diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp
index 027f7a9c06..200541c620 100644
--- a/src/mbgl/layer/line_layer.hpp
+++ b/src/mbgl/layer/line_layer.hpp
@@ -38,6 +38,7 @@ public:
class LineLayer : public StyleLayer {
public:
+ LineLayer() : StyleLayer(Type::Line) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override;
@@ -52,6 +53,11 @@ public:
LinePaintProperties paint;
};
+template <>
+inline bool StyleLayer::is<LineLayer>() const {
+ return type == Type::Line;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/raster_layer.hpp b/src/mbgl/layer/raster_layer.hpp
index bf912bad4a..52c0f0a7ae 100644
--- a/src/mbgl/layer/raster_layer.hpp
+++ b/src/mbgl/layer/raster_layer.hpp
@@ -19,6 +19,7 @@ public:
class RasterLayer : public StyleLayer {
public:
+ RasterLayer() : StyleLayer(Type::Raster) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override {};
@@ -32,6 +33,11 @@ public:
RasterPaintProperties paint;
};
+template <>
+inline bool StyleLayer::is<RasterLayer>() const {
+ return type == Type::Raster;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/symbol_layer.hpp b/src/mbgl/layer/symbol_layer.hpp
index 730bd2ad4a..a2b3b0acf9 100644
--- a/src/mbgl/layer/symbol_layer.hpp
+++ b/src/mbgl/layer/symbol_layer.hpp
@@ -84,6 +84,7 @@ public:
class SymbolLayer : public StyleLayer {
public:
+ SymbolLayer() : StyleLayer(Type::Symbol) {}
std::unique_ptr<StyleLayer> clone() const override;
void parseLayout(const JSValue&) override;
@@ -97,9 +98,14 @@ public:
SymbolLayoutProperties layout;
SymbolPaintProperties paint;
- SpriteAtlas* spriteAtlas;
+ SpriteAtlas* spriteAtlas = nullptr;
};
+template <>
+inline bool StyleLayer::is<SymbolLayer>() const {
+ return type == Type::Symbol;
+}
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 7e0fdd29fe..c3123fb3be 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -462,6 +462,11 @@ AnnotationIDs Map::addShapeAnnotations(const std::vector<ShapeAnnotation>& annot
return result;
}
+void Map::updatePointAnnotation(AnnotationID annotationId, const PointAnnotation& annotation) {
+ data->getAnnotationManager()->updatePointAnnotation(annotationId, annotation, getMaxZoom());
+ update(Update::Annotations);
+}
+
void Map::removeAnnotation(AnnotationID annotation) {
removeAnnotations({ annotation });
}
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index 03da5ee321..f9397d4f78 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -16,9 +16,10 @@
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_store.hpp>
-#include <mbgl/util/gl_object_store.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
+#include <mbgl/gl/texture_pool.hpp>
+
#include <mbgl/util/worker.hpp>
-#include <mbgl/util/texture_pool.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/mapbox.hpp>
@@ -27,18 +28,16 @@
namespace mbgl {
-MapContext::MapContext(View& view_, FileSource& fileSource, MapMode mode_, GLContextMode contextMode_, const float pixelRatio_)
+MapContext::MapContext(View& view_, FileSource& fileSource_, MapMode mode_, GLContextMode contextMode_, const float pixelRatio_)
: view(view_),
+ fileSource(fileSource_),
dataPtr(std::make_unique<MapData>(mode_, contextMode_, pixelRatio_)),
data(*dataPtr),
asyncUpdate([this] { update(); }),
asyncInvalidate([&view_] { view_.invalidate(); }),
- texturePool(std::make_unique<TexturePool>()) {
+ texturePool(std::make_unique<gl::TexturePool>()) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
- util::ThreadContext::setFileSource(&fileSource);
- util::ThreadContext::setGLObjectStore(&glObjectStore);
-
view.activate();
}
@@ -95,7 +94,7 @@ void MapContext::setStyleURL(const std::string& url) {
styleURL = url;
styleJSON.clear();
- style = std::make_unique<Style>(data);
+ style = std::make_unique<Style>(data, fileSource);
const size_t pos = styleURL.rfind('/');
std::string base = "";
@@ -103,8 +102,7 @@ void MapContext::setStyleURL(const std::string& url) {
base = styleURL.substr(0, pos + 1);
}
- FileSource* fs = util::ThreadContext::getFileSource();
- styleRequest = fs->request(Resource::style(styleURL), [this, base](Response res) {
+ styleRequest = fileSource.request(Resource::style(styleURL), [this, base](Response res) {
if (res.error) {
if (res.error->reason == Response::Error::Reason::NotFound &&
util::mapbox::isMapboxURL(styleURL)) {
@@ -113,14 +111,11 @@ void MapContext::setStyleURL(const std::string& url) {
Log::Error(Event::Setup, "loading style failed: %s", res.error->message.c_str());
data.loading = false;
}
+ } else if (res.notModified || res.noContent) {
return;
+ } else {
+ loadStyleJSON(*res.data, base);
}
-
- if (res.notModified) {
- return;
- }
-
- loadStyleJSON(*res.data, base);
});
}
@@ -132,7 +127,7 @@ void MapContext::setStyleJSON(const std::string& json, const std::string& base)
styleURL.clear();
styleJSON.clear();
- style = std::make_unique<Style>(data);
+ style = std::make_unique<Style>(data, fileSource);
loadStyleJSON(json, base);
}
@@ -241,7 +236,7 @@ bool MapContext::renderSync(const TransformState& state, const FrameData& frame)
// Cleanup OpenGL objects that we abandoned since the last render call.
glObjectStore.performCleanup();
- if (!painter) painter = std::make_unique<Painter>(data, transformState);
+ if (!painter) painter = std::make_unique<Painter>(data, transformState, glObjectStore);
painter->render(*style, frame, data.getAnnotationManager()->getSpriteAtlas());
if (data.mode == MapMode::Still) {
diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp
index dd0c2de465..83ab71c86e 100644
--- a/src/mbgl/map/map_context.hpp
+++ b/src/mbgl/map/map_context.hpp
@@ -8,9 +8,9 @@
#include <mbgl/map/map_data.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/util/async_task.hpp>
-#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/optional.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <vector>
@@ -18,11 +18,12 @@ namespace mbgl {
class View;
class MapData;
-class TexturePool;
class Painter;
class SpriteImage;
class FileRequest;
+namespace gl { class TexturePool; }
+
struct FrameData {
std::array<uint16_t, 2> framebufferSize;
};
@@ -77,16 +78,17 @@ private:
void loadStyleJSON(const std::string& json, const std::string& base);
View& view;
+ FileSource& fileSource;
std::unique_ptr<MapData> dataPtr;
MapData& data;
- util::GLObjectStore glObjectStore;
+ gl::GLObjectStore glObjectStore;
Update updateFlags = Update::Nothing;
util::AsyncTask asyncUpdate;
util::AsyncTask asyncInvalidate;
- std::unique_ptr<TexturePool> texturePool;
+ std::unique_ptr<gl::TexturePool> texturePool;
std::unique_ptr<Painter> painter;
std::unique_ptr<Style> style;
diff --git a/src/mbgl/map/raster_tile_data.cpp b/src/mbgl/map/raster_tile_data.cpp
deleted file mode 100644
index f9f5480197..0000000000
--- a/src/mbgl/map/raster_tile_data.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include <mbgl/map/raster_tile_data.hpp>
-#include <mbgl/map/source.hpp>
-#include <mbgl/storage/resource.hpp>
-#include <mbgl/storage/response.hpp>
-#include <mbgl/storage/file_source.hpp>
-#include <mbgl/util/worker.hpp>
-#include <mbgl/util/work_request.hpp>
-
-using namespace mbgl;
-
-RasterTileData::RasterTileData(const TileID& id_,
- float pixelRatio,
- const std::string& urlTemplate,
- TexturePool &texturePool_,
- Worker& worker_,
- const std::function<void(std::exception_ptr)>& callback)
- : TileData(id_),
- texturePool(texturePool_),
- worker(worker_) {
- state = State::loading;
-
- const Resource resource = Resource::tile(urlTemplate, pixelRatio, id.x, id.y, id.sourceZ);
- req = util::ThreadContext::getFileSource()->request(resource, [callback, this](Response res) {
- if (res.error) {
- std::exception_ptr error;
- if (res.error->reason == Response::Error::Reason::NotFound) {
- // This is a 404 response. We're treating these as empty tiles.
- workRequest.reset();
- state = State::parsed;
- bucket.reset();
- } else {
- // This is a different error, e.g. a connection or server error.
- error = std::make_exception_ptr(std::runtime_error(res.error->message));
- }
- callback(error);
- return;
- }
-
- modified = res.modified;
- expires = res.expires;
-
- if (res.notModified) {
- // We got the same data again. Abort early.
- return;
- }
-
- if (state == State::loading) {
- // Only overwrite the state when we didn't have a previous tile.
- state = State::loaded;
- }
-
- workRequest.reset();
- workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), res.data, [this, callback] (RasterTileParseResult result) {
- workRequest.reset();
- if (state != State::loaded) {
- return;
- }
-
- std::exception_ptr error;
- if (result.is<std::unique_ptr<Bucket>>()) {
- state = State::parsed;
- bucket = std::move(result.get<std::unique_ptr<Bucket>>());
- } else {
- error = result.get<std::exception_ptr>();
- state = State::obsolete;
- bucket.reset();
- }
-
- callback(error);
- });
- });
-}
-
-RasterTileData::~RasterTileData() {
- cancel();
-}
-
-Bucket* RasterTileData::getBucket(StyleLayer const&) {
- return bucket.get();
-}
-
-void RasterTileData::cancel() {
- if (state != State::obsolete) {
- state = State::obsolete;
- }
- req = nullptr;
- workRequest.reset();
-}
diff --git a/src/mbgl/map/tile.cpp b/src/mbgl/map/tile.cpp
deleted file mode 100644
index 408cdfaec5..0000000000
--- a/src/mbgl/map/tile.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <mbgl/map/tile.hpp>
-
-using namespace mbgl;
diff --git a/src/mbgl/map/tile_id.hpp b/src/mbgl/map/tile_id.hpp
index dddbce3bb7..a193b63392 100644
--- a/src/mbgl/map/tile_id.hpp
+++ b/src/mbgl/map/tile_id.hpp
@@ -6,6 +6,7 @@
#include <string>
#include <functional>
#include <forward_list>
+#include <limits>
namespace mbgl {
@@ -25,12 +26,6 @@ public:
return ((std::pow(2, z) * y + x) * 32) + z;
}
- struct Hash {
- std::size_t operator()(const TileID& id) const {
- return std::hash<uint64_t>()(id.to_uint64());
- }
- };
-
inline bool operator==(const TileID& rhs) const {
return w == rhs.w && z == rhs.z && x == rhs.x && y == rhs.y;
}
@@ -48,12 +43,24 @@ public:
TileID parent(int8_t z, int8_t sourceMaxZoom) const;
TileID normalized() const;
- std::forward_list<TileID> children(int8_t sourceMaxZoom) const;
+ std::forward_list<TileID>
+ children(int8_t sourceMaxZoom = std::numeric_limits<int8_t>::max()) const;
bool isChildOf(const TileID&) const;
operator std::string() const;
-
};
} // namespace mbgl
+namespace std {
+template <>
+struct hash<mbgl::TileID> {
+ typedef mbgl::TileID argument_type;
+ typedef std::size_t result_type;
+
+ result_type operator()(const mbgl::TileID& id) const {
+ return std::hash<uint64_t>()(id.to_uint64());
+ }
+};
+} // namespace std
+
#endif
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 009534fc8b..087defabda 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -1,7 +1,6 @@
#include <mbgl/map/transform_state.hpp>
#include <mbgl/map/tile_id.hpp>
#include <mbgl/util/constants.hpp>
-#include <mbgl/util/box.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/util/math.hpp>
@@ -54,18 +53,6 @@ void TransformState::getProjMatrix(mat4& projMatrix) const {
pixel_y() - getHeight() / 2.0f, 0);
}
-box TransformState::cornersToBox(uint32_t z) const {
- double w = width;
- double h = height;
- box b(
- pointToCoordinate({ 0, 0 }).zoomTo(z),
- pointToCoordinate({ w, 0 }).zoomTo(z),
- pointToCoordinate({ w, h }).zoomTo(z),
- pointToCoordinate({ 0, h }).zoomTo(z));
- return b;
-}
-
-
#pragma mark - Dimensions
uint16_t TransformState::getWidth() const {
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index dfcc1ed1a0..0fb1f2304b 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -15,8 +15,7 @@
namespace mbgl {
class TileID;
-struct box;
-struct TileCoordinate;
+class TileCoordinate;
class TransformState {
friend class Transform;
@@ -27,7 +26,6 @@ public:
// Matrix
void matrixFor(mat4& matrix, const TileID& id, const int8_t z) const;
void getProjMatrix(mat4& matrix) const;
- box cornersToBox(uint32_t z) const;
// Dimensions
uint16_t getWidth() const;
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index b7cbfdf0fe..85f97688dd 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_RENDERER_BUCKET
#define MBGL_RENDERER_BUCKET
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/mat4.hpp>
@@ -18,13 +18,17 @@ class StyleLayer;
class TileID;
class CollisionTile;
+namespace gl {
+class GLObjectStore;
+}
+
class Bucket : private util::noncopyable {
public:
Bucket() : uploaded(false) {}
// As long as this bucket has a Prepare render pass, this function is getting called. Typically,
// this only happens once when the bucket is being rendered for the first time.
- virtual void upload() = 0;
+ virtual void upload(gl::GLObjectStore&) = 0;
// Every time this bucket is getting rendered, this function is called. This happens either
// once or twice (for Opaque and Transparent render passes).
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index 1ebe8ffaf3..fcead38c33 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -14,9 +14,9 @@ CircleBucket::~CircleBucket() {
// Do not remove. header file only contains forward definitions to unique pointers.
}
-void CircleBucket::upload() {
- vertexBuffer_.upload();
- elementsBuffer_.upload();
+void CircleBucket::upload(gl::GLObjectStore& glObjectStore) {
+ vertexBuffer_.upload(glObjectStore);
+ elementsBuffer_.upload(glObjectStore);
uploaded = true;
}
@@ -73,7 +73,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
}
}
-void CircleBucket::drawCircles(CircleShader& shader) {
+void CircleBucket::drawCircles(CircleShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertexIndex = BUFFER_OFFSET(0);
GLbyte* elementsIndex = BUFFER_OFFSET(0);
@@ -82,7 +82,7 @@ void CircleBucket::drawCircles(CircleShader& shader) {
if (!group->elements_length) continue;
- group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex);
+ group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex));
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index f85c9267d3..875e5bb4a9 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -3,7 +3,7 @@
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/circle_buffer.hpp>
@@ -20,13 +20,13 @@ public:
CircleBucket();
~CircleBucket() override;
- void upload() override;
+ void upload(gl::GLObjectStore&) override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
bool hasData() const override;
void addGeometry(const GeometryCollection&);
- void drawCircles(CircleShader& shader);
+ void drawCircles(CircleShader&, gl::GLObjectStore&);
private:
CircleVertexBuffer vertexBuffer_;
diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp
index 2d0590c56b..947783ddb8 100644
--- a/src/mbgl/renderer/debug_bucket.cpp
+++ b/src/mbgl/renderer/debug_bucket.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cassert>
#include <string>
@@ -11,8 +11,8 @@ using namespace mbgl;
DebugBucket::DebugBucket(const TileID id, const TileData::State state_, optional<SystemTimePoint> modified_, optional<SystemTimePoint> expires_, MapDebugOptions debugMode_)
: state(state_),
- modified(modified_),
- expires(expires_),
+ modified(std::move(modified_)),
+ expires(std::move(expires_)),
debugMode(debugMode_) {
double baseline = 200;
if (debugMode & MapDebugOptions::ParseStatus) {
@@ -30,12 +30,12 @@ DebugBucket::DebugBucket(const TileID id, const TileData::State state_, optional
}
}
-void DebugBucket::drawLines(PlainShader& shader) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0);
+void DebugBucket::drawLines(PlainShader& shader, gl::GLObjectStore& glObjectStore) {
+ array.bind(shader, fontBuffer, BUFFER_OFFSET_0, glObjectStore);
MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index())));
}
-void DebugBucket::drawPoints(PlainShader& shader) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0);
+void DebugBucket::drawPoints(PlainShader& shader, gl::GLObjectStore& glObjectStore) {
+ array.bind(shader, fontBuffer, BUFFER_OFFSET_0, glObjectStore);
MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, (GLsizei)(fontBuffer.index())));
}
diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp
index 5c7511ce87..f12452751c 100644
--- a/src/mbgl/renderer/debug_bucket.hpp
+++ b/src/mbgl/renderer/debug_bucket.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_RENDERER_DEBUGBUCKET
#define MBGL_RENDERER_DEBUGBUCKET
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/geometry/debug_font_buffer.hpp>
#include <mbgl/geometry/vao.hpp>
@@ -11,6 +11,10 @@ namespace mbgl {
class PlainShader;
+namespace util {
+class GLObjectStore;
+}
+
class DebugBucket : private util::noncopyable {
public:
DebugBucket(TileID id, TileData::State,
@@ -18,8 +22,8 @@ public:
optional<SystemTimePoint> expires,
MapDebugOptions);
- void drawLines(PlainShader& shader);
- void drawPoints(PlainShader& shader);
+ void drawLines(PlainShader&, gl::GLObjectStore&);
+ void drawPoints(PlainShader&, gl::GLObjectStore&);
const TileData::State state;
const optional<SystemTimePoint> modified;
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index ff976c2450..d3a4bc2b57 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -6,7 +6,7 @@
#include <mbgl/shader/plain_shader.hpp>
#include <mbgl/shader/pattern_shader.hpp>
#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
#include <cassert>
@@ -186,10 +186,10 @@ void FillBucket::tessellate() {
lineGroup.vertex_length += total_vertex_count;
}
-void FillBucket::upload() {
- vertexBuffer.upload();
- triangleElementsBuffer.upload();
- lineElementsBuffer.upload();
+void FillBucket::upload(gl::GLObjectStore& glObjectStore) {
+ vertexBuffer.upload(glObjectStore);
+ triangleElementsBuffer.upload(glObjectStore);
+ lineElementsBuffer.upload(glObjectStore);
// From now on, we're going to render during the opaque and translucent pass.
uploaded = true;
@@ -206,36 +206,36 @@ bool FillBucket::hasData() const {
return !triangleGroups.empty() || !lineGroups.empty();
}
-void FillBucket::drawElements(PlainShader& shader) {
+void FillBucket::drawElements(PlainShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
assert(group);
- group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
+ group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
-void FillBucket::drawElements(PatternShader& shader) {
+void FillBucket::drawElements(PatternShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
assert(group);
- group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
+ group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
-void FillBucket::drawVertices(OutlineShader& shader) {
+void FillBucket::drawVertices(OutlineShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
assert(group);
- group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index);
+ group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * lineElementsBuffer.itemSize;
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index 674c41f7d1..b3b46f030b 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -2,7 +2,7 @@
#define MBGL_RENDERER_FILLBUCKET
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/fill_buffer.hpp>
@@ -32,16 +32,16 @@ public:
FillBucket();
~FillBucket() override;
- void upload() override;
+ void upload(gl::GLObjectStore&) override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
bool hasData() const override;
void addGeometry(const GeometryCollection&);
void tessellate();
- void drawElements(PlainShader& shader);
- void drawElements(PatternShader& shader);
- void drawVertices(OutlineShader& shader);
+ void drawElements(PlainShader&, gl::GLObjectStore&);
+ void drawElements(PatternShader&, gl::GLObjectStore&);
+ void drawVertices(OutlineShader&, gl::GLObjectStore&);
private:
TESSalloc *allocator;
diff --git a/src/mbgl/renderer/gl_config.hpp b/src/mbgl/renderer/gl_config.hpp
deleted file mode 100644
index 2f21b35fe3..0000000000
--- a/src/mbgl/renderer/gl_config.hpp
+++ /dev/null
@@ -1,330 +0,0 @@
-#ifndef MBGL_RENDERER_GL_CONFIG
-#define MBGL_RENDERER_GL_CONFIG
-
-#include <cstdint>
-#include <tuple>
-#include <array>
-
-#include <mbgl/platform/gl.hpp>
-
-namespace mbgl {
-namespace gl {
-
-template <typename T>
-class Value {
-public:
- inline void operator=(const typename T::Type& value) {
- if (dirty || current != value) {
- dirty = false;
- current = value;
- T::Set(current);
- }
- }
-
- inline void reset() {
- dirty = true;
- current = T::Default;
- T::Set(current);
- }
-
- inline void setDirty() {
- dirty = true;
- }
-
-private:
- typename T::Type current = T::Default;
- bool dirty = false;
-};
-
-struct ClearDepth {
- using Type = GLfloat;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glClearDepth(value));
- }
- inline static Type Get() {
- Type clearDepth;
- MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth));
- return clearDepth;
- }
-};
-
-struct ClearColor {
- struct Type { GLfloat r, g, b, a; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glClearColor(value.r, value.g, value.b, value.a));
- }
- inline static Type Get() {
- GLfloat floats[4];
- MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_CLEAR_VALUE, floats));
- return { floats[0], floats[1], floats[2], floats[3] };
- }
-};
-
-inline bool operator!=(const ClearColor::Type& a, const ClearColor::Type& b) {
- return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
-}
-
-struct ClearStencil {
- using Type = GLint;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glClearStencil(value));
- }
- inline static Type Get() {
- Type clearStencil;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil));
- return clearStencil;
- }
-};
-
-struct StencilMask {
- using Type = GLuint;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glStencilMask(value));
- }
- inline static Type Get() {
- GLint stencilMask;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask));
- return stencilMask;
- }
-};
-
-struct DepthMask {
- using Type = GLboolean;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glDepthMask(value));
- }
- inline static Type Get() {
- Type depthMask;
- MBGL_CHECK_ERROR(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask));
- return depthMask;
- }
-};
-
-struct ColorMask {
- struct Type { bool r, g, b, a; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glColorMask(value.r, value.g, value.b, value.a));
- }
- inline static Type Get() {
- GLboolean bools[4];
- MBGL_CHECK_ERROR(glGetBooleanv(GL_COLOR_WRITEMASK, bools));
- return { static_cast<bool>(bools[0]), static_cast<bool>(bools[1]),
- static_cast<bool>(bools[2]), static_cast<bool>(bools[3]) };
- }
-};
-
-inline bool operator!=(const ColorMask::Type& a, const ColorMask::Type& b) {
- return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
-}
-
-struct StencilFunc {
- struct Type { GLenum func; GLint ref; GLuint mask; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glStencilFunc(value.func, value.ref, value.mask));
- }
- inline static Type Get() {
- GLint func, ref, mask;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FUNC, &func));
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_REF, &ref));
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask));
- return { static_cast<GLenum>(func), ref, static_cast<GLuint>(mask) };
- }
-};
-
-inline bool operator!=(const StencilFunc::Type& a, const StencilFunc::Type& b) {
- return a.func != b.func || a.ref != b.ref || a.mask != b.mask;
-}
-
-struct StencilTest {
- using Type = bool;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(value ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST));
- }
- inline static Type Get() {
- Type stencilTest;
- MBGL_CHECK_ERROR(stencilTest = glIsEnabled(GL_STENCIL_TEST));
- return stencilTest;
- }
-};
-
-struct StencilOp {
- struct Type { GLenum sfail, dpfail, dppass; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glStencilOp(value.sfail, value.dpfail, value.dppass));
- }
- inline static Type Get() {
- GLint sfail, dpfail, dppass;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FAIL, &sfail));
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &dpfail));
- MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &dppass));
- return { static_cast<GLenum>(sfail), static_cast<GLenum>(dpfail), static_cast<GLuint>(dppass) };
- }
-};
-
-struct DepthRange {
- struct Type { GLfloat near, far; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glDepthRange(value.near, value.far));
- }
- inline static Type Get() {
- GLfloat floats[2];
- MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats));
- return { floats[0], floats[1] };
- }
-};
-
-inline bool operator!=(const DepthRange::Type& a, const DepthRange::Type& b) {
- return a.near != b.near || a.far != b.far;
-}
-
-struct DepthTest {
- using Type = bool;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
- }
- inline static Type Get() {
- Type depthTest;
- MBGL_CHECK_ERROR(depthTest = glIsEnabled(GL_DEPTH_TEST));
- return depthTest;
- }
-};
-
-struct DepthFunc {
- using Type = GLenum;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glDepthFunc(value));
- }
- inline static Type Get() {
- GLint depthFunc;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_DEPTH_FUNC, &depthFunc));
- return depthFunc;
- }
-};
-
-struct Blend {
- using Type = bool;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(value ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
- }
- inline static Type Get() {
- Type blend;
- MBGL_CHECK_ERROR(blend = glIsEnabled(GL_BLEND));
- return blend;
- }
-};
-
-struct BlendFunc {
- struct Type { GLenum sfactor, dfactor; };
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glBlendFunc(value.sfactor, value.dfactor));
- }
- inline static Type Get() {
- GLint sfactor, dfactor;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_SRC_ALPHA, &sfactor));
- MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_DST_ALPHA, &dfactor));
- return { static_cast<GLenum>(sfactor), static_cast<GLenum>(dfactor) };
- }
-};
-
-struct Program {
- using Type = GLuint;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glUseProgram(value));
- }
- inline static Type Get() {
- GLint program;
- MBGL_CHECK_ERROR(glGetIntegerv(GL_CURRENT_PROGRAM, &program));
- return program;
- }
-};
-
-struct LineWidth {
- using Type = GLfloat;
- static const Type Default;
- inline static void Set(const Type& value) {
- MBGL_CHECK_ERROR(glLineWidth(value));
- }
- inline static Type Get() {
- Type lineWidth;
- MBGL_CHECK_ERROR(glGetFloatv(GL_LINE_WIDTH, &lineWidth));
- return lineWidth;
- }
-};
-
-class Config {
-public:
- void reset() {
- stencilFunc.reset();
- stencilMask.reset();
- stencilTest.reset();
- stencilOp.reset();
- depthRange.reset();
- depthMask.reset();
- depthTest.reset();
- depthFunc.reset();
- blend.reset();
- blendFunc.reset();
- colorMask.reset();
- clearDepth.reset();
- clearColor.reset();
- clearStencil.reset();
- program.reset();
- lineWidth.reset();
- }
-
- void setDirty() {
- stencilFunc.setDirty();
- stencilMask.setDirty();
- stencilTest.setDirty();
- stencilOp.setDirty();
- depthRange.setDirty();
- depthMask.setDirty();
- depthTest.setDirty();
- depthFunc.setDirty();
- blend.setDirty();
- blendFunc.setDirty();
- colorMask.setDirty();
- clearDepth.setDirty();
- clearColor.setDirty();
- clearStencil.setDirty();
- program.setDirty();
- lineWidth.setDirty();
- }
-
- Value<StencilFunc> stencilFunc;
- Value<StencilMask> stencilMask;
- Value<StencilTest> stencilTest;
- Value<StencilOp> stencilOp;
- Value<DepthRange> depthRange;
- Value<DepthMask> depthMask;
- Value<DepthTest> depthTest;
- Value<DepthFunc> depthFunc;
- Value<Blend> blend;
- Value<BlendFunc> blendFunc;
- Value<ColorMask> colorMask;
- Value<ClearDepth> clearDepth;
- Value<ClearColor> clearColor;
- Value<ClearStencil> clearStencil;
- Value<Program> program;
- Value<LineWidth> lineWidth;
-};
-
-} // namespace gl
-} // namespace mbgl
-
-#endif // MBGL_RENDERER_GL_CONFIG
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 83c5b43776..ba50e6b1f0 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -6,13 +6,14 @@
#include <mbgl/shader/linesdf_shader.hpp>
#include <mbgl/shader/linepattern_shader.hpp>
#include <mbgl/util/math.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/util/constants.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cassert>
using namespace mbgl;
-LineBucket::LineBucket() {
+LineBucket::LineBucket(float overscaling_) : overscaling(overscaling_) {
}
LineBucket::~LineBucket() {
@@ -25,6 +26,21 @@ void LineBucket::addGeometry(const GeometryCollection& geometryCollection) {
}
}
+
+/*
+ * Sharp corners cause dashed lines to tilt because the distance along the line
+ * is the same at both the inner and outer corners. To improve the appearance of
+ * dashed lines we add extra points near sharp corners so that a smaller part
+ * of the line is tilted.
+ *
+ * COS_HALF_SHARP_CORNER controls how sharp a corner has to be for us to add an
+ * extra vertex. The default is 75 degrees.
+ *
+ * The newly created vertices are placed SHARP_CORNER_OFFSET pixels from the corner.
+ */
+const float COS_HALF_SHARP_CORNER = std::cos(75.0 / 2.0 * (M_PI / 180.0));
+const float SHARP_CORNER_OFFSET = 15.0f;
+
void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
const GLsizei len = [&vertices] {
GLsizei l = static_cast<GLsizei>(vertices.size());
@@ -42,6 +58,8 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
const float miterLimit = layout.join == JoinType::Bevel ? 1.05f : float(layout.miterLimit);
+ const double sharpCornerOffset = SHARP_CORNER_OFFSET * (util::EXTENT / (512.0 * overscaling));
+
const Coordinate firstVertex = vertices.front();
const Coordinate lastVertex = vertices[len - 1];
const bool closed = firstVertex == lastVertex;
@@ -98,10 +116,6 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
currentVertex = vertices[i];
- // Calculate how far along the line the currentVertex is
- if (prevVertex)
- distance += util::dist<double>(currentVertex, prevVertex);
-
// Calculate the normal towards the next vertex in this line. In case
// there is no next vertex, pretend that the line is continuing straight,
// meaning that we are just using the previous normal.
@@ -134,6 +148,18 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
const float cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y;
const float miterLength = cosHalfAngle != 0 ? 1 / cosHalfAngle: 1;
+ const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex;
+
+ if (isSharpCorner && i > 0) {
+ const double prevSegmentLength = util::dist<double>(currentVertex, prevVertex);
+ if (prevSegmentLength > 2.0 * sharpCornerOffset) {
+ Coordinate newPrevVertex = currentVertex - (util::round(vec2<double>(currentVertex - prevVertex) * (sharpCornerOffset / prevSegmentLength)));
+ distance += util::dist<double>(newPrevVertex, prevVertex);
+ addCurrentVertex(newPrevVertex, flip, distance, prevNormal, 0, 0, false, startVertex, triangleStore);
+ prevVertex = newPrevVertex;
+ }
+ }
+
// The join if a middle vertex, otherwise the cap
const bool middleVertex = prevVertex && nextVertex;
JoinType currentJoin = layout.join;
@@ -167,6 +193,10 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
}
}
+ // Calculate how far along the line the currentVertex is
+ if (prevVertex)
+ distance += util::dist<double>(currentVertex, prevVertex);
+
if (middleVertex && currentJoin == JoinType::Miter) {
joinNormal = joinNormal * miterLength;
addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex,
@@ -295,6 +325,16 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
}
}
+ if (isSharpCorner && i < len - 1) {
+ const double nextSegmentLength = util::dist<double>(currentVertex, nextVertex);
+ if (nextSegmentLength > 2 * sharpCornerOffset) {
+ Coordinate newCurrentVertex = currentVertex + util::round(vec2<double>(nextVertex - currentVertex) * (sharpCornerOffset / nextSegmentLength));
+ distance += util::dist<double>(newCurrentVertex, currentVertex);
+ addCurrentVertex(newCurrentVertex, flip, distance, nextNormal, 0, 0, false, startVertex, triangleStore);
+ currentVertex = newCurrentVertex;
+ }
+ }
+
startOfLine = false;
}
@@ -378,9 +418,9 @@ void LineBucket::addPieSliceVertex(const Coordinate& currentVertex,
}
}
-void LineBucket::upload() {
- vertexBuffer.upload();
- triangleElementsBuffer.upload();
+void LineBucket::upload(gl::GLObjectStore& glObjectStore) {
+ vertexBuffer.upload(glObjectStore);
+ triangleElementsBuffer.upload(glObjectStore);
// From now on, we're only going to render during the translucent pass.
uploaded = true;
@@ -397,7 +437,7 @@ bool LineBucket::hasData() const {
return !triangleGroups.empty();
}
-void LineBucket::drawLines(LineShader& shader) {
+void LineBucket::drawLines(LineShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -405,7 +445,7 @@ void LineBucket::drawLines(LineShader& shader) {
if (!group->elements_length) {
continue;
}
- group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
+ group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
@@ -413,7 +453,7 @@ void LineBucket::drawLines(LineShader& shader) {
}
}
-void LineBucket::drawLineSDF(LineSDFShader& shader) {
+void LineBucket::drawLineSDF(LineSDFShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -421,7 +461,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader) {
if (!group->elements_length) {
continue;
}
- group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
+ group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
@@ -429,7 +469,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader) {
}
}
-void LineBucket::drawLinePatterns(LinepatternShader& shader) {
+void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
@@ -437,7 +477,7 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader) {
if (!group->elements_length) {
continue;
}
- group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
+ group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 7d662aac02..dd0ce4ff29 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -2,7 +2,7 @@
#define MBGL_RENDERER_LINEBUCKET
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
@@ -24,19 +24,19 @@ class LineBucket : public Bucket {
using TriangleGroup = ElementGroup<3>;
public:
- LineBucket();
+ LineBucket(float overscaling);
~LineBucket() override;
- void upload() override;
+ void upload(gl::GLObjectStore&) override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
bool hasData() const override;
void addGeometry(const GeometryCollection&);
void addGeometry(const std::vector<Coordinate>& line);
- void drawLines(LineShader& shader);
- void drawLineSDF(LineSDFShader& shader);
- void drawLinePatterns(LinepatternShader& shader);
+ void drawLines(LineShader&, gl::GLObjectStore&);
+ void drawLineSDF(LineSDFShader&, gl::GLObjectStore&);
+ void drawLinePatterns(LinepatternShader&, gl::GLObjectStore&);
private:
struct TriangleElement {
@@ -62,6 +62,8 @@ private:
GLint e3;
std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
+
+ const float overscaling;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 0fd76314dc..da3551aa74 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -1,7 +1,7 @@
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/map/source.hpp>
-#include <mbgl/map/tile.hpp>
+#include <mbgl/source/source.hpp>
+#include <mbgl/tile/tile.hpp>
#include <mbgl/map/map_context.hpp>
#include <mbgl/map/map_data.hpp>
@@ -46,23 +46,25 @@
using namespace mbgl;
-Painter::Painter(MapData& data_, TransformState& state_)
- : data(data_), state(state_) {
+Painter::Painter(MapData& data_, TransformState& state_, gl::GLObjectStore& glObjectStore_)
+ : data(data_),
+ state(state_),
+ glObjectStore(glObjectStore_) {
gl::debugging::enable();
- plainShader = std::make_unique<PlainShader>();
- outlineShader = std::make_unique<OutlineShader>();
- lineShader = std::make_unique<LineShader>();
- linesdfShader = std::make_unique<LineSDFShader>();
- linepatternShader = std::make_unique<LinepatternShader>();
- patternShader = std::make_unique<PatternShader>();
- iconShader = std::make_unique<IconShader>();
- rasterShader = std::make_unique<RasterShader>();
- sdfGlyphShader = std::make_unique<SDFGlyphShader>();
- sdfIconShader = std::make_unique<SDFIconShader>();
- dotShader = std::make_unique<DotShader>();
- collisionBoxShader = std::make_unique<CollisionBoxShader>();
- circleShader = std::make_unique<CircleShader>();
+ plainShader = std::make_unique<PlainShader>(glObjectStore);
+ outlineShader = std::make_unique<OutlineShader>(glObjectStore);
+ lineShader = std::make_unique<LineShader>(glObjectStore);
+ linesdfShader = std::make_unique<LineSDFShader>(glObjectStore);
+ linepatternShader = std::make_unique<LinepatternShader>(glObjectStore);
+ patternShader = std::make_unique<PatternShader>(glObjectStore);
+ iconShader = std::make_unique<IconShader>(glObjectStore);
+ rasterShader = std::make_unique<RasterShader>(glObjectStore);
+ sdfGlyphShader = std::make_unique<SDFGlyphShader>(glObjectStore);
+ sdfIconShader = std::make_unique<SDFIconShader>(glObjectStore);
+ dotShader = std::make_unique<DotShader>(glObjectStore);
+ collisionBoxShader = std::make_unique<CollisionBoxShader>(glObjectStore);
+ circleShader = std::make_unique<CircleShader>(glObjectStore);
// Reset GL values
config.reset();
@@ -108,16 +110,16 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
{
MBGL_DEBUG_GROUP("upload");
- tileStencilBuffer.upload();
- tileBorderBuffer.upload();
- spriteAtlas->upload();
- lineAtlas->upload();
- glyphAtlas->upload();
- annotationSpriteAtlas.upload();
+ tileStencilBuffer.upload(glObjectStore);
+ tileBorderBuffer.upload(glObjectStore);
+ spriteAtlas->upload(glObjectStore);
+ lineAtlas->upload(glObjectStore);
+ glyphAtlas->upload(glObjectStore);
+ annotationSpriteAtlas.upload(glObjectStore);
for (const auto& item : order) {
if (item.bucket && item.bucket->needsUpload()) {
- item.bucket->upload();
+ item.bucket->upload(glObjectStore);
}
}
}
@@ -151,7 +153,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
source->updateMatrices(projMatrix, state);
}
- drawClippingMasks(sources);
+ drawClippingMasks(generator.getStencils());
}
frameHistory.record(data.getAnimationTime(), state.getZoom());
@@ -270,7 +272,7 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
float zoomFraction = state.getZoomFraction();
- config.program = patternShader->program;
+ config.program = patternShader->getID();
patternShader->u_matrix = identityMatrix;
patternShader->u_pattern_tl_a = (*imagePosA).tl;
patternShader->u_pattern_br_a = (*imagePosA).br;
@@ -315,9 +317,9 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
patternShader->u_patternmatrix_b = matrixB;
VertexArrayObject::Unbind();
- backgroundBuffer.bind();
+ backgroundBuffer.bind(glObjectStore);
patternShader->bind(0);
- spriteAtlas->bind(true);
+ spriteAtlas->bind(true, glObjectStore);
} else {
Color color = properties.color;
color[0] *= properties.opacity;
@@ -325,10 +327,10 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
color[2] *= properties.opacity;
color[3] *= properties.opacity;
- config.program = plainShader->program;
+ config.program = plainShader->getID();
plainShader->u_matrix = identityMatrix;
plainShader->u_color = color;
- backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0));
+ backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0), glObjectStore);
}
config.stencilTest = GL_FALSE;
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 092c164033..83d051359b 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -10,11 +10,11 @@
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/static_vertex_buffer.hpp>
-#include <mbgl/renderer/gl_config.hpp>
+#include <mbgl/gl/gl_config.hpp>
#include <mbgl/style/types.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/chrono.hpp>
@@ -66,9 +66,13 @@ class CollisionBoxShader;
struct ClipID;
+namespace util {
+class GLObjectStore;
+}
+
class Painter : private util::noncopyable {
public:
- Painter(MapData&, TransformState&);
+ Painter(MapData&, TransformState&, gl::GLObjectStore&);
~Painter();
void render(const Style& style,
@@ -93,8 +97,7 @@ public:
float contrastFactor(float contrast);
std::array<float, 3> spinWeights(float spin_value);
- void drawClippingMasks(const std::set<Source*>&);
- void drawClippingMask(const mat4& matrix, const ClipID& clip);
+ void drawClippingMasks(const std::map<TileID, ClipID>&);
bool needsAnimation() const;
@@ -119,7 +122,7 @@ private:
float scaleDivisor,
std::array<float, 2> texsize,
SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&));
+ void (SymbolBucket::*drawSDF)(SDFShader&, gl::GLObjectStore&));
void setDepthSublayer(int n);
@@ -143,6 +146,8 @@ private:
MapData& data;
TransformState& state;
+ gl::GLObjectStore& glObjectStore;
+
FrameData frame;
int indent = 0;
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 9518cf9e39..4ae562d674 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -38,7 +38,7 @@ void Painter::renderCircle(CircleBucket& bucket,
// are inversely related.
float antialiasing = 1 / data.pixelRatio / properties.radius;
- config.program = circleShader->program;
+ config.program = circleShader->getID();
circleShader->u_matrix = vtxMatrix;
circleShader->u_exmatrix = extrudeMatrix;
@@ -46,5 +46,5 @@ void Painter::renderCircle(CircleBucket& bucket,
circleShader->u_blur = std::max<float>(properties.blur, antialiasing);
circleShader->u_size = properties.radius;
- bucket.drawCircles(*circleShader);
+ bucket.drawCircles(*circleShader, glObjectStore);
}
diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp
index 6994650412..aed4c45869 100644
--- a/src/mbgl/renderer/painter_clipping.cpp
+++ b/src/mbgl/renderer/painter_clipping.cpp
@@ -1,36 +1,39 @@
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/map/source.hpp>
+#include <mbgl/source/source.hpp>
#include <mbgl/shader/plain_shader.hpp>
#include <mbgl/util/clip_id.hpp>
#include <mbgl/gl/debugging.hpp>
using namespace mbgl;
-void Painter::drawClippingMasks(const std::set<Source*>& sources) {
+
+void Painter::drawClippingMasks(const std::map<TileID, ClipID>& stencils) {
MBGL_DEBUG_GROUP("clipping masks");
- config.program = plainShader->program;
+ mat4 matrix;
+ const GLuint mask = 0b11111111;
+
+ config.program = plainShader->getID();
config.stencilOp.reset();
config.stencilTest = GL_TRUE;
- config.depthFunc.reset();
- config.depthTest = GL_TRUE;
+ config.depthTest = GL_FALSE;
config.depthMask = GL_FALSE;
config.colorMask = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };
- config.depthRange = { 1.0f, 1.0f };
+ config.stencilMask = mask;
- coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET_0);
+ coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET_0, glObjectStore);
- for (const auto& source : sources) {
- source->drawClippingMasks(*this);
- }
-}
+ for (const auto& stencil : stencils) {
+ const auto& id = stencil.first;
+ const auto& clip = stencil.second;
-void Painter::drawClippingMask(const mat4& matrix, const ClipID &clip) {
- plainShader->u_matrix = matrix;
+ MBGL_DEBUG_GROUP(std::string{ "mask: " } + std::string(id));
+ state.matrixFor(matrix, id, id.z);
+ matrix::multiply(matrix, projMatrix, matrix);
+ plainShader->u_matrix = matrix;
- const GLint ref = (GLint)(clip.reference.to_ulong());
- const GLuint mask = (GLuint)(clip.mask.to_ulong());
- config.stencilFunc = { GL_ALWAYS, ref, mask };
- config.stencilMask = mask;
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()));
+ const GLint ref = (GLint)(clip.reference.to_ulong());
+ config.stencilFunc = { GL_ALWAYS, ref, mask };
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()));
+ }
}
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index d6b1aec73c..575bffe53f 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -1,7 +1,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
-#include <mbgl/map/tile.hpp>
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <mbgl/map/map_data.hpp>
#include <mbgl/shader/plain_shader.hpp>
#include <mbgl/util/string.hpp>
@@ -15,7 +15,9 @@ void Painter::renderTileDebug(const Tile& tile) {
if (data.getDebug() != MapDebugOptions::NoDebug) {
prepareTile(tile);
renderDebugText(*tile.data, tile.matrix);
- renderDebugFrame(tile.matrix);
+ if (data.getDebug() & MapDebugOptions::TileBorders) {
+ renderDebugFrame(tile.matrix);
+ }
}
}
@@ -31,24 +33,24 @@ void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) {
tileData.debugBucket = std::make_unique<DebugBucket>(tileData.id, tileData.getState(), tileData.modified, tileData.expires, data.getDebug());
}
- config.program = plainShader->program;
+ config.program = plainShader->getID();
plainShader->u_matrix = matrix;
// Draw white outline
plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
config.lineWidth = 4.0f * data.pixelRatio;
- tileData.debugBucket->drawLines(*plainShader);
+ tileData.debugBucket->drawLines(*plainShader, glObjectStore);
#ifndef GL_ES_VERSION_2_0
// Draw line "end caps"
MBGL_CHECK_ERROR(glPointSize(2));
- tileData.debugBucket->drawPoints(*plainShader);
+ tileData.debugBucket->drawPoints(*plainShader, glObjectStore);
#endif
// Draw black text.
plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
config.lineWidth = 2.0f * data.pixelRatio;
- tileData.debugBucket->drawLines(*plainShader);
+ tileData.debugBucket->drawLines(*plainShader, glObjectStore);
config.depthFunc.reset();
config.depthTest = GL_TRUE;
@@ -64,11 +66,11 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
config.stencilOp.reset();
config.stencilTest = GL_TRUE;
- config.program = plainShader->program;
+ config.program = plainShader->getID();
plainShader->u_matrix = matrix;
// draw tile outline
- tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET_0);
+ tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET_0, glObjectStore);
plainShader->u_color = {{ 1.0f, 0.0f, 0.0f, 1.0f }};
config.lineWidth = 4.0f * data.pixelRatio;
MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()));
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 44ae1919a0..cd54645c2b 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -44,7 +44,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
// Because we're drawing top-to-bottom, and we update the stencil mask
// befrom, we have to draw the outline first (!)
if (outline && pass == RenderPass::Translucent) {
- config.program = outlineShader->program;
+ config.program = outlineShader->getID();
outlineShader->u_matrix = vtxMatrix;
config.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
@@ -56,7 +56,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
static_cast<float>(frame.framebufferSize[1])
}};
setDepthSublayer(0);
- bucket.drawVertices(*outlineShader);
+ bucket.drawVertices(*outlineShader, glObjectStore);
}
if (pattern) {
@@ -78,7 +78,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
1.0f / ((*posB).size[0] * factor * properties.pattern.value.toScale),
1.0f / ((*posB).size[1] * factor * properties.pattern.value.toScale));
- config.program = patternShader->program;
+ config.program = patternShader->getID();
patternShader->u_matrix = vtxMatrix;
patternShader->u_pattern_tl_a = (*posA).tl;
patternShader->u_pattern_br_a = (*posA).br;
@@ -111,11 +111,11 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
patternShader->u_offset_b = std::array<float, 2>{{offsetBx, offsetBy}};
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
- spriteAtlas->bind(true);
+ spriteAtlas->bind(true, glObjectStore);
// Draw the actual triangles into the color & stencil buffer.
setDepthSublayer(0);
- bucket.drawElements(*patternShader);
+ bucket.drawElements(*patternShader, glObjectStore);
}
}
else {
@@ -125,20 +125,20 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
// fragments or when it's translucent and we're drawing translucent
// fragments
// Draw filling rectangle.
- config.program = plainShader->program;
+ config.program = plainShader->getID();
plainShader->u_matrix = vtxMatrix;
plainShader->u_color = fill_color;
// Draw the actual triangles into the color & stencil buffer.
setDepthSublayer(1);
- bucket.drawElements(*plainShader);
+ bucket.drawElements(*plainShader, glObjectStore);
}
}
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (fringeline && pass == RenderPass::Translucent) {
- config.program = outlineShader->program;
+ config.program = outlineShader->getID();
outlineShader->u_matrix = vtxMatrix;
config.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
@@ -151,6 +151,6 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI
}};
setDepthSublayer(2);
- bucket.drawVertices(*outlineShader);
+ bucket.drawVertices(*outlineShader, glObjectStore);
}
}
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index dd2833b117..5fc5ee0221 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -70,7 +70,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
if (!properties.dasharray.value.from.empty()) {
- config.program = linesdfShader->program;
+ config.program = linesdfShader->getID();
linesdfShader->u_matrix = vtxMatrix;
linesdfShader->u_exmatrix = extrudeMatrix;
@@ -79,9 +79,9 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
linesdfShader->u_blur = blur;
linesdfShader->u_color = color;
- LinePatternPos posA = lineAtlas->getDashPosition(properties.dasharray.value.from, layout.cap == CapType::Round);
- LinePatternPos posB = lineAtlas->getDashPosition(properties.dasharray.value.to, layout.cap == CapType::Round);
- lineAtlas->bind();
+ LinePatternPos posA = lineAtlas->getDashPosition(properties.dasharray.value.from, layout.cap == CapType::Round, glObjectStore);
+ LinePatternPos posB = lineAtlas->getDashPosition(properties.dasharray.value.to, layout.cap == CapType::Round, glObjectStore);
+ lineAtlas->bind(glObjectStore);
const float widthA = posA.width * properties.dasharray.value.fromScale;
const float widthB = posB.width * properties.dasharray.value.toScale;
@@ -102,7 +102,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
linesdfShader->u_offset = -properties.offset;
linesdfShader->u_antialiasingmatrix = antialiasingMatrix;
- bucket.drawLineSDF(*linesdfShader);
+ bucket.drawLineSDF(*linesdfShader, glObjectStore);
} else if (!properties.pattern.value.from.empty()) {
optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.pattern.value.from, true);
@@ -113,7 +113,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
float factor = util::EXTENT / (512 * id.overscaling) / std::pow(2, state.getIntegerZoom() - id.z);
- config.program = linepatternShader->program;
+ config.program = linepatternShader->getID();
linepatternShader->u_matrix = vtxMatrix;
linepatternShader->u_exmatrix = extrudeMatrix;
@@ -134,12 +134,12 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
linepatternShader->u_antialiasingmatrix = antialiasingMatrix;
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
- spriteAtlas->bind(true);
+ spriteAtlas->bind(true, glObjectStore);
- bucket.drawLinePatterns(*linepatternShader);
+ bucket.drawLinePatterns(*linepatternShader, glObjectStore);
} else {
- config.program = lineShader->program;
+ config.program = lineShader->getID();
lineShader->u_matrix = vtxMatrix;
lineShader->u_exmatrix = extrudeMatrix;
@@ -152,6 +152,6 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI
lineShader->u_color = color;
- bucket.drawLines(*lineShader);
+ bucket.drawLines(*lineShader, glObjectStore);
}
}
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 3fd953fcd6..377b2c005c 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -1,5 +1,5 @@
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
#include <mbgl/layer/raster_layer.hpp>
#include <mbgl/shader/raster_shader.hpp>
@@ -12,7 +12,7 @@ void Painter::renderRaster(RasterBucket& bucket, const RasterLayer& layer, const
const RasterPaintProperties& properties = layer.paint;
if (bucket.hasData()) {
- config.program = rasterShader->program;
+ config.program = rasterShader->getID();
rasterShader->u_matrix = matrix;
rasterShader->u_buffer = 0;
rasterShader->u_opacity = properties.opacity;
@@ -28,7 +28,7 @@ void Painter::renderRaster(RasterBucket& bucket, const RasterLayer& layer, const
config.depthTest = GL_TRUE;
config.depthMask = GL_FALSE;
setDepthSublayer(0);
- bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray);
+ bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray, glObjectStore);
}
}
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 0538485824..5f59d6a8a6 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -23,7 +23,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
float sdfFontSize,
std::array<float, 2> texsize,
SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&))
+ void (SymbolBucket::*drawSDF)(SDFShader&, gl::GLObjectStore&))
{
mat4 vtxMatrix = translatedMatrix(matrix, styleProperties.translate, id, styleProperties.translateAnchor);
@@ -49,7 +49,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
float fontScale = fontSize / sdfFontSize;
matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f);
- config.program = sdfShader.program;
+ config.program = sdfShader.getID();
sdfShader.u_matrix = vtxMatrix;
sdfShader.u_exmatrix = exMatrix;
sdfShader.u_texsize = texsize;
@@ -101,7 +101,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
sdfShader.u_buffer = (haloOffset - styleProperties.haloWidth / fontScale) / sdfPx;
setDepthSublayer(0);
- (bucket.*drawSDF)(sdfShader);
+ (bucket.*drawSDF)(sdfShader, glObjectStore);
}
// Then, we draw the text/icon over the halo
@@ -122,7 +122,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f;
setDepthSublayer(1);
- (bucket.*drawSDF)(sdfShader);
+ (bucket.*drawSDF)(sdfShader, glObjectStore);
}
}
@@ -137,22 +137,6 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
config.depthMask = GL_FALSE;
- if (bucket.hasCollisionBoxData()) {
- config.stencilOp.reset();
- config.stencilTest = GL_TRUE;
-
- config.program = collisionBoxShader->program;
- collisionBoxShader->u_matrix = matrix;
- collisionBoxShader->u_scale = std::pow(2, state.getZoom() - id.z);
- collisionBoxShader->u_zoom = state.getZoom() * 10;
- collisionBoxShader->u_maxzoom = (id.z + 1) * 10;
- config.lineWidth = 1.0f;
-
- setDepthSublayer(0);
- bucket.drawCollisionBoxes(*collisionBoxShader);
-
- }
-
// TODO remove the `true ||` when #1673 is implemented
const bool drawAcrossEdges = (data.mode == MapMode::Continuous) && (true || !(layout.text.allowOverlap || layout.icon.allowOverlap ||
layout.text.ignorePlacement || layout.icon.ignorePlacement));
@@ -190,7 +174,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
SpriteAtlas* activeSpriteAtlas = layer.spriteAtlas;
const bool iconScaled = fontScale != 1 || data.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear;
const bool iconTransformed = layout.icon.rotationAlignment == RotationAlignmentType::Map || angleOffset != 0 || state.getPitch() != 0;
- activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed);
+ activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed, glObjectStore);
if (sdf) {
renderSDF(bucket,
@@ -227,7 +211,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
float x = state.getHeight() / 2.0f * std::tan(state.getPitch());
float extra = (topedgelength + x) / topedgelength - 1;
- config.program = iconShader->program;
+ config.program = iconShader->getID();
iconShader->u_matrix = vtxMatrix;
iconShader->u_exmatrix = exMatrix;
iconShader->u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
@@ -246,7 +230,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
iconShader->u_opacity = properties.icon.opacity;
setDepthSublayer(0);
- bucket.drawIcons(*iconShader);
+ bucket.drawIcons(*iconShader, glObjectStore);
}
}
@@ -258,7 +242,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
config.depthTest = GL_FALSE;
}
- glyphAtlas->bind();
+ glyphAtlas->bind(glObjectStore);
renderSDF(bucket,
id,
@@ -271,4 +255,20 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const
&SymbolBucket::drawGlyphs);
}
+ if (bucket.hasCollisionBoxData()) {
+ config.stencilOp.reset();
+ config.stencilTest = GL_TRUE;
+
+ config.program = collisionBoxShader->getID();
+ collisionBoxShader->u_matrix = matrix;
+ collisionBoxShader->u_scale = std::pow(2, state.getZoom() - id.z);
+ collisionBoxShader->u_zoom = state.getZoom() * 10;
+ collisionBoxShader->u_maxzoom = (id.z + 1) * 10;
+ config.lineWidth = 1.0f;
+
+ setDepthSublayer(0);
+ bucket.drawCollisionBoxes(*collisionBoxShader, glObjectStore);
+
+ }
+
}
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index 4dbbf18697..137574b731 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -5,13 +5,13 @@
using namespace mbgl;
-RasterBucket::RasterBucket(TexturePool& texturePool)
+RasterBucket::RasterBucket(gl::TexturePool& texturePool)
: raster(texturePool) {
}
-void RasterBucket::upload() {
+void RasterBucket::upload(gl::GLObjectStore& glObjectStore) {
if (hasData()) {
- raster.upload();
+ raster.upload(glObjectStore);
uploaded = true;
}
}
@@ -27,10 +27,10 @@ void RasterBucket::setImage(PremultipliedImage image) {
raster.load(std::move(image));
}
-void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array) {
- raster.bind(true);
+void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, gl::GLObjectStore& glObjectStore) {
+ raster.bind(true, glObjectStore);
shader.u_image = 0;
- array.bind(shader, vertices, BUFFER_OFFSET_0);
+ array.bind(shader, vertices, BUFFER_OFFSET_0, glObjectStore);
MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index()));
}
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index 0f6237969a..466a7602ed 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -12,15 +12,15 @@ class VertexArrayObject;
class RasterBucket : public Bucket {
public:
- RasterBucket(TexturePool&);
+ RasterBucket(gl::TexturePool&);
- void upload() override;
+ void upload(gl::GLObjectStore&) override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
bool hasData() const override;
void setImage(PremultipliedImage);
- void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array);
+ void drawRaster(RasterShader&, StaticVertexBuffer&, VertexArrayObject&, gl::GLObjectStore&);
Raster raster;
};
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index e4fccc22e9..683a6f4b11 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,6 +1,6 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/layer/symbol_layer.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/sprite/sprite_store.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
@@ -64,14 +64,14 @@ SymbolBucket::~SymbolBucket() {
// Do not remove. header file only contains forward definitions to unique pointers.
}
-void SymbolBucket::upload() {
+void SymbolBucket::upload(gl::GLObjectStore& glObjectStore) {
if (hasTextData()) {
- renderData->text.vertices.upload();
- renderData->text.triangles.upload();
+ renderData->text.vertices.upload(glObjectStore);
+ renderData->text.triangles.upload(glObjectStore);
}
if (hasIconData()) {
- renderData->icon.vertices.upload();
- renderData->icon.triangles.upload();
+ renderData->icon.vertices.upload(glObjectStore);
+ renderData->icon.triangles.upload(glObjectStore);
}
uploaded = true;
@@ -572,50 +572,50 @@ void SymbolBucket::swapRenderData() {
}
}
-void SymbolBucket::drawGlyphs(SDFShader &shader) {
+void SymbolBucket::drawGlyphs(SDFShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& text = renderData->text;
for (auto &group : text.groups) {
assert(group);
- group->array[0].bind(shader, text.vertices, text.triangles, vertex_index);
+ group->array[0].bind(shader, text.vertices, text.triangles, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * text.vertices.itemSize;
elements_index += group->elements_length * text.triangles.itemSize;
}
}
-void SymbolBucket::drawIcons(SDFShader &shader) {
+void SymbolBucket::drawIcons(SDFShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
- group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index);
+ group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
}
}
-void SymbolBucket::drawIcons(IconShader &shader) {
+void SymbolBucket::drawIcons(IconShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
GLbyte *elements_index = BUFFER_OFFSET_0;
auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
- group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index);
+ group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
}
}
-void SymbolBucket::drawCollisionBoxes(CollisionBoxShader &shader) {
+void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader, gl::GLObjectStore& glObjectStore) {
GLbyte *vertex_index = BUFFER_OFFSET_0;
auto& collisionBox = renderData->collisionBox;
for (auto &group : collisionBox.groups) {
- group->array[0].bind(shader, collisionBox.vertices, vertex_index);
+ group->array[0].bind(shader, collisionBox.vertices, vertex_index, glObjectStore);
MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length));
}
}
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 5728cfa28c..cebb7e5dbe 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -2,7 +2,7 @@
#define MBGL_RENDERER_SYMBOLBUCKET
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
@@ -70,7 +70,7 @@ public:
SymbolBucket(float overscaling, float zoom, const MapMode);
~SymbolBucket() override;
- void upload() override;
+ void upload(gl::GLObjectStore&) override;
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
bool hasData() const override;
bool hasTextData() const;
@@ -82,10 +82,10 @@ public:
GlyphAtlas&,
GlyphStore&);
- void drawGlyphs(SDFShader& shader);
- void drawIcons(SDFShader& shader);
- void drawIcons(IconShader& shader);
- void drawCollisionBoxes(CollisionBoxShader& shader);
+ void drawGlyphs(SDFShader&, gl::GLObjectStore&);
+ void drawIcons(SDFShader&, gl::GLObjectStore&);
+ void drawIcons(IconShader&, gl::GLObjectStore&);
+ void drawCollisionBoxes(CollisionBoxShader&, gl::GLObjectStore&);
void parseFeatures(const GeometryTileLayer&,
const FilterExpression&);
diff --git a/src/mbgl/shader/box_shader.cpp b/src/mbgl/shader/box_shader.cpp
index d9845ec36f..63f800ea69 100644
--- a/src/mbgl/shader/box_shader.cpp
+++ b/src/mbgl/shader/box_shader.cpp
@@ -1,16 +1,16 @@
#include <mbgl/shader/box_shader.hpp>
#include <mbgl/shader/box.vertex.hpp>
#include <mbgl/shader/box.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-CollisionBoxShader::CollisionBoxShader()
- : Shader("collisionbox", shaders::box::vertex, shaders::box::fragment) {
- a_extrude = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_extrude"));
- a_data = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data"));
+CollisionBoxShader::CollisionBoxShader(gl::GLObjectStore& glObjectStore)
+ : Shader("collisionbox", shaders::box::vertex, shaders::box::fragment, glObjectStore) {
+ a_extrude = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_extrude"));
+ a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"));
}
void CollisionBoxShader::bind(GLbyte *offset) {
diff --git a/src/mbgl/shader/box_shader.hpp b/src/mbgl/shader/box_shader.hpp
index 19df2ca825..f3015b73a7 100644
--- a/src/mbgl/shader/box_shader.hpp
+++ b/src/mbgl/shader/box_shader.hpp
@@ -3,13 +3,13 @@
#include <mbgl/shader/shader.hpp>
#include <mbgl/shader/uniform.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
namespace mbgl {
class CollisionBoxShader : public Shader {
public:
- CollisionBoxShader();
+ CollisionBoxShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp
index 0af5bcf604..3ec822747f 100644
--- a/src/mbgl/shader/circle_shader.cpp
+++ b/src/mbgl/shader/circle_shader.cpp
@@ -1,14 +1,14 @@
#include <mbgl/shader/circle_shader.hpp>
#include <mbgl/shader/circle.vertex.hpp>
#include <mbgl/shader/circle.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-CircleShader::CircleShader()
- : Shader("circle", shaders::circle::vertex, shaders::circle::fragment) {
+CircleShader::CircleShader(gl::GLObjectStore& glObjectStore)
+ : Shader("circle", shaders::circle::vertex, shaders::circle::fragment, glObjectStore) {
}
void CircleShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp
index 7c1212c275..a28bf3c6ae 100644
--- a/src/mbgl/shader/circle_shader.hpp
+++ b/src/mbgl/shader/circle_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class CircleShader : public Shader {
public:
- CircleShader();
+ CircleShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/dot_shader.cpp b/src/mbgl/shader/dot_shader.cpp
index 2eba489b66..9d60306da2 100644
--- a/src/mbgl/shader/dot_shader.cpp
+++ b/src/mbgl/shader/dot_shader.cpp
@@ -1,13 +1,14 @@
#include <mbgl/shader/dot_shader.hpp>
#include <mbgl/shader/dot.vertex.hpp>
#include <mbgl/shader/dot.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-DotShader::DotShader() : Shader("dot", shaders::dot::vertex, shaders::dot::fragment) {
+DotShader::DotShader(gl::GLObjectStore& glObjectStore)
+ : Shader("dot", shaders::dot::vertex, shaders::dot::fragment, glObjectStore) {
}
void DotShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/dot_shader.hpp b/src/mbgl/shader/dot_shader.hpp
index 606764c2d6..a015310a62 100644
--- a/src/mbgl/shader/dot_shader.hpp
+++ b/src/mbgl/shader/dot_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class DotShader : public Shader {
public:
- DotShader();
+ DotShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp
index bb43cb3e4a..2ff653a87c 100644
--- a/src/mbgl/shader/icon_shader.cpp
+++ b/src/mbgl/shader/icon_shader.cpp
@@ -1,16 +1,17 @@
#include <mbgl/shader/icon_shader.hpp>
#include <mbgl/shader/icon.vertex.hpp>
#include <mbgl/shader/icon.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-IconShader::IconShader() : Shader("icon", shaders::icon::vertex, shaders::icon::fragment) {
- a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_offset"));
- a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data1"));
- a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data2"));
+IconShader::IconShader(gl::GLObjectStore& glObjectStore)
+ : Shader("icon", shaders::icon::vertex, shaders::icon::fragment, glObjectStore) {
+ a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset"));
+ a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1"));
+ a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2"));
}
void IconShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp
index 8a25b635fe..ec6311ea80 100644
--- a/src/mbgl/shader/icon_shader.hpp
+++ b/src/mbgl/shader/icon_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class IconShader : public Shader {
public:
- IconShader();
+ IconShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp
index 54bc6c1148..e4df0531d8 100644
--- a/src/mbgl/shader/line_shader.cpp
+++ b/src/mbgl/shader/line_shader.cpp
@@ -1,14 +1,15 @@
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/line.vertex.hpp>
#include <mbgl/shader/line.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-LineShader::LineShader() : Shader("line", shaders::line::vertex, shaders::line::fragment) {
- a_data = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data"));
+LineShader::LineShader(gl::GLObjectStore& glObjectStore)
+ : Shader("line", shaders::line::vertex, shaders::line::fragment, glObjectStore) {
+ a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"));
}
void LineShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp
index 14e03c2eaf..1a9598f925 100644
--- a/src/mbgl/shader/line_shader.hpp
+++ b/src/mbgl/shader/line_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class LineShader : public Shader {
public:
- LineShader();
+ LineShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp
index 9e71d0a9d9..7acd42f727 100644
--- a/src/mbgl/shader/linepattern_shader.cpp
+++ b/src/mbgl/shader/linepattern_shader.cpp
@@ -1,15 +1,15 @@
#include <mbgl/shader/linepattern_shader.hpp>
#include <mbgl/shader/linepattern.vertex.hpp>
#include <mbgl/shader/linepattern.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-LinepatternShader::LinepatternShader()
- : Shader("linepattern", shaders::linepattern::vertex, shaders::linepattern::fragment) {
- a_data = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data"));
+LinepatternShader::LinepatternShader(gl::GLObjectStore& glObjectStore)
+ : Shader("linepattern", shaders::linepattern::vertex, shaders::linepattern::fragment, glObjectStore) {
+ a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"));
}
void LinepatternShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp
index 6c83cb0cc3..0d3e98c834 100644
--- a/src/mbgl/shader/linepattern_shader.hpp
+++ b/src/mbgl/shader/linepattern_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class LinepatternShader : public Shader {
public:
- LinepatternShader();
+ LinepatternShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp
index df988bb337..00adaf0c86 100644
--- a/src/mbgl/shader/linesdf_shader.cpp
+++ b/src/mbgl/shader/linesdf_shader.cpp
@@ -1,15 +1,15 @@
#include <mbgl/shader/linesdf_shader.hpp>
#include <mbgl/shader/linesdf.vertex.hpp>
#include <mbgl/shader/linesdf.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-LineSDFShader::LineSDFShader()
- : Shader("line", shaders::linesdf::vertex, shaders::linesdf::fragment) {
- a_data = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data"));
+LineSDFShader::LineSDFShader(gl::GLObjectStore& glObjectStore)
+ : Shader("line", shaders::linesdf::vertex, shaders::linesdf::fragment, glObjectStore) {
+ a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data"));
}
void LineSDFShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp
index 2a8bdc6629..8ac0aa5793 100644
--- a/src/mbgl/shader/linesdf_shader.hpp
+++ b/src/mbgl/shader/linesdf_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class LineSDFShader : public Shader {
public:
- LineSDFShader();
+ LineSDFShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp
index 9cda1a1108..8c7458327f 100644
--- a/src/mbgl/shader/outline_shader.cpp
+++ b/src/mbgl/shader/outline_shader.cpp
@@ -1,14 +1,14 @@
#include <mbgl/shader/outline_shader.hpp>
#include <mbgl/shader/outline.vertex.hpp>
#include <mbgl/shader/outline.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-OutlineShader::OutlineShader()
- : Shader("outline", shaders::outline::vertex, shaders::outline::fragment) {
+OutlineShader::OutlineShader(gl::GLObjectStore& glObjectStore)
+ : Shader("outline", shaders::outline::vertex, shaders::outline::fragment, glObjectStore) {
}
void OutlineShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp
index 3af9b8349f..800461bf06 100644
--- a/src/mbgl/shader/outline_shader.hpp
+++ b/src/mbgl/shader/outline_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class OutlineShader : public Shader {
public:
- OutlineShader();
+ OutlineShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp
index ef3f35c356..4f52df59fb 100644
--- a/src/mbgl/shader/pattern_shader.cpp
+++ b/src/mbgl/shader/pattern_shader.cpp
@@ -1,16 +1,17 @@
#include <mbgl/shader/pattern_shader.hpp>
#include <mbgl/shader/pattern.vertex.hpp>
#include <mbgl/shader/pattern.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-PatternShader::PatternShader()
+PatternShader::PatternShader(gl::GLObjectStore& glObjectStore)
: Shader(
"pattern",
- shaders::pattern::vertex, shaders::pattern::fragment
+ shaders::pattern::vertex, shaders::pattern::fragment,
+ glObjectStore
) {
}
diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp
index db7901c578..8692f6ed39 100644
--- a/src/mbgl/shader/pattern_shader.hpp
+++ b/src/mbgl/shader/pattern_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class PatternShader : public Shader {
public:
- PatternShader();
+ PatternShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp
index 1817ffbc3d..1b5a7819b3 100644
--- a/src/mbgl/shader/plain_shader.cpp
+++ b/src/mbgl/shader/plain_shader.cpp
@@ -1,13 +1,14 @@
#include <mbgl/shader/plain_shader.hpp>
#include <mbgl/shader/plain.vertex.hpp>
#include <mbgl/shader/plain.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-PlainShader::PlainShader() : Shader("plain", shaders::plain::vertex, shaders::plain::fragment) {
+PlainShader::PlainShader(gl::GLObjectStore& glObjectStore)
+ : Shader("plain", shaders::plain::vertex, shaders::plain::fragment, glObjectStore) {
}
void PlainShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp
index f9b8c41a63..34ee4dcdf7 100644
--- a/src/mbgl/shader/plain_shader.hpp
+++ b/src/mbgl/shader/plain_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class PlainShader : public Shader {
public:
- PlainShader();
+ PlainShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp
index aaf0bfd2a5..77bcf40008 100644
--- a/src/mbgl/shader/raster_shader.cpp
+++ b/src/mbgl/shader/raster_shader.cpp
@@ -1,14 +1,14 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/shader/raster.vertex.hpp>
#include <mbgl/shader/raster.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-RasterShader::RasterShader()
- : Shader("raster", shaders::raster::vertex, shaders::raster::fragment) {
+RasterShader::RasterShader(gl::GLObjectStore& glObjectStore)
+ : Shader("raster", shaders::raster::vertex, shaders::raster::fragment, glObjectStore) {
}
void RasterShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp
index 60b283fc2a..6a2e2ecf3e 100644
--- a/src/mbgl/shader/raster_shader.hpp
+++ b/src/mbgl/shader/raster_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class RasterShader : public Shader {
public:
- RasterShader();
+ RasterShader(gl::GLObjectStore&);
void bind(GLbyte *offset) final;
diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp
index 97297a7baf..a972849d3d 100644
--- a/src/mbgl/shader/sdf_shader.cpp
+++ b/src/mbgl/shader/sdf_shader.cpp
@@ -1,16 +1,17 @@
#include <mbgl/shader/sdf_shader.hpp>
#include <mbgl/shader/sdf.vertex.hpp>
#include <mbgl/shader/sdf.fragment.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <cstdio>
using namespace mbgl;
-SDFShader::SDFShader() : Shader("sdf", shaders::sdf::vertex, shaders::sdf::fragment) {
- a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_offset"));
- a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data1"));
- a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_data2"));
+SDFShader::SDFShader(gl::GLObjectStore& glObjectStore)
+ : Shader("sdf", shaders::sdf::vertex, shaders::sdf::fragment, glObjectStore) {
+ a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset"));
+ a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1"));
+ a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2"));
}
void SDFGlyphShader::bind(GLbyte* offset) {
diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp
index 29dbfea047..402168de0c 100644
--- a/src/mbgl/shader/sdf_shader.hpp
+++ b/src/mbgl/shader/sdf_shader.hpp
@@ -8,7 +8,7 @@ namespace mbgl {
class SDFShader : public Shader {
public:
- SDFShader();
+ SDFShader(gl::GLObjectStore&);
UniformMatrix<4> u_matrix = {"u_matrix", *this};
UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this};
@@ -32,11 +32,13 @@ protected:
class SDFGlyphShader : public SDFShader {
public:
+ SDFGlyphShader(gl::GLObjectStore& glObjectStore) : SDFShader(glObjectStore) {}
void bind(GLbyte *offset) final;
};
class SDFIconShader : public SDFShader {
public:
+ SDFIconShader(gl::GLObjectStore& glObjectStore) : SDFShader(glObjectStore) {}
void bind(GLbyte *offset) final;
};
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp
index e8deefc8ff..8216de5b4d 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/shader/shader.cpp
@@ -1,5 +1,5 @@
#include <mbgl/shader/shader.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/stopwatch.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/platform/log.hpp>
@@ -11,94 +11,74 @@
#include <fstream>
#include <cstdio>
-using namespace mbgl;
+namespace mbgl {
-Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource)
+Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource, gl::GLObjectStore& glObjectStore)
: name(name_)
- , program(0)
{
util::stopwatch stopwatch("shader compilation", Event::Shader);
- program = MBGL_CHECK_ERROR(glCreateProgram());
-
- if (!compileShader(&vertShader, GL_VERTEX_SHADER, &vertSource)) {
+ program.create(glObjectStore);
+ vertexShader.create(glObjectStore);
+ if (!compileShader(vertexShader, &vertSource)) {
Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertSource);
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile");
}
- if (!compileShader(&fragShader, GL_FRAGMENT_SHADER, &fragSource)) {
+ fragmentShader.create(glObjectStore);
+ if (!compileShader(fragmentShader, &fragSource)) {
Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragSource);
- MBGL_CHECK_ERROR(glDeleteShader(vertShader));
- vertShader = 0;
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile");
}
// Attach shaders
- MBGL_CHECK_ERROR(glAttachShader(program, vertShader));
- MBGL_CHECK_ERROR(glAttachShader(program, fragShader));
+ MBGL_CHECK_ERROR(glAttachShader(program.getID(), vertexShader.getID()));
+ MBGL_CHECK_ERROR(glAttachShader(program.getID(), fragmentShader.getID()));
{
// Link program
GLint status;
- MBGL_CHECK_ERROR(glLinkProgram(program));
+ MBGL_CHECK_ERROR(glLinkProgram(program.getID()));
- MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_LINK_STATUS, &status));
if (status == 0) {
GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_INFO_LOG_LENGTH, &logLength));
const auto log = std::make_unique<GLchar[]>(logLength);
if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(program, logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program.getID(), logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
}
-
- MBGL_CHECK_ERROR(glDeleteShader(vertShader));
- vertShader = 0;
- MBGL_CHECK_ERROR(glDeleteShader(fragShader));
- fragShader = 0;
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
}
}
- a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos"));
+ a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.getID(), "a_pos"));
}
+bool Shader::compileShader(gl::ShaderHolder& shader, const GLchar *source[]) {
+ GLint status = 0;
-bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source[]) {
- GLint status;
-
- *shader = MBGL_CHECK_ERROR(glCreateShader(type));
const GLsizei lengths = static_cast<GLsizei>(std::strlen(*source));
- MBGL_CHECK_ERROR(glShaderSource(*shader, 1, source, &lengths));
+ MBGL_CHECK_ERROR(glShaderSource(shader.getID(), 1, source, &lengths));
- MBGL_CHECK_ERROR(glCompileShader(*shader));
+ MBGL_CHECK_ERROR(glCompileShader(shader.getID()));
- MBGL_CHECK_ERROR(glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_COMPILE_STATUS, &status));
if (status == 0) {
GLint logLength;
- MBGL_CHECK_ERROR(glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_INFO_LOG_LENGTH, &logLength));
if (logLength > 0) {
const auto log = std::make_unique<GLchar[]>(logLength);
- MBGL_CHECK_ERROR(glGetShaderInfoLog(*shader, logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetShaderInfoLog(shader.getID(), logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Shader failed to compile: %s", log.get());
}
-
- MBGL_CHECK_ERROR(glDeleteShader(*shader));
- *shader = 0;
return false;
}
- MBGL_CHECK_ERROR(glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_COMPILE_STATUS, &status));
if (status == GL_FALSE) {
Log::Error(Event::Shader, "Shader %s failed to compile.", name);
- MBGL_CHECK_ERROR(glDeleteShader(*shader));
- *shader = 0;
return false;
}
@@ -107,13 +87,9 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source[])
Shader::~Shader() {
if (program) {
- MBGL_CHECK_ERROR(glDetachShader(program, vertShader));
- MBGL_CHECK_ERROR(glDetachShader(program, fragShader));
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
- MBGL_CHECK_ERROR(glDeleteShader(vertShader));
- vertShader = 0;
- MBGL_CHECK_ERROR(glDeleteShader(fragShader));
- fragShader = 0;
+ MBGL_CHECK_ERROR(glDetachShader(program.getID(), vertexShader.getID()));
+ MBGL_CHECK_ERROR(glDetachShader(program.getID(), fragmentShader.getID()));
}
}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
index 927fdf0b0b..b543f73a6f 100644
--- a/src/mbgl/shader/shader.hpp
+++ b/src/mbgl/shader/shader.hpp
@@ -1,25 +1,21 @@
#ifndef MBGL_RENDERER_SHADER
#define MBGL_RENDERER_SHADER
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <cstdint>
-#include <array>
-#include <string>
-
namespace mbgl {
class Shader : private util::noncopyable {
public:
- Shader(const GLchar *name, const GLchar *vertex, const GLchar *fragment);
+ Shader(const GLchar *name, const GLchar *vertex, const GLchar *fragment, gl::GLObjectStore&);
~Shader();
const GLchar *name;
- GLuint program;
- inline GLuint getID() const {
- return program;
+ GLuint getID() const {
+ return program.getID();
}
virtual void bind(GLbyte *offset) = 0;
@@ -28,10 +24,11 @@ protected:
GLint a_pos = -1;
private:
- bool compileShader(GLuint *shader, GLenum type, const GLchar *source[]);
+ bool compileShader(gl::ShaderHolder&, const GLchar *source[]);
- GLuint vertShader = 0;
- GLuint fragShader = 0;
+ gl::ProgramHolder program;
+ gl::ShaderHolder vertexShader = { GL_VERTEX_SHADER };
+ gl::ShaderHolder fragmentShader = { GL_FRAGMENT_SHADER };
};
} // namespace mbgl
diff --git a/src/mbgl/shader/uniform.hpp b/src/mbgl/shader/uniform.hpp
index 0b6d574d09..5c4a2b14c4 100644
--- a/src/mbgl/shader/uniform.hpp
+++ b/src/mbgl/shader/uniform.hpp
@@ -2,7 +2,9 @@
#define MBGL_SHADER_UNIFORM
#include <mbgl/shader/shader.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+
+#include <array>
namespace mbgl {
@@ -10,7 +12,7 @@ template <typename T>
class Uniform {
public:
Uniform(const GLchar* name, const Shader& shader) : current() {
- location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.program, name));
+ location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.getID(), name));
}
void operator=(const T& t) {
@@ -33,7 +35,7 @@ public:
typedef std::array<float, C*R> T;
UniformMatrix(const GLchar* name, const Shader& shader) : current() {
- location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.program, name));
+ location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.getID(), name));
}
void operator=(const std::array<double, C*R>& t) {
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/source/source.cpp
index 7f9b47440b..8947e4f988 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/source/source.cpp
@@ -1,8 +1,8 @@
-#include <mbgl/map/source.hpp>
+#include <mbgl/source/source.hpp>
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/transform.hpp>
-#include <mbgl/map/tile.hpp>
-#include <mbgl/map/vector_tile.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/annotation/annotation_tile.hpp>
#include <mbgl/tile/geojson_tile.hpp>
#include <mbgl/renderer/painter.hpp>
@@ -11,8 +11,6 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/math.hpp>
-#include <mbgl/util/box.hpp>
-#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_update_parameters.hpp>
@@ -22,8 +20,8 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/tile_cover.hpp>
-#include <mbgl/map/vector_tile_data.hpp>
-#include <mbgl/map/raster_tile_data.hpp>
+#include <mbgl/tile/vector_tile_data.hpp>
+#include <mbgl/tile/raster_tile_data.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/gl/debugging.hpp>
@@ -70,10 +68,7 @@ bool Source::isLoading() const {
return !loaded && req.operator bool();
}
-// Note: This is a separate function that must be called exactly once after creation
-// The reason this isn't part of the constructor is that calling shared_from_this() in
-// the constructor fails.
-void Source::load() {
+void Source::load(FileSource& fileSource) {
if (url.empty()) {
// In case there is no URL set, we assume that we already have all of the data because the
// TileJSON was specified inline in the stylesheet.
@@ -88,80 +83,77 @@ void Source::load() {
}
// URL may either be a TileJSON file, or a GeoJSON file.
- FileSource* fs = util::ThreadContext::getFileSource();
- req = fs->request(Resource::source(url), [this](Response res) {
+ req = fileSource.request(Resource::source(url), [this](Response res) {
if (res.error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
return;
- }
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty source")));
+ } else {
+ bool reloadTiles = false;
+
+ if (type == SourceType::Vector || type == SourceType::Raster) {
+ std::unique_ptr<SourceInfo> newInfo;
+
+ // Create a new copy of the SourceInfo object that holds the base values we've parsed
+ // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
+ // via the URL.
+ try {
+ newInfo = StyleParser::parseTileJSON(*res.data, url, type, tileSize);
+ } catch (...) {
+ observer->onSourceError(*this, std::current_exception());
+ return;
+ }
- if (res.notModified) {
- // We got the same data back as last time. Abort early.
- return;
- }
+ // Check whether previous information specifies different tile
+ if (info && info->tiles != newInfo->tiles) {
+ reloadTiles = true;
- bool reloadTiles = false;
+ // Tile size changed: We need to recalculate the tiles we need to load because we
+ // might have to load tiles for a different zoom level
+ // This is done automatically when we trigger the onSourceLoaded observer below.
- if (type == SourceType::Vector || type == SourceType::Raster) {
- std::unique_ptr<SourceInfo> newInfo;
+ // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles
+ // loaded that are outside the new zoom range
+ // This is done automatically when we trigger the onSourceLoaded observer below.
- // Create a new copy of the SourceInfo object that holds the base values we've parsed
- // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
- // via the URL.
- try {
- newInfo = StyleParser::parseTileJSON(*res.data, url, type);
- } catch (...) {
- observer->onSourceError(*this, std::current_exception());
- return;
- }
+ // Attribution changed: We need to notify the embedding application that this
+ // changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723
+ // This is not yet implemented.
- // Check whether previous information specifies different tile
- if (info && info->tiles != newInfo->tiles) {
- reloadTiles = true;
+ // Center/bounds changed: We're not using these values currently
+ }
- // Tile size changed: We need to recalculate the tiles we need to load because we
- // might have to load tiles for a different zoom level
- // This is done automatically when we trigger the onSourceLoaded observer below.
+ info = std::move(newInfo);
+ } else if (type == SourceType::GeoJSON) {
+ info = std::make_unique<SourceInfo>();
- // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles
- // loaded that are outside the new zoom range
- // This is done automatically when we trigger the onSourceLoaded observer below.
+ rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> d;
+ d.Parse<0>(res.data->c_str());
- // Attribution changed: We need to notify the embedding application that this
- // changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723
- // This is not yet implemented.
+ if (d.HasParseError()) {
+ std::stringstream message;
+ message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError());
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str())));
+ return;
+ }
- // Center/bounds changed: We're not using these values currently
+ geojsonvt = StyleParser::parseGeoJSON(d);
+ reloadTiles = true;
}
- info = std::move(newInfo);
- } else if (type == SourceType::GeoJSON) {
- info = std::make_unique<SourceInfo>();
-
- rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> d;
- d.Parse<0>(res.data->c_str());
-
- if (d.HasParseError()) {
- std::stringstream message;
- message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError());
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str())));
- return;
+ if (reloadTiles) {
+ // Tile information changed because we got new GeoJSON data, or a new tile URL.
+ tilePtrs.clear();
+ tileDataMap.clear();
+ tiles.clear();
+ cache.clear();
}
- geojsonvt = StyleParser::parseGeoJSON(d);
- reloadTiles = true;
- }
-
- if (reloadTiles) {
- // Tile information changed because we got new GeoJSON data, or a new tile URL.
- tilePtrs.clear();
- tileDataMap.clear();
- tiles.clear();
- cache.clear();
+ loaded = true;
+ observer->onSourceLoaded(*this);
}
-
- loaded = true;
- observer->onSourceLoaded(*this);
});
}
@@ -173,14 +165,6 @@ void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transf
}
}
-void Source::drawClippingMasks(Painter &painter) {
- for (const auto& pair : tiles) {
- Tile &tile = *pair.second;
- MBGL_DEBUG_GROUP(std::string { "mask: " } + std::string(tile.id));
- painter.drawClippingMask(tile.matrix, tile.clip);
- }
-}
-
void Source::finishRender(Painter &painter) {
for (const auto& pair : tiles) {
Tile &tile = *pair.second;
@@ -271,12 +255,13 @@ TileData::State Source::addTile(const TileID& tileID, const StyleUpdateParameter
info->tiles.at(0),
parameters.texturePool,
parameters.worker,
+ parameters.fileSource,
callback);
} else {
std::unique_ptr<GeometryTileMonitor> monitor;
if (type == SourceType::Vector) {
- monitor = std::make_unique<VectorTileMonitor>(normalizedID, parameters.pixelRatio, info->tiles.at(0));
+ monitor = std::make_unique<VectorTileMonitor>(normalizedID, parameters.pixelRatio, info->tiles.at(0), parameters.fileSource);
} else if (type == SourceType::Annotations) {
monitor = std::make_unique<AnnotationTileMonitor>(normalizedID, parameters.data);
} else if (type == SourceType::GeoJSON) {
@@ -302,47 +287,6 @@ TileData::State Source::addTile(const TileID& tileID, const StyleUpdateParameter
return newState;
}
-double Source::getZoom(const TransformState& state) const {
- double offset = std::log(util::tileSize / tileSize) / std::log(2);
- return state.getZoom() + offset;
-}
-
-int32_t Source::coveringZoomLevel(const TransformState& state) const {
- double zoom = getZoom(state);
- if (type == SourceType::Raster || type == SourceType::Video) {
- zoom = ::round(zoom);
- } else {
- zoom = std::floor(zoom);
- }
- return util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
-}
-
-std::forward_list<TileID> Source::coveringTiles(const TransformState& state) const {
- int32_t z = coveringZoomLevel(state);
-
- auto actualZ = z;
- const bool reparseOverscaled =
- type == SourceType::Vector ||
- type == SourceType::Annotations;
-
- if (z < info->minZoom) return {{}};
- if (z > info->maxZoom) z = info->maxZoom;
-
- // Map four viewport corners to pixel coordinates
- box points = state.cornersToBox(z);
- const TileCoordinate center = state.pointToCoordinate({ state.getWidth() / 2.0f, state.getHeight()/ 2.0f }).zoomTo(z);
-
- std::forward_list<TileID> covering_tiles = tileCover(z, points, reparseOverscaled ? actualZ : z);
-
- covering_tiles.sort([&center](const TileID& a, const TileID& b) {
- // Sorts by distance from the box center
- return std::fabs(a.x - center.column) + std::fabs(a.y - center.row) <
- std::fabs(b.x - center.column) + std::fabs(b.y - center.row);
- });
-
- return covering_tiles;
-}
-
/**
* Recursively find children of the given tile that are already loaded.
*
@@ -352,14 +296,14 @@ std::forward_list<TileID> Source::coveringTiles(const TransformState& state) con
*
* @return boolean Whether the children found completely cover the tile.
*/
-bool Source::findLoadedChildren(const TileID& tileID, int32_t maxCoveringZoom, std::forward_list<TileID>& retain) {
+bool Source::findLoadedChildren(const TileID& tileID, int32_t maxCoveringZoom, std::vector<TileID>& retain) {
bool complete = true;
int32_t z = tileID.z;
auto ids = tileID.children(info->maxZoom);
for (const auto& child_id : ids) {
const TileData::State state = hasTile(child_id);
if (TileData::isReadyState(state)) {
- retain.emplace_front(child_id);
+ retain.emplace_back(child_id);
}
if (state != TileData::State::parsed) {
complete = false;
@@ -381,12 +325,12 @@ bool Source::findLoadedChildren(const TileID& tileID, int32_t maxCoveringZoom, s
*
* @return boolean Whether a parent was found.
*/
-void Source::findLoadedParent(const TileID& tileID, int32_t minCoveringZoom, std::forward_list<TileID>& retain) {
+void Source::findLoadedParent(const TileID& tileID, int32_t minCoveringZoom, std::vector<TileID>& retain) {
for (int32_t z = tileID.z - 1; z >= minCoveringZoom; --z) {
const TileID parent_id = tileID.parent(z, info->maxZoom);
const TileData::State state = hasTile(parent_id);
if (TileData::isReadyState(state)) {
- retain.emplace_front(parent_id);
+ retain.emplace_back(parent_id);
if (state == TileData::State::parsed) {
return;
}
@@ -401,17 +345,29 @@ bool Source::update(const StyleUpdateParameters& parameters) {
return allTilesUpdated;
}
- double zoom = coveringZoomLevel(parameters.transformState);
- std::forward_list<TileID> required = coveringTiles(parameters.transformState);
-
- // Determine the overzooming/underzooming amounts.
+ // Determine the overzooming/underzooming amounts and required tiles.
+ std::vector<TileID> required;
+ int32_t zoom = coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize);
int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info->minZoom, info->maxZoom);
int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info->minZoom, info->maxZoom);
+ if (zoom >= info->minZoom) {
+ const bool reparseOverscaled =
+ type == SourceType::Vector ||
+ type == SourceType::Annotations;
+
+ const auto actualZ = zoom;
+ if (zoom > info->maxZoom) {
+ zoom = info->maxZoom;
+ }
+
+ required = tileCover(parameters.transformState, zoom, reparseOverscaled ? actualZ : zoom);
+ }
+
// Retain is a list of tiles that we shouldn't delete, even if they are not
// the most ideal tile for the current viewport. This may include tiles like
// parent or child tiles that are *already* loaded.
- std::forward_list<TileID> retain(required);
+ std::vector<TileID> retain(required);
// Add existing child/parent tiles if the actual tile is not yet loaded
for (const auto& tileID : required) {
diff --git a/src/mbgl/map/source.hpp b/src/mbgl/source/source.hpp
index d9146c1fdb..52c7d76baf 100644
--- a/src/mbgl/map/source.hpp
+++ b/src/mbgl/source/source.hpp
@@ -1,13 +1,15 @@
#ifndef MBGL_MAP_SOURCE
#define MBGL_MAP_SOURCE
-#include <mbgl/map/tile_cache.hpp>
-#include <mbgl/map/source_info.hpp>
+#include <mbgl/tile/tile_data.hpp>
+#include <mbgl/tile/tile_cache.hpp>
+#include <mbgl/source/source_info.hpp>
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <forward_list>
+#include <vector>
#include <map>
namespace mapbox {
@@ -20,6 +22,7 @@ namespace mbgl {
class StyleUpdateParameters;
class Painter;
+class FileSource;
class FileRequest;
class TransformState;
class Tile;
@@ -49,10 +52,12 @@ public:
~Source();
bool loaded = false;
- void load();
+ void load(FileSource&);
bool isLoading() const;
bool isLoaded() const;
+ const SourceInfo* getInfo() const { return info.get(); }
+
// Request or parse all the tiles relevant for the "TransformState". This method
// will return true if all the tiles were scheduled for updating of false if
// they were not. shouldReparsePartialTiles must be set to "true" if there is
@@ -60,7 +65,6 @@ public:
bool update(const StyleUpdateParameters&);
void updateMatrices(const mat4 &projMatrix, const TransformState &transform);
- void drawClippingMasks(Painter &painter);
void finishRender(Painter &painter);
std::forward_list<Tile *> getLoadedTiles() const;
@@ -83,17 +87,13 @@ private:
std::exception_ptr,
bool isNewTile);
bool handlePartialTile(const TileID&);
- bool findLoadedChildren(const TileID&, int32_t maxCoveringZoom, std::forward_list<TileID>& retain);
- void findLoadedParent(const TileID&, int32_t minCoveringZoom, std::forward_list<TileID>& retain);
- int32_t coveringZoomLevel(const TransformState&) const;
- std::forward_list<TileID> coveringTiles(const TransformState&) const;
+ bool findLoadedChildren(const TileID&, int32_t maxCoveringZoom, std::vector<TileID>& retain);
+ void findLoadedParent(const TileID&, int32_t minCoveringZoom, std::vector<TileID>& retain);
TileData::State addTile(const TileID&, const StyleUpdateParameters&);
TileData::State hasTile(const TileID&);
void updateTilePtrs();
- double getZoom(const TransformState &state) const;
-
private:
std::unique_ptr<const SourceInfo> info;
diff --git a/src/mbgl/map/source_info.hpp b/src/mbgl/source/source_info.hpp
index 2fb5c2466d..2fb5c2466d 100644
--- a/src/mbgl/map/source_info.hpp
+++ b/src/mbgl/source/source_info.hpp
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index be5c59c74c..12d12a53cb 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -1,9 +1,8 @@
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_store.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
@@ -144,9 +143,9 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
dirty = true;
}
-void SpriteAtlas::upload() {
+void SpriteAtlas::upload(gl::GLObjectStore& glObjectStore) {
if (dirty) {
- bind();
+ bind(false, glObjectStore);
}
}
@@ -181,14 +180,14 @@ void SpriteAtlas::updateDirty() {
}
}
-void SpriteAtlas::bind(bool linear) {
+void SpriteAtlas::bind(bool linear, gl::GLObjectStore& glObjectStore) {
if (!data) {
return; // Empty atlas
}
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create(glObjectStore);
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -198,7 +197,7 @@ void SpriteAtlas::bind(bool linear) {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
fullUploadRequired = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST;
@@ -247,13 +246,7 @@ void SpriteAtlas::bind(bool linear) {
}
};
-SpriteAtlas::~SpriteAtlas() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
- if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
- }
-}
+SpriteAtlas::~SpriteAtlas() = default;
SpriteAtlas::Holder::Holder(const std::shared_ptr<const SpriteImage>& spriteImage_,
const Rect<dimension>& pos_)
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index 73b3037ec6..ba592c5acb 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -2,7 +2,8 @@
#define MBGL_SPRITE_ATLAS
#include <mbgl/geometry/binpack.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/optional.hpp>
@@ -51,14 +52,14 @@ public:
optional<SpriteAtlasPosition> getPosition(const std::string& name, bool repeating = false);
// Binds the atlas texture to the GPU, and uploads data if it is out of date.
- void bind(bool linear = false);
+ void bind(bool linear, gl::GLObjectStore&);
// Updates sprites in the atlas texture that may have changed in the source SpriteStore object.
void updateDirty();
// Uploads the texture to the GPU to be available when we need it. This is a lazy operation;
// the texture is only bound when the data is out of date (=dirty).
- void upload();
+ void upload(gl::GLObjectStore&);
inline dimension getWidth() const { return width; }
inline dimension getHeight() const { return height; }
@@ -94,7 +95,7 @@ private:
std::unique_ptr<uint32_t[]> data;
std::atomic<bool> dirty;
bool fullUploadRequired = true;
- GLuint texture = 0;
+ gl::TextureHolder texture;
uint32_t filter = 0;
static const int buffer = 1;
};
diff --git a/src/mbgl/sprite/sprite_store.cpp b/src/mbgl/sprite/sprite_store.cpp
index 15a345cc4d..869abab39f 100644
--- a/src/mbgl/sprite/sprite_store.cpp
+++ b/src/mbgl/sprite/sprite_store.cpp
@@ -5,7 +5,6 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/util/exception.hpp>
-#include <mbgl/util/thread_context.hpp>
#include <cassert>
#include <string>
@@ -25,7 +24,7 @@ SpriteStore::SpriteStore(float pixelRatio_)
SpriteStore::~SpriteStore() = default;
-void SpriteStore::setURL(const std::string& url) {
+void SpriteStore::load(const std::string& url, FileSource& fileSource) {
if (url.empty()) {
// Treat a non-existent sprite as a successfully loaded empty sprite.
loaded = true;
@@ -34,37 +33,30 @@ void SpriteStore::setURL(const std::string& url) {
loader = std::make_unique<Loader>();
- FileSource* fs = util::ThreadContext::getFileSource();
- loader->jsonRequest = fs->request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
+ loader->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
if (res.error) {
observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
return;
- }
-
- if (res.notModified) {
- // We got the same data back as last time. Abort early.
- return;
- }
-
- if (!loader->json || *loader->json != *res.data) {
+ } else if (res.noContent) {
+ loader->json = std::make_shared<const std::string>();
+ emitSpriteLoadedIfComplete();
+ } else {
// Only trigger a sprite loaded event we got new data.
loader->json = res.data;
emitSpriteLoadedIfComplete();
}
});
- loader->spriteRequest = fs->request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
+ loader->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
if (res.error) {
observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
return;
- }
-
- if (res.notModified) {
- // We got the same data back as last time. Abort early.
- return;
- }
-
- if (!loader->image || *loader->image != *res.data) {
+ } else if (res.noContent) {
+ loader->image = std::make_shared<const std::string>();
+ emitSpriteLoadedIfComplete();
+ } else {
loader->image = res.data;
emitSpriteLoadedIfComplete();
}
diff --git a/src/mbgl/sprite/sprite_store.hpp b/src/mbgl/sprite/sprite_store.hpp
index 7c5fe71802..995cb81900 100644
--- a/src/mbgl/sprite/sprite_store.hpp
+++ b/src/mbgl/sprite/sprite_store.hpp
@@ -10,6 +10,8 @@
namespace mbgl {
+class FileSource;
+
class SpriteStore : private util::noncopyable {
public:
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
@@ -25,7 +27,7 @@ public:
SpriteStore(float pixelRatio);
~SpriteStore();
- void setURL(const std::string&);
+ void load(const std::string& url, FileSource&);
bool isLoaded() const {
return loaded;
diff --git a/src/mbgl/storage/http_context_base.hpp b/src/mbgl/storage/http_context_base.hpp
index b50bf11ec7..6615ea00cf 100644
--- a/src/mbgl/storage/http_context_base.hpp
+++ b/src/mbgl/storage/http_context_base.hpp
@@ -11,6 +11,7 @@ namespace mbgl {
class HTTPContextBase {
public:
static std::unique_ptr<HTTPContextBase> createContext();
+ static uint32_t maximumConcurrentRequests();
virtual ~HTTPContextBase() = default;
virtual HTTPRequestBase* createRequest(const Resource&, HTTPRequestBase::Callback) = 0;
diff --git a/src/mbgl/storage/resource.cpp b/src/mbgl/storage/resource.cpp
index 6f727a6027..d5b88d9292 100644
--- a/src/mbgl/storage/resource.cpp
+++ b/src/mbgl/storage/resource.cpp
@@ -49,6 +49,7 @@ Resource Resource::glyphs(const std::string& urlTemplate, const std::string& fon
}
Resource Resource::tile(const std::string& urlTemplate, float pixelRatio, int32_t x, int32_t y, int8_t z) {
+ bool supportsRatio = urlTemplate.find("{ratio}") != std::string::npos;
return Resource {
Resource::Kind::Tile,
util::replaceTokens(urlTemplate, [&](const std::string& token) {
@@ -71,7 +72,7 @@ Resource Resource::tile(const std::string& urlTemplate, float pixelRatio, int32_
}),
Resource::TileData {
urlTemplate,
- uint8_t(pixelRatio > 1.0 ? 2 : 1),
+ uint8_t(supportsRatio && pixelRatio > 1.0 ? 2 : 1),
x,
y,
z
diff --git a/src/mbgl/storage/response.cpp b/src/mbgl/storage/response.cpp
index 22263d2ebb..644d73d286 100644
--- a/src/mbgl/storage/response.cpp
+++ b/src/mbgl/storage/response.cpp
@@ -1,6 +1,9 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/util/chrono.hpp>
+#include <iostream>
+#include <cassert>
+
namespace mbgl {
Response::Response(const Response& res) {
@@ -9,6 +12,7 @@ Response::Response(const Response& res) {
Response& Response::operator=(const Response& res) {
error = res.error ? std::make_unique<Error>(*res.error) : nullptr;
+ noContent = res.noContent;
notModified = res.notModified;
data = res.data;
modified = res.modified;
@@ -21,4 +25,23 @@ Response::Error::Error(Reason reason_, const std::string& message_)
: reason(reason_), message(message_) {
}
+std::ostream& operator<<(std::ostream& os, Response::Error::Reason r) {
+ switch (r) {
+ case Response::Error::Reason::Success:
+ return os << "Response::Error::Reason::NotFound";
+ case Response::Error::Reason::NotFound:
+ return os << "Response::Error::Reason::NotFound";
+ case Response::Error::Reason::Server:
+ return os << "Response::Error::Reason::Server";
+ case Response::Error::Reason::Connection:
+ return os << "Response::Error::Reason::Connection";
+ case Response::Error::Reason::Other:
+ return os << "Response::Error::Reason::Other";
+ }
+
+ // The above switch is exhaustive, but placate GCC nonetheless:
+ assert(false);
+ return os;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/storage/sqlite_cache.hpp b/src/mbgl/storage/sqlite_cache.hpp
deleted file mode 100644
index b5a7cbcc07..0000000000
--- a/src/mbgl/storage/sqlite_cache.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef MBGL_STORAGE_DEFAULT_SQLITE_CACHE
-#define MBGL_STORAGE_DEFAULT_SQLITE_CACHE
-
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/chrono.hpp>
-
-#include <functional>
-#include <memory>
-#include <string>
-
-namespace mbgl {
-
-class Resource;
-class Response;
-class WorkRequest;
-
-namespace util {
-template <typename T> class Thread;
-} // namespace util
-
-class SQLiteCache : private util::noncopyable {
-public:
- static std::shared_ptr<SQLiteCache> getShared(const std::string &path = ":memory:");
-
- SQLiteCache(const std::string &path = ":memory:");
- ~SQLiteCache();
-
- void setMaximumCacheSize(uint64_t size);
- void setMaximumCacheEntrySize(uint64_t size);
-
- using Callback = std::function<void(std::unique_ptr<Response>)>;
-
- std::unique_ptr<WorkRequest> get(const Resource&, Callback);
- void put(const Resource&, const Response&);
-
- class Impl;
-
-private:
- const std::unique_ptr<util::Thread<Impl>> thread;
-};
-
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/style/filter_expression.cpp b/src/mbgl/style/filter_expression.cpp
index e8231b82e0..660c978f0d 100644
--- a/src/mbgl/style/filter_expression.cpp
+++ b/src/mbgl/style/filter_expression.cpp
@@ -1,5 +1,5 @@
#include <mbgl/style/filter_expression.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/platform/log.hpp>
namespace mbgl {
diff --git a/src/mbgl/style/function.hpp b/src/mbgl/style/function.hpp
index 4d2e4fcbd7..160f5be390 100644
--- a/src/mbgl/style/function.hpp
+++ b/src/mbgl/style/function.hpp
@@ -27,6 +27,9 @@ public:
T evaluate(const StyleCalculationParameters&) const;
+ float getBase() const { return base; }
+ const std::vector<std::pair<float, T>>& getStops() const { return stops; }
+
private:
float base = 1;
std::vector<std::pair<float, T>> stops;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 1ffd75bf69..e5ba08e57f 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -1,7 +1,7 @@
#include <mbgl/style/style.hpp>
#include <mbgl/map/map_data.hpp>
-#include <mbgl/map/source.hpp>
-#include <mbgl/map/tile.hpp>
+#include <mbgl/source/source.hpp>
+#include <mbgl/tile/tile.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/layer/custom_layer.hpp>
@@ -27,9 +27,10 @@
namespace mbgl {
-Style::Style(MapData& data_)
+Style::Style(MapData& data_, FileSource& fileSource_)
: data(data_),
- glyphStore(std::make_unique<GlyphStore>()),
+ fileSource(fileSource_),
+ glyphStore(std::make_unique<GlyphStore>(fileSource)),
glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)),
spriteStore(std::make_unique<SpriteStore>(data.pixelRatio)),
spriteAtlas(std::make_unique<SpriteAtlas>(1024, 1024, data.pixelRatio, *spriteStore)),
@@ -55,7 +56,7 @@ void Style::setJSON(const std::string& json, const std::string&) {
}
glyphStore->setURL(parser.glyphURL);
- spriteStore->setURL(parser.spriteURL);
+ spriteStore->load(parser.spriteURL, fileSource);
loaded = true;
}
@@ -116,13 +117,14 @@ void Style::removeLayer(const std::string& id) {
}
void Style::update(const TransformState& transform,
- TexturePool& texturePool) {
+ gl::TexturePool& texturePool) {
bool allTilesUpdated = true;
StyleUpdateParameters parameters(data.pixelRatio,
data.getDebug(),
data.getAnimationTime(),
transform,
workers,
+ fileSource,
texturePool,
shouldReparsePartialTiles,
data.mode,
@@ -180,7 +182,9 @@ void Style::recalculate(float z) {
Source* source = getSource(layer->source);
if (source && layer->needsRendering()) {
source->enabled = true;
- if (!source->loaded && !source->isLoading()) source->load();
+ if (!source->loaded && !source->isLoading()) {
+ source->load(fileSource);
+ }
}
}
}
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 7bd98a7552..82c048b195 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -3,7 +3,7 @@
#include <mbgl/style/zoom_history.hpp>
-#include <mbgl/map/source.hpp>
+#include <mbgl/source/source.hpp>
#include <mbgl/text/glyph_store.hpp>
#include <mbgl/sprite/sprite_store.hpp>
@@ -19,6 +19,7 @@
namespace mbgl {
class MapData;
+class FileSource;
class GlyphAtlas;
class GlyphStore;
class SpriteStore;
@@ -26,11 +27,11 @@ class SpriteAtlas;
class LineAtlas;
class StyleLayer;
class TransformState;
-class TexturePool;
-
class Tile;
class Bucket;
+namespace gl { class TexturePool; }
+
struct RenderItem {
inline RenderItem(const StyleLayer& layer_,
const Tile* tile_ = nullptr,
@@ -54,7 +55,7 @@ class Style : public GlyphStore::Observer,
public Source::Observer,
public util::noncopyable {
public:
- Style(MapData&);
+ Style(MapData&, FileSource&);
~Style();
class Observer : public GlyphStore::Observer,
@@ -79,7 +80,7 @@ public:
// Fetch the tiles needed by the current viewport and emit a signal when
// a tile is ready so observers can render the tile.
- void update(const TransformState&, TexturePool&);
+ void update(const TransformState&, gl::TexturePool&);
void cascade();
void recalculate(float z);
@@ -107,6 +108,7 @@ public:
void dumpDebugLogs() const;
MapData& data;
+ FileSource& fileSource;
std::unique_ptr<GlyphStore> glyphStore;
std::unique_ptr<GlyphAtlas> glyphAtlas;
std::unique_ptr<SpriteStore> spriteStore;
diff --git a/src/mbgl/style/style_bucket_parameters.cpp b/src/mbgl/style/style_bucket_parameters.cpp
index e8303e3d8f..7bde1fd80e 100644
--- a/src/mbgl/style/style_bucket_parameters.cpp
+++ b/src/mbgl/style/style_bucket_parameters.cpp
@@ -1,5 +1,5 @@
#include <mbgl/style/style_bucket_parameters.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
namespace mbgl {
diff --git a/src/mbgl/style/style_bucket_parameters.hpp b/src/mbgl/style/style_bucket_parameters.hpp
index 3329cac032..134850066d 100644
--- a/src/mbgl/style/style_bucket_parameters.hpp
+++ b/src/mbgl/style/style_bucket_parameters.hpp
@@ -3,7 +3,7 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/style/filter_expression.hpp>
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <functional>
diff --git a/src/mbgl/style/style_layer.hpp b/src/mbgl/style/style_layer.hpp
index 764906576f..fa09ee2e82 100644
--- a/src/mbgl/style/style_layer.hpp
+++ b/src/mbgl/style/style_layer.hpp
@@ -23,11 +23,18 @@ public:
virtual ~StyleLayer() = default;
// Check whether this layer is of the given subtype.
- template <class T> bool is() const { return dynamic_cast<const T*>(this); }
+ template <class T>
+ bool is() const;
// Dynamically cast this layer to the given subtype.
- template <class T> T* as() { return dynamic_cast< T*>(this); }
- template <class T> const T* as() const { return dynamic_cast<const T*>(this); }
+ template <class T>
+ T* as() {
+ return is<T>() ? reinterpret_cast<T*>(this) : nullptr;
+ }
+ template <class T>
+ const T* as() const {
+ return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
+ }
// Create a copy of this layer.
virtual std::unique_ptr<StyleLayer> clone() const = 0;
@@ -64,10 +71,22 @@ public:
VisibilityType visibility = VisibilityType::Visible;
protected:
- StyleLayer() = default;
+ enum class Type {
+ Fill,
+ Line,
+ Circle,
+ Symbol,
+ Raster,
+ Background,
+ Custom,
+ };
+
+ StyleLayer(Type type_) : type(type_) {}
StyleLayer(const StyleLayer&) = default;
StyleLayer& operator=(const StyleLayer&) = delete;
+ const Type type;
+
// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 7d53d603e5..7c2a94b206 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -18,6 +18,7 @@
#include <algorithm>
#include <sstream>
+#include <set>
namespace mbgl {
@@ -255,7 +256,7 @@ std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> StyleParser::parseGeoJSON(const JS
}
}
-std::unique_ptr<SourceInfo> StyleParser::parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type) {
+std::unique_ptr<SourceInfo> StyleParser::parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type, uint16_t tileSize) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> document;
document.Parse<0>(json.c_str());
@@ -268,11 +269,10 @@ std::unique_ptr<SourceInfo> StyleParser::parseTileJSON(const std::string& json,
std::unique_ptr<SourceInfo> result = StyleParser::parseTileJSON(document);
// TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with.
- if (type == SourceType::Raster && util::mapbox::isMapboxURL(sourceURL)) {
- std::transform(result->tiles.begin(),
- result->tiles.end(),
- result->tiles.begin(),
- util::mapbox::normalizeRasterTileURL);
+ if (util::mapbox::isMapboxURL(sourceURL)) {
+ for (auto& url : result->tiles) {
+ url = util::mapbox::canonicalizeTileURL(url, type, tileSize);
+ }
}
return result;
@@ -484,4 +484,23 @@ void StyleParser::parseVisibility(StyleLayer& layer, const JSValue& value) {
layer.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
}
+std::vector<std::string> StyleParser::fontStacks() const {
+ std::set<std::string> result;
+
+ for (const auto& layer : layers) {
+ if (layer->is<SymbolLayer>()) {
+ LayoutProperty<std::string> property = layer->as<SymbolLayer>()->layout.text.font;
+ if (property.parsedValue) {
+ for (const auto& stop : property.parsedValue->getStops()) {
+ result.insert(stop.second);
+ }
+ } else {
+ result.insert(property.value);
+ }
+ }
+ }
+
+ return std::vector<std::string>(result.begin(), result.end());
+}
+
} // namespace mbgl
diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp
index 69bd8a3bf9..280cda530b 100644
--- a/src/mbgl/style/style_parser.hpp
+++ b/src/mbgl/style/style_parser.hpp
@@ -2,7 +2,7 @@
#define MBGL_STYLE_STYLE_PARSER
#include <mbgl/style/style_layer.hpp>
-#include <mbgl/map/source.hpp>
+#include <mbgl/source/source.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <vector>
@@ -28,7 +28,10 @@ public:
std::vector<std::unique_ptr<Source>> sources;
std::vector<std::unique_ptr<StyleLayer>> layers;
- static std::unique_ptr<SourceInfo> parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType);
+ // Statically evaluate layer properties to determine what font stacks are used.
+ std::vector<std::string> fontStacks() const;
+
+ static std::unique_ptr<SourceInfo> parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType, uint16_t tileSize);
static std::unique_ptr<SourceInfo> parseTileJSON(const JSValue&);
static std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> parseGeoJSON(const JSValue&);
diff --git a/src/mbgl/style/style_update_parameters.hpp b/src/mbgl/style/style_update_parameters.hpp
index 0a646219f0..9ea7e112eb 100644
--- a/src/mbgl/style/style_update_parameters.hpp
+++ b/src/mbgl/style/style_update_parameters.hpp
@@ -7,9 +7,10 @@ namespace mbgl {
class TransformState;
class Worker;
-class TexturePool;
+class FileSource;
class MapData;
class Style;
+namespace gl { class TexturePool; }
class StyleUpdateParameters {
public:
@@ -18,7 +19,8 @@ public:
TimePoint animationTime_,
const TransformState& transformState_,
Worker& worker_,
- TexturePool& texturePool_,
+ FileSource& fileSource_,
+ gl::TexturePool& texturePool_,
bool shouldReparsePartialTiles_,
const MapMode mode_,
MapData& data_,
@@ -28,6 +30,7 @@ public:
animationTime(animationTime_),
transformState(transformState_),
worker(worker_),
+ fileSource(fileSource_),
texturePool(texturePool_),
shouldReparsePartialTiles(shouldReparsePartialTiles_),
mode(mode_),
@@ -39,7 +42,8 @@ public:
TimePoint animationTime;
const TransformState& transformState;
Worker& worker;
- TexturePool& texturePool;
+ FileSource& fileSource;
+ gl::TexturePool& texturePool;
bool shouldReparsePartialTiles;
const MapMode mode;
diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp
index 1a2142bfb2..7a129d692c 100644
--- a/src/mbgl/text/get_anchors.cpp
+++ b/src/mbgl/text/get_anchors.cpp
@@ -10,14 +10,19 @@ namespace mbgl {
Anchors resample(const std::vector<Coordinate> &line, const float offset, const float spacing,
const float angleWindowSize, const float maxAngle, const float labelLength, const bool continuedLine, const bool placeAtMiddle) {
+ const float halfLabelLength = labelLength / 2.0f;
+ float lineLength = 0;
+ for (auto it = line.begin(), end = line.end() - 1; it != end; it++) {
+ lineLength += util::dist<float>(*(it), *(it + 1));
+ }
+
float distance = 0;
float markedDistance = offset - spacing;
Anchors anchors;
- auto end = line.end() - 1;
int i = 0;
- for (auto it = line.begin(); it != end; it++, i++) {
+ for (auto it = line.begin(), end = line.end() - 1; it != end; it++, i++) {
const Coordinate &a = *(it);
const Coordinate &b = *(it + 1);
@@ -31,7 +36,12 @@ Anchors resample(const std::vector<Coordinate> &line, const float offset, const
x = util::interpolate(float(a.x), float(b.x), t),
y = util::interpolate(float(a.y), float(b.y), t);
- if (x >= 0 && x < util::EXTENT && y >= 0 && y < util::EXTENT) {
+ // Check that the point is within the tile boundaries and that
+ // the label would fit before the beginning and end of the line
+ // if placed at this point.
+ if (x >= 0 && x < util::EXTENT && y >= 0 && y < util::EXTENT &&
+ markedDistance - halfLabelLength >= 0.0f &&
+ markedDistance + halfLabelLength <= lineLength) {
Anchor anchor(::round(x), ::round(y), angle, 0.5f, i);
if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
diff --git a/src/mbgl/text/glyph_pbf.cpp b/src/mbgl/text/glyph_pbf.cpp
index 0dfed6b430..c9466e8652 100644
--- a/src/mbgl/text/glyph_pbf.cpp
+++ b/src/mbgl/text/glyph_pbf.cpp
@@ -8,7 +8,6 @@
#include <mbgl/util/exception.hpp>
#include <mbgl/util/pbf.hpp>
#include <mbgl/util/string.hpp>
-#include <mbgl/util/thread_context.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/url.hpp>
@@ -64,29 +63,29 @@ namespace mbgl {
GlyphPBF::GlyphPBF(GlyphStore* store,
const std::string& fontStack,
const GlyphRange& glyphRange,
- GlyphStore::Observer* observer_)
+ GlyphStore::Observer* observer_,
+ FileSource& fileSource)
: parsed(false),
observer(observer_) {
- FileSource* fs = util::ThreadContext::getFileSource();
- req = fs->request(Resource::glyphs(store->getURL(), fontStack, glyphRange), [this, store, fontStack, glyphRange](Response res) {
+ req = fileSource.request(Resource::glyphs(store->getURL(), fontStack, glyphRange), [this, store, fontStack, glyphRange](Response res) {
if (res.error) {
observer->onGlyphsError(fontStack, glyphRange, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
return;
- }
-
- if (res.notModified) {
- return;
- }
+ } else if (res.noContent) {
+ parsed = true;
+ observer->onGlyphsLoaded(fontStack, glyphRange);
+ } else {
+ try {
+ parseGlyphPBF(**store->getFontStack(fontStack), *res.data);
+ } catch (...) {
+ observer->onGlyphsError(fontStack, glyphRange, std::current_exception());
+ return;
+ }
- try {
- parseGlyphPBF(**store->getFontStack(fontStack), *res.data);
- } catch (...) {
- observer->onGlyphsError(fontStack, glyphRange, std::current_exception());
- return;
+ parsed = true;
+ observer->onGlyphsLoaded(fontStack, glyphRange);
}
-
- parsed = true;
- observer->onGlyphsLoaded(fontStack, glyphRange);
});
}
diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp
index 9e2ee4eacf..016792aae8 100644
--- a/src/mbgl/text/glyph_pbf.hpp
+++ b/src/mbgl/text/glyph_pbf.hpp
@@ -14,13 +14,15 @@ namespace mbgl {
class FontStack;
class FileRequest;
+class FileSource;
class GlyphPBF : private util::noncopyable {
public:
GlyphPBF(GlyphStore* store,
const std::string& fontStack,
const GlyphRange&,
- GlyphStore::Observer*);
+ GlyphStore::Observer*,
+ FileSource&);
~GlyphPBF();
bool isParsed() const {
diff --git a/src/mbgl/text/glyph_store.cpp b/src/mbgl/text/glyph_store.cpp
index a3d1530e3d..1c75f7191e 100644
--- a/src/mbgl/text/glyph_store.cpp
+++ b/src/mbgl/text/glyph_store.cpp
@@ -7,7 +7,10 @@
namespace mbgl {
-GlyphStore::GlyphStore() = default;
+GlyphStore::GlyphStore(FileSource& fileSource_)
+ : fileSource(fileSource_) {
+}
+
GlyphStore::~GlyphStore() = default;
void GlyphStore::requestGlyphRange(const std::string& fontStackName, const GlyphRange& range) {
@@ -22,7 +25,7 @@ void GlyphStore::requestGlyphRange(const std::string& fontStackName, const Glyph
}
rangeSets.emplace(range,
- std::make_unique<GlyphPBF>(this, fontStackName, range, observer));
+ std::make_unique<GlyphPBF>(this, fontStackName, range, observer, fileSource));
}
diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp
index 2236bce38c..6829397851 100644
--- a/src/mbgl/text/glyph_store.hpp
+++ b/src/mbgl/text/glyph_store.hpp
@@ -14,6 +14,7 @@
namespace mbgl {
+class FileSource;
class GlyphPBF;
// The GlyphStore manages the loading and storage of Glyphs
@@ -29,7 +30,7 @@ public:
virtual void onGlyphsError(const std::string& /* fontStack */, const GlyphRange&, std::exception_ptr) {};
};
- GlyphStore();
+ GlyphStore(FileSource&);
~GlyphStore();
util::exclusive<FontStack> getFontStack(const std::string& fontStack);
@@ -54,6 +55,7 @@ public:
private:
void requestGlyphRange(const std::string& fontStackName, const GlyphRange& range);
+ FileSource& fileSource;
std::string glyphURL;
std::unordered_map<std::string, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>> ranges;
diff --git a/src/mbgl/tile/geojson_tile.hpp b/src/mbgl/tile/geojson_tile.hpp
index fd27fa5917..6f3cbc10d1 100644
--- a/src/mbgl/tile/geojson_tile.hpp
+++ b/src/mbgl/tile/geojson_tile.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_ANNOTATION_GEOJSON_VT_TILE
#define MBGL_ANNOTATION_GEOJSON_VT_TILE
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/map/tile_id.hpp>
#include <unordered_map>
diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 82affc689f..fa41481d4d 100644
--- a/src/mbgl/map/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter_expression_private.hpp>
diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 5cb2f96fdc..5cb2f96fdc 100644
--- a/src/mbgl/map/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
diff --git a/src/mbgl/tile/raster_tile_data.cpp b/src/mbgl/tile/raster_tile_data.cpp
new file mode 100644
index 0000000000..3f26bbdfdd
--- /dev/null
+++ b/src/mbgl/tile/raster_tile_data.cpp
@@ -0,0 +1,83 @@
+#include <mbgl/tile/raster_tile_data.hpp>
+#include <mbgl/source/source.hpp>
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/worker.hpp>
+#include <mbgl/util/work_request.hpp>
+
+using namespace mbgl;
+
+RasterTileData::RasterTileData(const TileID& id_,
+ float pixelRatio,
+ const std::string& urlTemplate,
+ gl::TexturePool &texturePool_,
+ Worker& worker_,
+ FileSource& fileSource,
+ const std::function<void(std::exception_ptr)>& callback)
+ : TileData(id_),
+ texturePool(texturePool_),
+ worker(worker_) {
+ state = State::loading;
+
+ const Resource resource = Resource::tile(urlTemplate, pixelRatio, id.x, id.y, id.sourceZ);
+ req = fileSource.request(resource, [callback, this](Response res) {
+ if (res.error) {
+ callback(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ modified = res.modified;
+ expires = res.expires;
+ } else if (res.noContent) {
+ state = State::parsed;
+ modified = res.modified;
+ expires = res.expires;
+ workRequest.reset();
+ bucket.reset();
+ callback(nullptr);
+ } else {
+ modified = res.modified;
+ expires = res.expires;
+
+ // Only overwrite the state when we didn't have a previous tile.
+ if (state == State::loading) {
+ state = State::loaded;
+ }
+
+ workRequest.reset();
+ workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), res.data, [this, callback] (RasterTileParseResult result) {
+ workRequest.reset();
+ if (state != State::loaded) {
+ return;
+ }
+
+ std::exception_ptr error;
+ if (result.is<std::unique_ptr<Bucket>>()) {
+ state = State::parsed;
+ bucket = std::move(result.get<std::unique_ptr<Bucket>>());
+ } else {
+ error = result.get<std::exception_ptr>();
+ state = State::obsolete;
+ bucket.reset();
+ }
+
+ callback(error);
+ });
+ }
+ });
+}
+
+RasterTileData::~RasterTileData() {
+ cancel();
+}
+
+Bucket* RasterTileData::getBucket(StyleLayer const&) {
+ return bucket.get();
+}
+
+void RasterTileData::cancel() {
+ if (state != State::obsolete) {
+ state = State::obsolete;
+ }
+ req = nullptr;
+ workRequest.reset();
+}
diff --git a/src/mbgl/map/raster_tile_data.hpp b/src/mbgl/tile/raster_tile_data.hpp
index e68fbc94c5..59eee88496 100644
--- a/src/mbgl/map/raster_tile_data.hpp
+++ b/src/mbgl/tile/raster_tile_data.hpp
@@ -1,23 +1,25 @@
#ifndef MBGL_MAP_RASTER_TILE_DATA
#define MBGL_MAP_RASTER_TILE_DATA
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
namespace mbgl {
+class FileSource;
class FileRequest;
class StyleLayer;
-class TexturePool;
class WorkRequest;
+namespace gl { class TexturePool; }
class RasterTileData : public TileData {
public:
RasterTileData(const TileID&,
float pixelRatio,
const std::string& urlTemplate,
- TexturePool&,
+ gl::TexturePool&,
Worker&,
+ FileSource&,
const std::function<void(std::exception_ptr)>& callback);
~RasterTileData();
@@ -25,7 +27,7 @@ public:
Bucket* getBucket(StyleLayer const &layer_desc) override;
private:
- TexturePool& texturePool;
+ gl::TexturePool& texturePool;
Worker& worker;
std::unique_ptr<FileRequest> req;
std::unique_ptr<Bucket> bucket;
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
new file mode 100644
index 0000000000..a1d36421a4
--- /dev/null
+++ b/src/mbgl/tile/tile.cpp
@@ -0,0 +1,3 @@
+#include <mbgl/tile/tile.hpp>
+
+using namespace mbgl;
diff --git a/src/mbgl/map/tile.hpp b/src/mbgl/tile/tile.hpp
index 8b9030f1bd..8b9030f1bd 100644
--- a/src/mbgl/map/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
diff --git a/src/mbgl/map/tile_cache.cpp b/src/mbgl/tile/tile_cache.cpp
index 2d1a0da96c..423b355827 100644
--- a/src/mbgl/map/tile_cache.cpp
+++ b/src/mbgl/tile/tile_cache.cpp
@@ -1,4 +1,5 @@
-#include <mbgl/map/tile_cache.hpp>
+#include <mbgl/tile/tile_cache.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <cassert>
diff --git a/src/mbgl/map/tile_cache.hpp b/src/mbgl/tile/tile_cache.hpp
index e39db0ffae..4d0b42242a 100644
--- a/src/mbgl/map/tile_cache.hpp
+++ b/src/mbgl/tile/tile_cache.hpp
@@ -1,13 +1,14 @@
#ifndef MBGL_MAP_TILE_CACHE
#define MBGL_MAP_TILE_CACHE
-#include <mbgl/map/tile_data.hpp>
-
#include <list>
+#include <memory>
#include <unordered_map>
namespace mbgl {
+class TileData;
+
class TileCache {
public:
TileCache(size_t size_ = 0) : size(size_) {}
@@ -18,6 +19,7 @@ public:
std::shared_ptr<TileData> get(uint64_t key);
bool has(uint64_t key);
void clear();
+
private:
std::unordered_map<uint64_t, std::shared_ptr<TileData>> tiles;
std::list<uint64_t> orderedKeys;
diff --git a/src/mbgl/map/tile_data.cpp b/src/mbgl/tile/tile_data.cpp
index edfe4d7ada..46ce64771c 100644
--- a/src/mbgl/map/tile_data.cpp
+++ b/src/mbgl/tile/tile_data.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/util/string.hpp>
diff --git a/src/mbgl/map/tile_data.hpp b/src/mbgl/tile/tile_data.hpp
index 90196f8a42..90196f8a42 100644
--- a/src/mbgl/map/tile_data.hpp
+++ b/src/mbgl/tile/tile_data.hpp
diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp
index edbd392057..917b61fde9 100644
--- a/src/mbgl/map/tile_worker.cpp
+++ b/src/mbgl/tile/tile_worker.cpp
@@ -1,6 +1,6 @@
#include <mbgl/text/collision_tile.hpp>
-#include <mbgl/map/tile_worker.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/tile_worker.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_bucket_parameters.hpp>
#include <mbgl/layer/background_layer.hpp>
diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp
index bcd8e59bf9..08048c134b 100644
--- a/src/mbgl/map/tile_worker.hpp
+++ b/src/mbgl/tile/tile_worker.hpp
@@ -4,7 +4,7 @@
#include <mapbox/variant.hpp>
#include <mbgl/map/mode.hpp>
-#include <mbgl/map/tile_data.hpp>
+#include <mbgl/tile/tile_data.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/text/placement_config.hpp>
diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp
index 17746a26a1..9e35debbff 100644
--- a/src/mbgl/map/vector_tile.cpp
+++ b/src/mbgl/tile/vector_tile.cpp
@@ -1,9 +1,8 @@
-#include <mbgl/map/vector_tile.hpp>
-#include <mbgl/map/source.hpp>
+#include <mbgl/tile/vector_tile.hpp>
+#include <mbgl/source/source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/storage/file_source.hpp>
-#include <mbgl/util/thread_context.hpp>
#include <mbgl/util/url.hpp>
#include <utility>
@@ -182,31 +181,25 @@ util::ptr<const GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i)
return std::make_shared<VectorTileFeature>(features.at(i), *this);
}
-VectorTileMonitor::VectorTileMonitor(const TileID& tileID_, float pixelRatio_, const std::string& urlTemplate_)
+VectorTileMonitor::VectorTileMonitor(const TileID& tileID_, float pixelRatio_, const std::string& urlTemplate_, FileSource& fileSource_)
: tileID(tileID_),
pixelRatio(pixelRatio_),
- urlTemplate(urlTemplate_) {
+ urlTemplate(urlTemplate_),
+ fileSource(fileSource_) {
}
std::unique_ptr<FileRequest> VectorTileMonitor::monitorTile(const GeometryTileMonitor::Callback& callback) {
const Resource resource = Resource::tile(urlTemplate, pixelRatio, tileID.x, tileID.y, tileID.sourceZ);
- return util::ThreadContext::getFileSource()->request(resource, [callback, this](Response res) {
- if (res.notModified) {
- // We got the same data again. Abort early.
- return;
- }
-
+ return fileSource.request(resource, [callback, this](Response res) {
if (res.error) {
- if (res.error->reason == Response::Error::Reason::NotFound) {
- callback(nullptr, nullptr, res.modified, res.expires);
- return;
- } else {
- callback(std::make_exception_ptr(std::runtime_error(res.error->message)), nullptr, res.modified, res.expires);
- return;
- }
+ callback(std::make_exception_ptr(std::runtime_error(res.error->message)), nullptr, res.modified, res.expires);
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ callback(nullptr, nullptr, res.modified, res.expires);
+ } else {
+ callback(nullptr, std::make_unique<VectorTile>(res.data), res.modified, res.expires);
}
-
- callback(nullptr, std::make_unique<VectorTile>(res.data), res.modified, res.expires);
});
}
diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/tile/vector_tile.hpp
index 8550b1c55a..48e501cbd7 100644
--- a/src/mbgl/map/vector_tile.hpp
+++ b/src/mbgl/tile/vector_tile.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_MAP_VECTOR_TILE
#define MBGL_MAP_VECTOR_TILE
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/map/tile_id.hpp>
#include <mbgl/util/pbf.hpp>
@@ -59,10 +59,11 @@ private:
};
class TileID;
+class FileSource;
class VectorTileMonitor : public GeometryTileMonitor {
public:
- VectorTileMonitor(const TileID&, float pixelRatio, const std::string& urlTemplate);
+ VectorTileMonitor(const TileID&, float pixelRatio, const std::string& urlTemplate, FileSource&);
std::unique_ptr<FileRequest> monitorTile(const GeometryTileMonitor::Callback&) override;
@@ -70,6 +71,7 @@ private:
TileID tileID;
float pixelRatio;
std::string urlTemplate;
+ FileSource& fileSource;
};
} // namespace mbgl
diff --git a/src/mbgl/map/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 27172a3e63..d2eecab975 100644
--- a/src/mbgl/map/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -1,5 +1,5 @@
-#include <mbgl/map/vector_tile_data.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/vector_tile_data.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_request.hpp>
diff --git a/src/mbgl/map/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index b61b2a25a0..d0b599c4cf 100644
--- a/src/mbgl/map/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -1,8 +1,8 @@
#ifndef MBGL_MAP_VECTOR_TILE_DATA
#define MBGL_MAP_VECTOR_TILE_DATA
-#include <mbgl/map/tile_data.hpp>
-#include <mbgl/map/tile_worker.hpp>
+#include <mbgl/tile/tile_data.hpp>
+#include <mbgl/tile/tile_worker.hpp>
#include <mbgl/text/placement_config.hpp>
#include <atomic>
diff --git a/src/mbgl/util/box.hpp b/src/mbgl/util/box.hpp
deleted file mode 100644
index 2806fb95fc..0000000000
--- a/src/mbgl/util/box.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef MBGL_UTIL_BOX
-#define MBGL_UTIL_BOX
-
-#include <mbgl/util/tile_coordinate.hpp>
-
-namespace mbgl {
-
-struct box {
- box(TileCoordinate tl_, TileCoordinate tr_, TileCoordinate br_, TileCoordinate bl_) :
- tl(tl_), tr(tr_), br(br_), bl(bl_) {}
- TileCoordinate tl, tr, br, bl;
-};
-
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/util/clip_id.cpp b/src/mbgl/util/clip_id.cpp
index b89315d97b..47a5877bb6 100644
--- a/src/mbgl/util/clip_id.cpp
+++ b/src/mbgl/util/clip_id.cpp
@@ -2,7 +2,8 @@
#include <mbgl/platform/log.hpp>
#include <mbgl/util/math.hpp>
-#include <mbgl/map/tile.hpp>
+#include <mbgl/util/std.hpp>
+#include <mbgl/tile/tile.hpp>
#include <list>
#include <vector>
@@ -10,13 +11,14 @@
#include <cassert>
#include <iostream>
#include <algorithm>
+#include <iterator>
namespace mbgl {
-ClipIDGenerator::Leaf::Leaf(Tile &tile_) : tile(tile_) {}
+ClipIDGenerator::Leaf::Leaf(TileID id_, ClipID& clip_) : id(id_), clip(clip_) {}
void ClipIDGenerator::Leaf::add(const TileID &p) {
- if (p.isChildOf(tile.id)) {
+ if (p.isChildOf(id)) {
// Ensure that no already present child is a parent of the new p.
for (const auto& child : children) {
if (p.isChildOf(child))
@@ -27,27 +29,16 @@ void ClipIDGenerator::Leaf::add(const TileID &p) {
}
bool ClipIDGenerator::Leaf::operator==(const Leaf &other) const {
- return tile.id == other.tile.id && children == other.children;
-}
-
-bool ClipIDGenerator::reuseExisting(Leaf &leaf) {
- for (const auto& pool : pools) {
- auto existing = std::find(pool.begin(), pool.end(), leaf);
- if (existing != pool.end()) {
- leaf.tile.clip = existing->tile.clip;
- return true;
- }
- }
- return false;
+ return id == other.id && children == other.children;
}
void ClipIDGenerator::update(std::forward_list<Tile *> tiles) {
- Pool pool;
-
tiles.sort([](const Tile *a, const Tile *b) {
return a->id < b->id;
});
+ std::size_t size = 0;
+
const auto end = tiles.end();
for (auto it = tiles.begin(); it != end; it++) {
if (!*it) {
@@ -56,37 +47,49 @@ void ClipIDGenerator::update(std::forward_list<Tile *> tiles) {
}
Tile &tile = **it;
- Leaf clip { tile };
+ // Use the actual zoom level for computing the clipping mask.
+ Leaf leaf{ TileID{ tile.id.sourceZ, tile.id.x, tile.id.y, tile.id.sourceZ }, tile.clip };
// Try to add all remaining ids as children. We sorted the tile list
// by z earlier, so all preceding items cannot be children of the current
// tile.
for (auto child_it = std::next(it); child_it != end; child_it++) {
- clip.add((*child_it)->id);
+ // Use the actual zoom level for computing the clipping mask.
+ const auto& childID = (*child_it)->id;
+ leaf.add(TileID { childID.sourceZ, childID.x, childID.y, childID.sourceZ });
}
- clip.children.sort();
+ leaf.children.sort();
// Loop through all existing pools and try to find a matching ClipID.
- if (!reuseExisting(clip)) {
+ auto existing = std::find(pool.begin(), pool.end(), leaf);
+ if (existing != pool.end()) {
+ leaf.clip = existing->clip;
+ } else {
// We haven't found an existing clip ID
- pool.push_back(std::move(clip));
+ leaf.clip = {};
+ size++;
}
+
+ pool.emplace_back(std::move(leaf));
}
- if (!pool.empty()) {
- const uint32_t bit_count = util::ceil_log2(pool.size() + 1);
+ if (size > 0) {
+ const uint32_t bit_count = util::ceil_log2(size + 1);
const std::bitset<8> mask = uint64_t(((1ul << bit_count) - 1) << bit_offset);
// We are starting our count with 1 since we need at least 1 bit set to distinguish between
// areas without any tiles whatsoever and the current area.
uint8_t count = 1;
- for (auto& leaf : pool) {
- leaf.tile.clip.mask = mask;
- leaf.tile.clip.reference = uint32_t(count++) << bit_offset;
+ for (auto& tile : tiles) {
+ tile->clip.mask |= mask;
+
+ // Assign only to clip IDs that have no value yet.
+ if (tile->clip.reference.none()) {
+ tile->clip.reference = uint32_t(count++) << bit_offset;
+ }
}
bit_offset += bit_count;
- pools.push_front(std::move(pool));
}
if (bit_offset > 8) {
@@ -94,4 +97,58 @@ void ClipIDGenerator::update(std::forward_list<Tile *> tiles) {
}
}
+template <typename Container>
+bool coveredByChildren(const TileID& id, const Container& container) {
+ for (const auto& child : id.children()) {
+ const auto lower = container.lower_bound(child);
+ if (lower == container.end() ||
+ (lower->first != child && !coveredByChildren(child, container))) {
+ return false;
+ }
+ }
+
+ // We looked at all four immediate children and verified that they're covered.
+ return true;
+}
+
+std::map<TileID, ClipID> ClipIDGenerator::getStencils() const {
+ std::map<TileID, ClipID> stencils;
+
+ // Merge everything.
+ for (auto& leaf : pool) {
+ auto res = stencils.emplace(leaf.id, leaf.clip);
+ if (!res.second) {
+ // Merge with the existing ClipID when there was already an element with the
+ // same tile ID.
+ res.first->second |= leaf.clip;
+ }
+ }
+
+ for (auto it = stencils.begin(); it != stencils.end(); ++it) {
+ auto& childId = it->first;
+ auto& childClip = it->second;
+
+ // Loop through all preceding stencils, and find all parents.
+
+ for (auto parentIt = std::reverse_iterator<std::map<TileID, ClipID>::iterator>(it);
+ parentIt != stencils.rend(); ++parentIt) {
+ auto& parentId = parentIt->first;
+ if (childId.isChildOf(parentId)) {
+ // Once we have a parent, we add the bits that this ID hasn't set yet.
+ const auto& parentClip = parentIt->second;
+ const auto mask = ~(childClip.mask & parentClip.mask);
+ childClip.reference |= mask & parentClip.reference;
+ childClip.mask |= parentClip.mask;
+ }
+ }
+ }
+
+ // Remove tiles that are entirely covered by children.
+ util::erase_if(stencils, [&] (const auto& stencil) {
+ return coveredByChildren(stencil.first, stencils);
+ });
+
+ return stencils;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/util/clip_id.hpp b/src/mbgl/util/clip_id.hpp
index 71a07708c9..2c128d2643 100644
--- a/src/mbgl/util/clip_id.hpp
+++ b/src/mbgl/util/clip_id.hpp
@@ -14,7 +14,6 @@
namespace mbgl {
class Tile;
-class TileID;
struct ClipID {
inline ClipID() {}
@@ -26,28 +25,33 @@ struct ClipID {
inline bool operator==(const ClipID &other) const {
return mask == other.mask && reference == other.reference;
}
+
+ inline ClipID& operator|=(const ClipID &other) {
+ mask |= other.mask;
+ reference |= other.reference;
+ return *this;
+ }
};
class ClipIDGenerator {
private:
struct Leaf {
- Leaf(Tile &tile);
+ Leaf(TileID, ClipID&);
void add(const TileID &p);
bool operator==(const Leaf &other) const;
- Tile &tile;
+ const TileID id;
std::forward_list<TileID> children;
+ ClipID& clip;
};
- typedef std::vector<Leaf> Pool;
- std::forward_list<Pool> pools;
uint8_t bit_offset = 0;
-
-private:
- bool reuseExisting(Leaf &leaf);
+ std::vector<Leaf> pool;
public:
void update(std::forward_list<Tile *> tiles);
+
+ std::map<TileID, ClipID> getStencils() const;
};
diff --git a/src/mbgl/util/clip_lines.cpp b/src/mbgl/util/clip_lines.cpp
index 3a909d674a..071e9d09bd 100644
--- a/src/mbgl/util/clip_lines.cpp
+++ b/src/mbgl/util/clip_lines.cpp
@@ -21,33 +21,33 @@ std::vector<std::vector<Coordinate>> clipLines(const std::vector<std::vector<Coo
if (p0.x < x1 && p1.x < x1) {
continue;
} else if (p0.x < x1) {
- p0 = { x1, static_cast<int16_t>(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x))) };
+ p0 = { x1, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x)))) };
} else if (p1.x < x1) {
- p1 = { x1, static_cast<int16_t>(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x))) };
+ p1 = { x1, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x1 - p0.x) / (p1.x - p0.x)))) };
}
if (p0.y < y1 && p1.y < y1) {
continue;
} else if (p0.y < y1) {
- p0 = { static_cast<int16_t>(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y))), y1 };
+ p0 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y)))), y1 };
} else if (p1.y < y1) {
- p1 = { static_cast<int16_t>(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y))), y1 };
+ p1 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y1 - p0.y) / (p1.y - p0.y)))), y1 };
}
if (p0.x >= x2 && p1.x >= x2) {
continue;
} else if (p0.x >= x2) {
- p0 = { x2, static_cast<int16_t>(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x))) };
+ p0 = { x2, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x)))) };
} else if (p1.x >= x2) {
- p1 = { x2, static_cast<int16_t>(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x))) };
+ p1 = { x2, static_cast<int16_t>(::round(p0.y + (p1.y - p0.y) * ((float)(x2 - p0.x) / (p1.x - p0.x)))) };
}
if (p0.y >= y2 && p1.y >= y2) {
continue;
} else if (p0.y >= y2) {
- p0 = { static_cast<int16_t>(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y))), y2 };
+ p0 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y)))), y2 };
} else if (p1.y >= y2) {
- p1 = { static_cast<int16_t>(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y))), y2 };
+ p1 = { static_cast<int16_t>(::round(p0.x + (p1.x - p0.x) * ((float)(y2 - p0.y) / (p1.y - p0.y)))), y2 };
}
if (clippedLines.empty() || (!clippedLines.back().empty() && !(p0 == clippedLines.back().back()))) {
diff --git a/src/mbgl/util/constants.cpp b/src/mbgl/util/constants.cpp
index 0452dd19e5..90a4d28c2f 100644
--- a/src/mbgl/util/constants.cpp
+++ b/src/mbgl/util/constants.cpp
@@ -1,6 +1,12 @@
#include <mbgl/util/constants.hpp>
-const float mbgl::util::tileSize = 512.0f;
+#include <limits>
+
+namespace mbgl {
+
+namespace util {
+
+const float tileSize = 512.0f;
/*
* The maximum extent of a feature that can be safely stored in the buffer.
@@ -12,37 +18,47 @@ const float mbgl::util::tileSize = 512.0f;
* One bit is lost to support features extending past the extent on the right edge of the tile.
* This leaves us with 2^13 = 8192
*/
-const int32_t mbgl::util::EXTENT = 8192;
+const int32_t EXTENT = 8192;
+
+const double DEG2RAD = M_PI / 180.0;
+const double RAD2DEG = 180.0 / M_PI;
+const double M2PI = 2 * M_PI;
+const double EARTH_RADIUS_M = 6378137;
+const double LATITUDE_MAX = 85.05112878;
+const double PITCH_MAX = M_PI / 3;
+const double MIN_ZOOM = 0.0;
+const double MAX_ZOOM = 25.5;
-const double mbgl::util::DEG2RAD = M_PI / 180.0;
-const double mbgl::util::RAD2DEG = 180.0 / M_PI;
-const double mbgl::util::M2PI = 2 * M_PI;
-const double mbgl::util::EARTH_RADIUS_M = 6378137;
-const double mbgl::util::LATITUDE_MAX = 85.05112878;
-const double mbgl::util::PITCH_MAX = M_PI / 3;
-const double mbgl::util::MIN_ZOOM = 0.0;
-const double mbgl::util::MAX_ZOOM = 25.5;
+const uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
+
+} // namespace util
+
+namespace debug {
#if defined(DEBUG)
-const bool mbgl::debug::tileParseWarnings = false;
-const bool mbgl::debug::styleParseWarnings = false;
-const bool mbgl::debug::spriteWarnings = false;
-const bool mbgl::debug::renderWarnings = false;
-const bool mbgl::debug::renderTree = false;
-const bool mbgl::debug::labelTextMissingWarning = true;
-const bool mbgl::debug::missingFontStackWarning = true;
-const bool mbgl::debug::missingFontFaceWarning = true;
-const bool mbgl::debug::glyphWarning = true;
-const bool mbgl::debug::shapingWarning = true;
+const bool tileParseWarnings = false;
+const bool styleParseWarnings = false;
+const bool spriteWarnings = false;
+const bool renderWarnings = false;
+const bool renderTree = false;
+const bool labelTextMissingWarning = true;
+const bool missingFontStackWarning = true;
+const bool missingFontFaceWarning = true;
+const bool glyphWarning = true;
+const bool shapingWarning = true;
#else
-const bool mbgl::debug::tileParseWarnings = false;
-const bool mbgl::debug::styleParseWarnings = false;
-const bool mbgl::debug::spriteWarnings = false;
-const bool mbgl::debug::renderWarnings = false;
-const bool mbgl::debug::renderTree = false;
-const bool mbgl::debug::labelTextMissingWarning = false;
-const bool mbgl::debug::missingFontStackWarning = false;
-const bool mbgl::debug::missingFontFaceWarning = false;
-const bool mbgl::debug::glyphWarning = false;
-const bool mbgl::debug::shapingWarning = false;
+const bool tileParseWarnings = false;
+const bool styleParseWarnings = false;
+const bool spriteWarnings = false;
+const bool renderWarnings = false;
+const bool renderTree = false;
+const bool labelTextMissingWarning = false;
+const bool missingFontStackWarning = false;
+const bool missingFontFaceWarning = false;
+const bool glyphWarning = false;
+const bool shapingWarning = false;
#endif
+
+} // namespace debug
+
+} // namespace mbgl
diff --git a/src/mbgl/util/get_geometries.cpp b/src/mbgl/util/get_geometries.cpp
index 4d4d02c5ff..5961af2150 100644
--- a/src/mbgl/util/get_geometries.cpp
+++ b/src/mbgl/util/get_geometries.cpp
@@ -1,6 +1,8 @@
#include <mbgl/util/get_geometries.hpp>
#include <mbgl/util/constants.hpp>
+#include <cmath>
+
namespace mbgl {
GeometryCollection getGeometries(const GeometryTileFeature& feature) {
@@ -8,8 +10,8 @@ GeometryCollection getGeometries(const GeometryTileFeature& feature) {
GeometryCollection geometryCollection = feature.getGeometries();
for (auto& line : geometryCollection) {
for (auto& point : line) {
- point.x = std::round(point.x * scale);
- point.y = std::round(point.y * scale);
+ point.x = ::round(point.x * scale);
+ point.y = ::round(point.y * scale);
}
}
return geometryCollection;
diff --git a/src/mbgl/util/get_geometries.hpp b/src/mbgl/util/get_geometries.hpp
index 32dd389507..013a7e5b9f 100644
--- a/src/mbgl/util/get_geometries.hpp
+++ b/src/mbgl/util/get_geometries.hpp
@@ -1,7 +1,7 @@
#ifndef MBGL_UTIL_GET_GEOMETRIES
#define MBGL_UTIL_GET_GEOMETRIES
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
namespace mbgl {
diff --git a/src/mbgl/util/gl_object_store.cpp b/src/mbgl/util/gl_object_store.cpp
deleted file mode 100644
index 78d6700237..0000000000
--- a/src/mbgl/util/gl_object_store.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <mbgl/util/gl_object_store.hpp>
-
-#include <mbgl/util/thread.hpp>
-#include <mbgl/geometry/vao.hpp>
-#include <mbgl/platform/gl.hpp>
-
-#include <cassert>
-
-namespace mbgl {
-namespace util {
-
-void GLObjectStore::abandonVAO(GLuint vao) {
- assert(ThreadContext::currentlyOn(ThreadType::Map));
- abandonedVAOs.emplace_back(vao);
-}
-
-void GLObjectStore::abandonBuffer(GLuint buffer) {
- assert(ThreadContext::currentlyOn(ThreadType::Map));
- abandonedBuffers.emplace_back(buffer);
-}
-
-void GLObjectStore::abandonTexture(GLuint texture) {
- assert(ThreadContext::currentlyOn(ThreadType::Map));
- abandonedTextures.emplace_back(texture);
-}
-
-void GLObjectStore::performCleanup() {
- assert(ThreadContext::currentlyOn(ThreadType::Map));
-
- if (!abandonedVAOs.empty()) {
- MBGL_CHECK_ERROR(VertexArrayObject::Delete(static_cast<GLsizei>(abandonedVAOs.size()),
- abandonedVAOs.data()));
- abandonedVAOs.clear();
- }
-
- if (!abandonedTextures.empty()) {
- MBGL_CHECK_ERROR(glDeleteTextures(static_cast<GLsizei>(abandonedTextures.size()),
- abandonedTextures.data()));
- abandonedTextures.clear();
- }
-
- if (!abandonedBuffers.empty()) {
- MBGL_CHECK_ERROR(glDeleteBuffers(static_cast<GLsizei>(abandonedBuffers.size()),
- abandonedBuffers.data()));
- abandonedBuffers.clear();
- }
-}
-
-} // namespace util
-} // namespace mbgl
diff --git a/src/mbgl/util/gl_object_store.hpp b/src/mbgl/util/gl_object_store.hpp
deleted file mode 100644
index 775d4d1d01..0000000000
--- a/src/mbgl/util/gl_object_store.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef MBGL_MAP_UTIL_GL_OBJECT_STORE
-#define MBGL_MAP_UTIL_GL_OBJECT_STORE
-
-#include <mbgl/platform/gl.hpp>
-#include <mbgl/util/noncopyable.hpp>
-
-#include <cstdint>
-#include <vector>
-
-namespace mbgl {
-namespace util {
-
-class GLObjectStore : private util::noncopyable {
-public:
- GLObjectStore() = default;
-
- // Mark OpenGL objects for deletion
- void abandonVAO(GLuint vao);
- void abandonBuffer(GLuint buffer);
- void abandonTexture(GLuint texture);
-
- // Actually remove the objects we marked as abandoned with the above methods.
- // Only call this while the OpenGL context is exclusive to this thread.
- void performCleanup();
-
-private:
- std::vector<GLuint> abandonedVAOs;
- std::vector<GLuint> abandonedBuffers;
- std::vector<GLuint> abandonedTextures;
-};
-
-} // namespace util
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/util/mapbox.cpp b/src/mbgl/util/mapbox.cpp
index d94a9a5f7d..7ee0f279b6 100644
--- a/src/mbgl/util/mapbox.cpp
+++ b/src/mbgl/util/mapbox.cpp
@@ -111,83 +111,62 @@ std::string normalizeGlyphsURL(const std::string& url, const std::string& access
return baseURL + "fonts/v1/" + user + "/" + fontstack + "/" + range + "?access_token=" + accessToken;
}
-std::string normalizeRasterTileURL(const std::string& url) {
- std::string::size_type queryIdx = url.rfind("?");
- // Trim off the right end but never touch anything before the extension dot.
- std::string urlSansParams((queryIdx == std::string::npos) ? url : url.substr(0, queryIdx));
-
- while (!urlSansParams.empty() && isdigit(urlSansParams.back())) {
- urlSansParams.pop_back();
- }
-
- std::string::size_type basenameIdx = url.rfind("/", queryIdx);
- std::string::size_type extensionIdx = url.rfind(".", queryIdx);
- if (basenameIdx == std::string::npos || extensionIdx == std::string::npos ||
- basenameIdx > extensionIdx) {
- // No file extension: probably not a file name we can tack a ratio onto.
+std::string normalizeTileURL(const std::string& url, const std::string& accessToken) {
+ if (!isMapboxURL(url)) {
return url;
}
- std::string normalizedURL(url);
-#if !defined(__ANDROID__) && !defined(__APPLE__)
- // Replace PNG with WebP.
- if (normalizedURL.compare(extensionIdx + 1, 3, "png") == 0) {
- normalizedURL.replace(extensionIdx + 1, 3, "webp");
- }
-#endif // !defined(__ANDROID__) && !defined(__APPLE__)
- normalizedURL.insert(extensionIdx, "{ratio}");
- return normalizedURL;
+ return baseURL + "v4/" + url.substr(sizeof("mapbox://tiles/") - 1) + "?access_token=" + accessToken;
}
-
-std::string removeAccessTokenFromURL(const std::string &url) {
- const size_t token_start = url.find("access_token=");
- // Ensure that token exists, isn't at the front and is preceded by either & or ?.
- if (token_start == std::string::npos || token_start == 0 || !(url[token_start - 1] == '&' || url[token_start - 1] == '?')) {
+std::string canonicalizeTileURL(const std::string& url, SourceType type, uint16_t tileSize) {
+ auto tilesetStartIdx = url.find("/v4/");
+ if (tilesetStartIdx == std::string::npos) {
return url;
}
- const size_t token_end = url.find_first_of('&', token_start);
- if (token_end == std::string::npos) {
- // The token is the last query argument. We slice away the "&access_token=..." part
- return url.substr(0, token_start - 1);
- } else {
- // We slice away the "access_token=...&" part.
- return url.substr(0, token_start) + url.substr(token_end + 1);
- }
-}
-
-namespace {
+ tilesetStartIdx += sizeof("/v4/") - 1;
-std::string convertMapboxDomainsToProtocol(const std::string &url) {
- const size_t protocol_separator = url.find("://");
- if (protocol_separator == std::string::npos) {
+ auto tilesetEndIdx = url.find("/", tilesetStartIdx);
+ if (tilesetEndIdx == std::string::npos) {
return url;
}
- const std::string protocol = url.substr(0, protocol_separator);
- if (!(protocol == "http" || protocol == "https")) {
- return url;
+ auto queryIdx = url.rfind("?");
+ if (queryIdx == std::string::npos) {
+ queryIdx = url.length();
}
- const size_t domain_begin = protocol_separator + 3;
- const size_t path_separator = url.find("/", domain_begin);
- if (path_separator == std::string::npos) {
- return url;
+ auto basenameIdx = url.rfind("/", queryIdx);
+ if (basenameIdx == std::string::npos || basenameIdx == queryIdx - 1) {
+ basenameIdx = url.length();
+ } else {
+ basenameIdx += 1;
}
- const std::string domain = url.substr(domain_begin, path_separator - domain_begin);
- if (domain == "api.mapbox.com" || domain.find(".tiles.mapbox.com") != std::string::npos) {
- return std::string{ "mapbox://" } + url.substr(path_separator + 1);
- } else {
+ auto extensionIdx = url.find(".", basenameIdx);
+ if (extensionIdx == std::string::npos || extensionIdx == queryIdx - 1) {
return url;
}
-}
-} // end namespace
+ auto tileset = url.substr(tilesetStartIdx, tilesetEndIdx - tilesetStartIdx);
+ auto extension = url.substr(extensionIdx + 1, queryIdx - extensionIdx - 1);
+
+#if !defined(__ANDROID__) && !defined(__APPLE__)
+ // Replace PNG with WebP.
+ if (extension == "png") {
+ extension = "webp";
+ }
+#endif // !defined(__ANDROID__) && !defined(__APPLE__)
+
+ std::string result = "mapbox://tiles/" + tileset + "/{z}/{x}/{y}";
+
+ if (type == SourceType::Raster) {
+ result += tileSize == 512 ? "@2x" : "{ratio}";
+ }
-std::string canonicalURL(const std::string &url) {
- return removeAccessTokenFromURL(convertMapboxDomainsToProtocol(url));
+ result += "." + extension;
+ return result;
}
} // end namespace mapbox
diff --git a/src/mbgl/util/mapbox.hpp b/src/mbgl/util/mapbox.hpp
index 3c44d704c7..bb0536cfa2 100644
--- a/src/mbgl/util/mapbox.hpp
+++ b/src/mbgl/util/mapbox.hpp
@@ -14,13 +14,10 @@ std::string normalizeSourceURL(const std::string& url, const std::string& access
std::string normalizeStyleURL(const std::string& url, const std::string& accessToken);
std::string normalizeSpriteURL(const std::string& url, const std::string& accessToken);
std::string normalizeGlyphsURL(const std::string& url, const std::string& accessToken);
-std::string normalizeRasterTileURL(const std::string& url);
+std::string normalizeTileURL(const std::string& url, const std::string& accessToken);
-// Canonicalizes Mapbox URLs by removing [a-d] subdomain prefixes, access tokens, and protocol.
-// Note that this is close, but not exactly the reverse operation as above, as this retains certain
-// information, such as the API version. It is used to cache resources retrieved from the URL, that
-// sometimes have multiple valid URLs.
-std::string canonicalURL(const std::string &url);
+// Return a "mapbox://tiles/..." URL (suitable for normalizeTileURL) for the given Mapbox tile URL.
+std::string canonicalizeTileURL(const std::string& url, SourceType, uint16_t tileSize);
} // namespace mapbox
} // namespace util
diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp
index 704d05e1eb..a74b73a016 100644
--- a/src/mbgl/util/raster.cpp
+++ b/src/mbgl/util/raster.cpp
@@ -1,5 +1,5 @@
#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/raster.hpp>
@@ -9,13 +9,14 @@
using namespace mbgl;
-Raster::Raster(TexturePool& texturePool_)
+Raster::Raster(gl::TexturePool& texturePool_)
: texturePool(texturePool_)
{}
Raster::~Raster() {
if (textured) {
- texturePool.removeTextureID(texture);
+ texturePool.releaseTextureID(textureID);
+ textureID = 0;
}
}
@@ -36,16 +37,16 @@ void Raster::load(PremultipliedImage image) {
}
-void Raster::bind(bool linear) {
+void Raster::bind(bool linear, gl::GLObjectStore& glObjectStore) {
if (!width || !height) {
Log::Error(Event::OpenGL, "trying to bind texture without dimension");
return;
}
if (img.data && !textured) {
- upload();
+ upload(glObjectStore);
} else if (textured) {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID));
}
GLint new_filter = linear ? GL_LINEAR : GL_NEAREST;
@@ -56,10 +57,10 @@ void Raster::bind(bool linear) {
}
}
-void Raster::upload() {
+void Raster::upload(gl::GLObjectStore& glObjectStore) {
if (img.data && !textured) {
- texture = texturePool.getTextureID();
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ textureID = texturePool.getTextureID(glObjectStore);
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp
index 02d6615a9f..0a275a197c 100644
--- a/src/mbgl/util/raster.hpp
+++ b/src/mbgl/util/raster.hpp
@@ -1,8 +1,8 @@
#ifndef MBGL_UTIL_RASTER
#define MBGL_UTIL_RASTER
-#include <mbgl/platform/gl.hpp>
-#include <mbgl/util/texture_pool.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/texture_pool.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/chrono.hpp>
@@ -14,17 +14,17 @@ namespace mbgl {
class Raster : public std::enable_shared_from_this<Raster> {
public:
- Raster(TexturePool&);
+ Raster(gl::TexturePool&);
~Raster();
// load image data
void load(PremultipliedImage);
// bind current texture
- void bind(bool linear = false);
+ void bind(bool linear, gl::GLObjectStore&);
// uploads the texture if it hasn't been uploaded yet.
- void upload();
+ void upload(gl::GLObjectStore&);
// loaded status
bool isLoaded() const;
@@ -38,7 +38,7 @@ public:
bool textured = false;
// the uploaded texture
- GLuint texture = 0;
+ GLuint textureID = 0;
// texture opacity
double opacity = 0;
@@ -50,7 +50,7 @@ private:
bool loaded = false;
// shared texture pool
- TexturePool& texturePool;
+ gl::TexturePool& texturePool;
// min/mag filter
GLint filter = 0;
diff --git a/src/mbgl/util/texture_pool.cpp b/src/mbgl/util/texture_pool.cpp
deleted file mode 100644
index d4afb1f868..0000000000
--- a/src/mbgl/util/texture_pool.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <mbgl/util/texture_pool.hpp>
-
-#include <mbgl/util/gl_object_store.hpp>
-#include <mbgl/util/thread_context.hpp>
-
-#include <vector>
-
-const GLsizei TextureMax = 64;
-
-using namespace mbgl;
-
-GLuint TexturePool::getTextureID() {
- if (texture_ids.empty()) {
- GLuint new_texture_ids[TextureMax];
- MBGL_CHECK_ERROR(glGenTextures(TextureMax, new_texture_ids));
- for (GLuint id = 0; id < TextureMax; id++) {
- texture_ids.insert(new_texture_ids[id]);
- }
- }
-
- GLuint id = 0;
-
- if (!texture_ids.empty()) {
- std::set<GLuint>::iterator id_iterator = texture_ids.begin();
- id = *id_iterator;
- texture_ids.erase(id_iterator);
- }
-
- return id;
-}
-
-void TexturePool::removeTextureID(GLuint texture_id) {
- bool needs_clear = false;
-
- texture_ids.insert(texture_id);
-
- if (texture_ids.size() > TextureMax) {
- needs_clear = true;
- }
-
- if (needs_clear) {
- // TODO: We need to find a better way to deal with texture pool cleanup
-// clearTextureIDs();
- }
-}
-
-void TexturePool::clearTextureIDs() {
- auto getGLObjectStore = util::ThreadContext::getGLObjectStore();
- for (auto texture : texture_ids) {
- getGLObjectStore->abandonTexture(texture);
- }
- texture_ids.clear();
-}
diff --git a/src/mbgl/util/texture_pool.hpp b/src/mbgl/util/texture_pool.hpp
deleted file mode 100644
index a980584c13..0000000000
--- a/src/mbgl/util/texture_pool.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef MBGL_UTIL_TEXTUREPOOL
-#define MBGL_UTIL_TEXTUREPOOL
-
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/platform/gl.hpp>
-
-#include <set>
-#include <mutex>
-
-namespace mbgl {
-
-class TexturePool : private util::noncopyable {
-
-public:
- GLuint getTextureID();
- void removeTextureID(GLuint texture_id);
- void clearTextureIDs();
-
-private:
- std::set<GLuint> texture_ids;
-};
-
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/util/thread_context.cpp b/src/mbgl/util/thread_context.cpp
index b611b3d023..d6ddda2e8e 100644
--- a/src/mbgl/util/thread_context.cpp
+++ b/src/mbgl/util/thread_context.cpp
@@ -44,38 +44,6 @@ ThreadPriority ThreadContext::getPriority() {
}
}
-FileSource* ThreadContext::getFileSource() {
- if (current.get() != nullptr) {
- return current.get()->fileSource;
- } else {
- return nullptr;
- }
-}
-
-void ThreadContext::setFileSource(FileSource* fileSource) {
- if (current.get() != nullptr) {
- current.get()->fileSource = fileSource;
- } else {
- throw std::runtime_error("Current thread has no current ThreadContext.");
- }
-}
-
-GLObjectStore* ThreadContext::getGLObjectStore() {
- if (current.get() != nullptr) {
- return current.get()->glObjectStore;
- } else {
- return nullptr;
- }
-}
-
-void ThreadContext::setGLObjectStore(GLObjectStore* glObjectStore) {
- if (current.get() != nullptr) {
- current.get()->glObjectStore = glObjectStore;
- } else {
- throw std::runtime_error("Current thread has no current ThreadContext.");
- }
-}
-
class MainThreadContextRegistrar {
public:
MainThreadContextRegistrar() : context("Main", ThreadType::Main, ThreadPriority::Regular) {
diff --git a/src/mbgl/util/thread_context.hpp b/src/mbgl/util/thread_context.hpp
index 2b22b2faf4..dea98fe3fa 100644
--- a/src/mbgl/util/thread_context.hpp
+++ b/src/mbgl/util/thread_context.hpp
@@ -6,13 +6,8 @@
#include <thread>
namespace mbgl {
-
-class FileSource;
-
namespace util {
-class GLObjectStore;
-
enum class ThreadPriority : bool {
Regular,
Low,
@@ -35,17 +30,9 @@ public:
static std::string getName();
static ThreadPriority getPriority();
- static FileSource* getFileSource();
- static void setFileSource(FileSource* fileSource);
- static GLObjectStore* getGLObjectStore();
- static void setGLObjectStore(GLObjectStore* glObjectStore);
-
std::string name;
ThreadType type;
ThreadPriority priority;
-
- FileSource* fileSource = nullptr;
- GLObjectStore* glObjectStore = nullptr;
};
} // namespace util
diff --git a/src/mbgl/util/tile_coordinate.hpp b/src/mbgl/util/tile_coordinate.hpp
index 4710e08d0a..a989bef0c9 100644
--- a/src/mbgl/util/tile_coordinate.hpp
+++ b/src/mbgl/util/tile_coordinate.hpp
@@ -5,23 +5,11 @@
namespace mbgl {
-struct TileCoordinate {
+class TileCoordinate {
+public:
double column;
double row;
double zoom;
-
- TileCoordinate(double column_, double row_, double zoom_) :
- column(column_), row(row_), zoom(zoom_) {}
-
- TileCoordinate zoomTo(double targetZoom) {
- double scale = std::pow(2, targetZoom - zoom);
- return { column * scale, row * scale, targetZoom };
- }
-
- TileCoordinate operator-(TileCoordinate c) {
- c = c.zoomTo(zoom);
- return { column - c.column, row - c.row, zoom };
- };
};
} // namespace mbgl
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index 803aa53eee..e77ea469a7 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -1,7 +1,8 @@
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/vec.hpp>
-#include <mbgl/util/box.hpp>
#include <mbgl/util/tile_coordinate.hpp>
+#include <mbgl/util/constants.hpp>
+#include <mbgl/map/transform_state.hpp>
namespace mbgl {
@@ -66,7 +67,27 @@ static void scanTriangle(const mbgl::vec2<double> a, const mbgl::vec2<double> b,
if (bc.dy) scanSpans(ca, bc, ymin, ymax, scanLine);
}
-std::forward_list<TileID> tileCover(int8_t z, const mbgl::box &bounds, int8_t actualZ) {
+int32_t coveringZoomLevel(double zoom, SourceType type, uint16_t tileSize) {
+ zoom += std::log(util::tileSize / tileSize) / std::log(2);
+ if (type == SourceType::Raster || type == SourceType::Video) {
+ return ::round(zoom);
+ } else {
+ return std::floor(zoom);
+ }
+}
+
+static mbgl::vec2<double> zoomTo(const TileCoordinate& c, double z) {
+ double scale = std::pow(2, z - c.zoom);
+ return { c.column * scale, c.row * scale };
+}
+
+std::vector<TileID> tileCover(const TileCoordinate& tl_,
+ const TileCoordinate& tr_,
+ const TileCoordinate& br_,
+ const TileCoordinate& bl_,
+ const TileCoordinate& center,
+ int32_t z,
+ int32_t actualZ) {
int32_t tiles = 1 << z;
std::forward_list<mbgl::TileID> t;
@@ -79,10 +100,11 @@ std::forward_list<TileID> tileCover(int8_t z, const mbgl::box &bounds, int8_t ac
}
};
- mbgl::vec2<double> tl = { bounds.tl.column, bounds.tl.row };
- mbgl::vec2<double> tr = { bounds.tr.column, bounds.tr.row };
- mbgl::vec2<double> br = { bounds.br.column, bounds.br.row };
- mbgl::vec2<double> bl = { bounds.bl.column, bounds.bl.row };
+ mbgl::vec2<double> tl = zoomTo(tl_, z);
+ mbgl::vec2<double> tr = zoomTo(tr_, z);
+ mbgl::vec2<double> br = zoomTo(br_, z);
+ mbgl::vec2<double> bl = zoomTo(bl_, z);
+ mbgl::vec2<double> c = zoomTo(center, z);
// Divide the screen up in two triangles and scan each of them:
// \---+
@@ -94,7 +116,46 @@ std::forward_list<TileID> tileCover(int8_t z, const mbgl::box &bounds, int8_t ac
t.sort();
t.unique();
- return t;
+ t.sort([&](const TileID& a, const TileID& b) {
+ // Sorts by distance from the box center
+ return std::fabs(a.x - c.x) + std::fabs(a.y - c.y) <
+ std::fabs(b.x - c.x) + std::fabs(b.y - c.y);
+ });
+
+ return std::vector<TileID>(t.begin(), t.end());
+}
+
+std::vector<TileID> tileCover(const LatLngBounds& bounds_, int32_t z, int32_t actualZ) {
+ if (bounds_.isEmpty() ||
+ bounds_.south() > util::LATITUDE_MAX ||
+ bounds_.north() < -util::LATITUDE_MAX) {
+ return {};
+ }
+
+ LatLngBounds bounds = LatLngBounds::hull(
+ { std::max(bounds_.south(), -util::LATITUDE_MAX), bounds_.west() },
+ { std::min(bounds_.north(), util::LATITUDE_MAX), bounds_.east() });
+
+ const TransformState state;
+ return tileCover(
+ state.latLngToCoordinate(bounds.northwest()),
+ state.latLngToCoordinate(bounds.northeast()),
+ state.latLngToCoordinate(bounds.southeast()),
+ state.latLngToCoordinate(bounds.southwest()),
+ state.latLngToCoordinate(bounds.center()),
+ z, actualZ);
+}
+
+std::vector<TileID> tileCover(const TransformState& state, int32_t z, int32_t actualZ) {
+ const double w = state.getWidth();
+ const double h = state.getHeight();
+ return tileCover(
+ state.pointToCoordinate({ 0, 0 }),
+ state.pointToCoordinate({ w, 0 }),
+ state.pointToCoordinate({ w, h }),
+ state.pointToCoordinate({ 0, h }),
+ state.pointToCoordinate({ w/2, h/2 }),
+ z, actualZ);
}
} // namespace mbgl
diff --git a/src/mbgl/util/tile_cover.hpp b/src/mbgl/util/tile_cover.hpp
index 0514c36b62..a489964abf 100644
--- a/src/mbgl/util/tile_cover.hpp
+++ b/src/mbgl/util/tile_cover.hpp
@@ -2,13 +2,19 @@
#define MBGL_UTIL_TILE_COVER
#include <mbgl/map/tile_id.hpp>
-#include <mbgl/util/box.hpp>
+#include <mbgl/style/types.hpp>
-#include <forward_list>
+#include <vector>
namespace mbgl {
-std::forward_list<TileID> tileCover(int8_t z, const box& bounds, int8_t actualZ);
+class TransformState;
+class LatLngBounds;
+
+int32_t coveringZoomLevel(double z, SourceType type, uint16_t tileSize);
+
+std::vector<TileID> tileCover(const TransformState&, int32_t z, int32_t actualZ);
+std::vector<TileID> tileCover(const LatLngBounds&, int32_t z, int32_t actualZ);
} // namespace mbgl
diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp
index fe8ee81779..bc6e4be3db 100644
--- a/src/mbgl/util/worker.cpp
+++ b/src/mbgl/util/worker.cpp
@@ -3,7 +3,7 @@
#include <mbgl/util/work_request.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
-#include <mbgl/map/geometry_tile.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/style/style_layer.hpp>
#include <cassert>
diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp
index d72438bc75..96a7b27885 100644
--- a/src/mbgl/util/worker.hpp
+++ b/src/mbgl/util/worker.hpp
@@ -3,7 +3,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/thread.hpp>
-#include <mbgl/map/tile_worker.hpp>
+#include <mbgl/tile/tile_worker.hpp>
#include <functional>
#include <memory>