Merge branch 'master' of github.com:mapbox/mapbox-gl-native into android-mason
Conflicts: README.md configure gyp/mbgl-linux.gypi include/mbgl/map/map.hpp include/mbgl/platform/default/image_reader.hpp include/mbgl/platform/default/jpeg_reader.hpp include/mbgl/platform/default/png_reader.hpp include/mbgl/util/uv_detail.hpp ios/mapbox-gl-cocoa platform/default/image.cpp platform/default/image_reader.cpp platform/default/jpeg_reader.cpp platform/default/png_reader.cpp src/map/map.cpp
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
['OS == "linux"', {
|
||||
'other_ldflags': [
|
||||
'<@(png_static_libs)',
|
||||
'<@(jpeg_static_libs)',
|
||||
'<@(glfw3_static_libs)',
|
||||
'<@(glfw3_ldflags)',
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(uv_cflags)',
|
||||
'<@(curl_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
|
||||
@@ -28,8 +28,6 @@ private:
|
||||
const SDFGlyph& glyph);
|
||||
public:
|
||||
GlyphAtlas(uint16_t width, uint16_t height);
|
||||
~GlyphAtlas();
|
||||
|
||||
|
||||
Rect<uint16_t> addGlyph(uint64_t tile_id, const std::string& face_name,
|
||||
const SDFGlyph& glyph);
|
||||
@@ -46,7 +44,7 @@ private:
|
||||
std::mutex mtx;
|
||||
BinPack<uint16_t> bin;
|
||||
std::map<std::string, std::map<uint32_t, GlyphValue>> index;
|
||||
char *const data = nullptr;
|
||||
std::unique_ptr<char[]> data;
|
||||
std::atomic<bool> dirty;
|
||||
uint32_t texture = 0;
|
||||
};
|
||||
|
||||
@@ -79,7 +79,6 @@ public:
|
||||
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height);
|
||||
|
||||
// Styling
|
||||
const std::set<util::ptr<StyleSource>> getActiveSources() const;
|
||||
void setAppliedClasses(const std::vector<std::string> &classes);
|
||||
void toggleClass(const std::string &name);
|
||||
const std::vector<std::string> &getAppliedClasses() const;
|
||||
@@ -133,24 +132,12 @@ public:
|
||||
// Call this when the network reachability changed.
|
||||
void setReachability(bool status);
|
||||
|
||||
public:
|
||||
inline const TransformState &getState() const { return state; }
|
||||
inline util::ptr<Style> getStyle() const { return style; }
|
||||
inline GlyphAtlas & getGlyphAtlas() { return glyphAtlas; }
|
||||
inline util::ptr<GlyphStore> getGlyphStore() { return glyphStore; }
|
||||
inline SpriteAtlas & getSpriteAtlas() { return spriteAtlas; }
|
||||
util::ptr<Sprite> getSprite();
|
||||
inline util::ptr<Texturepool> getTexturepool() { return texturepool; }
|
||||
uv::worker &getWorker();
|
||||
inline timestamp getAnimationTime() const { return animationTime; }
|
||||
inline timestamp getTime() const { return animationTime; }
|
||||
void updateTiles();
|
||||
|
||||
private:
|
||||
// uv async callbacks
|
||||
static void render(uv_async_t *async);
|
||||
static void terminate(uv_async_t *async);
|
||||
static void cleanup(uv_async_t *async);
|
||||
util::ptr<Sprite> getSprite();
|
||||
uv::worker& getWorker();
|
||||
|
||||
// Checks if render thread needs to pause
|
||||
void check_for_pause();
|
||||
@@ -158,6 +145,7 @@ private:
|
||||
// Setup
|
||||
void setup();
|
||||
|
||||
void updateTiles();
|
||||
void updateSources();
|
||||
void updateSources(const util::ptr<StyleLayerGroup> &group);
|
||||
|
||||
@@ -168,16 +156,14 @@ private:
|
||||
// Unconditionally performs a render with the current map state.
|
||||
void render();
|
||||
|
||||
private:
|
||||
bool async = false;
|
||||
std::unique_ptr<uv::loop> loop;
|
||||
std::unique_ptr<uv::worker> workers;
|
||||
std::unique_ptr<uv::thread> thread;
|
||||
std::unique_ptr<uv_async_t> async_terminate;
|
||||
std::unique_ptr<uv_async_t> async_render;
|
||||
std::unique_ptr<uv_async_t> async_cleanup;
|
||||
std::unique_ptr<uv::async> async_terminate;
|
||||
std::unique_ptr<uv::async> async_render;
|
||||
std::unique_ptr<uv::async> async_cleanup;
|
||||
|
||||
private:
|
||||
bool terminating = false;
|
||||
bool pausing = false;
|
||||
bool is_paused = false;
|
||||
@@ -186,7 +172,6 @@ private:
|
||||
std::mutex mutex_pause;
|
||||
std::condition_variable cond_pause;
|
||||
|
||||
private:
|
||||
// If cleared, the next time the render thread attempts to render the map, it will *actually*
|
||||
// render the map.
|
||||
std::atomic_flag is_clean = ATOMIC_FLAG_INIT;
|
||||
@@ -202,10 +187,8 @@ private:
|
||||
// Stores whether the map thread has been stopped already.
|
||||
std::atomic_bool is_stopped;
|
||||
|
||||
public:
|
||||
View &view;
|
||||
|
||||
private:
|
||||
#ifndef NDEBUG
|
||||
const unsigned long main_thread;
|
||||
unsigned long map_thread = -1;
|
||||
@@ -238,7 +221,6 @@ private:
|
||||
timestamp animationTime = 0;
|
||||
|
||||
std::set<util::ptr<StyleSource>> activeSources;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Map;
|
||||
class Painter;
|
||||
class SourceInfo;
|
||||
class StyleLayer;
|
||||
class Texturepool;
|
||||
|
||||
class RasterTileData : public TileData {
|
||||
friend class TileParser;
|
||||
|
||||
public:
|
||||
RasterTileData(Tile::ID const& id, Map &map, const util::ptr<SourceInfo> &source);
|
||||
RasterTileData(Tile::ID const& id, Texturepool&, const SourceInfo&);
|
||||
~RasterTileData();
|
||||
|
||||
virtual void parse();
|
||||
|
||||
@@ -18,7 +18,13 @@
|
||||
namespace mbgl {
|
||||
|
||||
class Map;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class FileSource;
|
||||
class Texturepool;
|
||||
class Style;
|
||||
class Painter;
|
||||
class StyleLayer;
|
||||
class TransformState;
|
||||
@@ -26,10 +32,15 @@ struct box;
|
||||
|
||||
class Source : public std::enable_shared_from_this<Source>, private util::noncopyable {
|
||||
public:
|
||||
Source(const util::ptr<SourceInfo>& info);
|
||||
Source(SourceInfo&);
|
||||
|
||||
void load(Map&, FileSource&);
|
||||
bool update(Map&, FileSource&);
|
||||
void update(Map&, uv::worker&,
|
||||
util::ptr<Style>,
|
||||
GlyphAtlas&, GlyphStore&,
|
||||
SpriteAtlas&, util::ptr<Sprite>,
|
||||
Texturepool&, FileSource&,
|
||||
std::function<void ()> callback);
|
||||
|
||||
void updateMatrices(const mat4 &projMatrix, const TransformState &transform);
|
||||
void drawClippingMasks(Painter &painter);
|
||||
@@ -48,14 +59,19 @@ private:
|
||||
int32_t coveringZoomLevel(const TransformState&) const;
|
||||
std::forward_list<Tile::ID> coveringTiles(const TransformState&) const;
|
||||
|
||||
bool updateTiles(Map&, FileSource&);
|
||||
TileData::State addTile(Map&, uv::worker&,
|
||||
util::ptr<Style>,
|
||||
GlyphAtlas&, GlyphStore&,
|
||||
SpriteAtlas&, util::ptr<Sprite>,
|
||||
FileSource&, Texturepool&,
|
||||
const Tile::ID&,
|
||||
std::function<void ()> callback);
|
||||
|
||||
TileData::State addTile(Map&, FileSource&, const Tile::ID&);
|
||||
TileData::State hasTile(const Tile::ID& id);
|
||||
|
||||
double getZoom(const TransformState &state) const;
|
||||
|
||||
util::ptr<SourceInfo> info;
|
||||
SourceInfo& info;
|
||||
bool loaded = false;
|
||||
|
||||
// Stores the time when this source was most recently updated.
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
#include <exception>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
namespace uv {
|
||||
class worker;
|
||||
}
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -41,12 +46,12 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
TileData(Tile::ID const& id, Map &map, const util::ptr<SourceInfo> &source);
|
||||
TileData(Tile::ID const& id, const SourceInfo&);
|
||||
~TileData();
|
||||
|
||||
void request(FileSource&);
|
||||
void request(uv::worker&, FileSource&, float pixelRatio, std::function<void ()> callback);
|
||||
void reparse(uv::worker&, std::function<void ()> callback);
|
||||
void cancel();
|
||||
void reparse();
|
||||
const std::string toString() const;
|
||||
|
||||
inline bool ready() const {
|
||||
@@ -63,11 +68,8 @@ public:
|
||||
const Tile::ID id;
|
||||
std::atomic<State> state;
|
||||
|
||||
protected:
|
||||
Map ↦
|
||||
|
||||
public:
|
||||
util::ptr<SourceInfo> source;
|
||||
const SourceInfo& source;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Request> req;
|
||||
|
||||
@@ -28,6 +28,7 @@ class StyleBucketSymbol;
|
||||
class StyleLayerGroup;
|
||||
class VectorTileData;
|
||||
class Collision;
|
||||
class Texturepool;
|
||||
|
||||
class TileParser : private util::noncopyable
|
||||
{
|
||||
@@ -35,9 +36,10 @@ public:
|
||||
TileParser(const std::string &data, VectorTileData &tile,
|
||||
const util::ptr<const Style> &style,
|
||||
GlyphAtlas & glyphAtlas,
|
||||
const util::ptr<GlyphStore> &glyphStore,
|
||||
GlyphStore & glyphStore,
|
||||
SpriteAtlas & spriteAtlas,
|
||||
const util::ptr<Sprite> &sprite);
|
||||
const util::ptr<Sprite> &sprite,
|
||||
Texturepool& texturepool);
|
||||
~TileParser();
|
||||
|
||||
public:
|
||||
@@ -49,7 +51,7 @@ private:
|
||||
std::unique_ptr<Bucket> createBucket(util::ptr<StyleBucket> bucket_desc);
|
||||
|
||||
std::unique_ptr<Bucket> createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill);
|
||||
std::unique_ptr<Bucket> createRasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster &raster);
|
||||
std::unique_ptr<Bucket> createRasterBucket(Texturepool& texturepool, const StyleBucketRaster &raster);
|
||||
std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line);
|
||||
std::unique_ptr<Bucket> createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol);
|
||||
|
||||
@@ -62,10 +64,10 @@ private:
|
||||
// Cross-thread shared data.
|
||||
util::ptr<const Style> style;
|
||||
GlyphAtlas & glyphAtlas;
|
||||
util::ptr<GlyphStore> glyphStore;
|
||||
GlyphStore & glyphStore;
|
||||
SpriteAtlas & spriteAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
util::ptr<Texturepool> texturePool;
|
||||
Texturepool& texturePool;
|
||||
|
||||
std::unique_ptr<Collision> collision;
|
||||
};
|
||||
|
||||
@@ -16,18 +16,29 @@
|
||||
namespace mbgl {
|
||||
|
||||
class Bucket;
|
||||
class Map;
|
||||
class Painter;
|
||||
class SourceInfo;
|
||||
class StyleLayer;
|
||||
class TileParser;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class Texturepool;
|
||||
class Style;
|
||||
|
||||
class VectorTileData : public TileData {
|
||||
friend class TileParser;
|
||||
|
||||
public:
|
||||
VectorTileData(Tile::ID const& id, Map &map, const util::ptr<SourceInfo> &source);
|
||||
VectorTileData(Tile::ID const&,
|
||||
float mapMaxZoom, util::ptr<Style>,
|
||||
GlyphAtlas&, GlyphStore&,
|
||||
SpriteAtlas&, util::ptr<Sprite>,
|
||||
Texturepool&,
|
||||
const SourceInfo&);
|
||||
~VectorTileData();
|
||||
|
||||
virtual void parse();
|
||||
virtual void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const mat4 &matrix);
|
||||
virtual bool hasData(StyleLayer const& layer_desc) const;
|
||||
@@ -46,6 +57,14 @@ protected:
|
||||
// Holds the buckets of this tile.
|
||||
// They contain the location offsets in the buffers stored above
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
|
||||
GlyphAtlas& glyphAtlas;
|
||||
GlyphStore& glyphStore;
|
||||
SpriteAtlas& spriteAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
Texturepool& texturepool;
|
||||
util::ptr<Style> style;
|
||||
|
||||
public:
|
||||
const float depth;
|
||||
};
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
class image_reader_exception : public std::exception
|
||||
class ImageReaderException : public std::exception
|
||||
{
|
||||
private:
|
||||
std::string message_;
|
||||
public:
|
||||
image_reader_exception(std::string const& message)
|
||||
ImageReaderException(std::string const& message)
|
||||
: message_(message) {}
|
||||
|
||||
~image_reader_exception() throw() {}
|
||||
~ImageReaderException() throw() {}
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
@@ -25,17 +25,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct image_reader : private noncopyable
|
||||
struct ImageReader : private noncopyable
|
||||
{
|
||||
virtual unsigned width() const=0;
|
||||
virtual unsigned height() const=0;
|
||||
virtual bool has_alpha() const=0;
|
||||
virtual bool premultiplied_alpha() const=0;
|
||||
virtual bool hasAlpha() const=0;
|
||||
virtual bool premultipliedAlpha() const=0;
|
||||
virtual void read(unsigned x,unsigned y, unsigned width, unsigned height, char* image)=0;
|
||||
virtual ~image_reader() {}
|
||||
virtual ~ImageReader() {}
|
||||
};
|
||||
|
||||
std::unique_ptr<image_reader> get_image_reader(char const* data, size_t size);
|
||||
std::unique_ptr<ImageReader> getImageReader(char const* data, size_t size);
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ extern "C"
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class jpeg_reader : public image_reader
|
||||
class JpegReader : public ImageReader
|
||||
{
|
||||
public:
|
||||
using source_type = T;
|
||||
@@ -46,12 +46,12 @@ private:
|
||||
unsigned width_;
|
||||
unsigned height_;
|
||||
public:
|
||||
jpeg_reader(char const* data, size_t size);
|
||||
~jpeg_reader();
|
||||
JpegReader(char const* data, size_t size);
|
||||
~JpegReader();
|
||||
unsigned width() const;
|
||||
unsigned height() const;
|
||||
inline bool has_alpha() const { return false; }
|
||||
inline bool premultiplied_alpha() const { return true; }
|
||||
inline bool hasAlpha() const { return false; }
|
||||
inline bool premultipliedAlpha() const { return true; }
|
||||
void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image);
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -16,7 +16,7 @@ extern "C"
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class png_reader : public image_reader
|
||||
class PngReader : public ImageReader
|
||||
{
|
||||
using source_type = T;
|
||||
using input_stream = boost::iostreams::stream<source_type>;
|
||||
@@ -44,12 +44,12 @@ private:
|
||||
int color_type_;
|
||||
bool has_alpha_;
|
||||
public:
|
||||
png_reader(char const* data, std::size_t size);
|
||||
~png_reader();
|
||||
PngReader(char const* data, std::size_t size);
|
||||
~PngReader();
|
||||
unsigned width() const;
|
||||
unsigned height() const;
|
||||
inline bool has_alpha() const { return has_alpha_; }
|
||||
bool premultiplied_alpha() const { return true; } // png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2)
|
||||
inline bool hasAlpha() const { return has_alpha_; }
|
||||
bool premultipliedAlpha() const { return true; } // png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2)
|
||||
void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image);
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -16,7 +16,7 @@ class VertexArrayObject;
|
||||
|
||||
class RasterBucket : public Bucket {
|
||||
public:
|
||||
RasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster& properties);
|
||||
RasterBucket(Texturepool&, const StyleBucketRaster&);
|
||||
|
||||
virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
|
||||
virtual bool hasData() const;
|
||||
@@ -31,8 +31,6 @@ public:
|
||||
void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, GLuint texture);
|
||||
|
||||
Raster raster;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,16 +29,11 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class StyleSource : public std::enable_shared_from_this<StyleSource> {
|
||||
class StyleSource : private util::noncopyable {
|
||||
public:
|
||||
util::ptr<SourceInfo> info;
|
||||
|
||||
SourceInfo info;
|
||||
bool enabled = false;
|
||||
util::ptr<Source> source;
|
||||
|
||||
StyleSource(const util::ptr<SourceInfo> &info_)
|
||||
: info(info_)
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace mbgl {
|
||||
class Raster : public std::enable_shared_from_this<Raster> {
|
||||
|
||||
public:
|
||||
Raster(const util::ptr<Texturepool> &texturepool);
|
||||
Raster(Texturepool&);
|
||||
~Raster();
|
||||
|
||||
// load image data
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
bool loaded = false;
|
||||
|
||||
// shared texture pool
|
||||
util::ptr<Texturepool> texturepool;
|
||||
Texturepool& texturepool;
|
||||
|
||||
// min/mag filter
|
||||
uint32_t filter = 0;
|
||||
|
||||
@@ -12,14 +12,10 @@ namespace uv {
|
||||
|
||||
std::string cwd();
|
||||
|
||||
struct deleter {
|
||||
void operator()(uv_async_t *async);
|
||||
void operator()(uv_timer_t *timer);
|
||||
};
|
||||
|
||||
class thread;
|
||||
class rwlock;
|
||||
class loop;
|
||||
class async;
|
||||
class worker;
|
||||
class mutex;
|
||||
class cond;
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
#ifndef MBGL_UTIL_UV_DETAIL
|
||||
#define MBGL_UTIL_UV_DETAIL
|
||||
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/uv-worker.h>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace uv {
|
||||
|
||||
class thread {
|
||||
template <class T>
|
||||
void close(T* handle) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(handle), nullptr);
|
||||
}
|
||||
|
||||
class thread : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline operator uv_thread_t *() { return &t; }
|
||||
|
||||
@@ -21,7 +26,7 @@ private:
|
||||
uv_thread_t t;
|
||||
};
|
||||
|
||||
class loop {
|
||||
class loop : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline loop() {
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
@@ -51,8 +56,43 @@ private:
|
||||
uv_loop_t *l = nullptr;
|
||||
};
|
||||
|
||||
class mutex {
|
||||
class async : public mbgl::util::noncopyable {
|
||||
friend class cond;
|
||||
public:
|
||||
inline async(uv_loop_t* loop, std::function<void ()> fn_)
|
||||
: fn(fn_) {
|
||||
a.data = this;
|
||||
if (uv_async_init(loop, &a, async_cb) != 0) {
|
||||
throw std::runtime_error("failed to initialize async");
|
||||
}
|
||||
}
|
||||
|
||||
inline ~async() {
|
||||
close(&a);
|
||||
}
|
||||
|
||||
inline void send() {
|
||||
if (uv_async_send(&a) != 0) {
|
||||
throw std::runtime_error("failed to async send");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
static void async_cb(uv_async_t* a, int) {
|
||||
#else
|
||||
static void async_cb(uv_async_t* a) {
|
||||
#endif
|
||||
reinterpret_cast<async*>(a->data)->fn();
|
||||
}
|
||||
|
||||
uv_async_t a;
|
||||
std::function<void ()> fn;
|
||||
};
|
||||
|
||||
class mutex : public mbgl::util::noncopyable {
|
||||
friend class cond;
|
||||
|
||||
public:
|
||||
inline mutex() {
|
||||
if (uv_mutex_init(&mtx) != 0) {
|
||||
@@ -67,7 +107,7 @@ private:
|
||||
uv_mutex_t mtx;
|
||||
};
|
||||
|
||||
class cond {
|
||||
class cond : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline cond() {
|
||||
if (uv_cond_init(&cnd) != 0) {
|
||||
@@ -84,7 +124,7 @@ private:
|
||||
uv_cond_t cnd;
|
||||
};
|
||||
|
||||
class lock {
|
||||
class lock : public mbgl::util::noncopyable {
|
||||
public:
|
||||
lock(mutex &mtx_) : mtx(mtx_) { mtx.lock(); }
|
||||
~lock() { mtx.unlock(); }
|
||||
@@ -93,7 +133,7 @@ private:
|
||||
mutex &mtx;
|
||||
};
|
||||
|
||||
class rwlock {
|
||||
class rwlock : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline rwlock() {
|
||||
if (uv_rwlock_init(&mtx) != 0) {
|
||||
@@ -110,7 +150,7 @@ private:
|
||||
uv_rwlock_t mtx;
|
||||
};
|
||||
|
||||
class readlock {
|
||||
class readlock : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline readlock(rwlock &mtx_) : mtx(mtx_) { mtx.rdlock(); }
|
||||
inline readlock(const std::unique_ptr<rwlock> &mtx_) : mtx(*mtx_) { mtx.rdlock(); }
|
||||
@@ -120,7 +160,7 @@ private:
|
||||
rwlock &mtx;
|
||||
};
|
||||
|
||||
class writelock {
|
||||
class writelock : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline writelock(rwlock &mtx_) : mtx(mtx_) { mtx.wrlock(); }
|
||||
inline writelock(const std::unique_ptr<rwlock> &mtx_) : mtx(*mtx_) { mtx.wrlock(); }
|
||||
@@ -130,18 +170,7 @@ private:
|
||||
rwlock &mtx;
|
||||
};
|
||||
|
||||
class once {
|
||||
public:
|
||||
typedef void (*callback)();
|
||||
void operator()(void (*callback)(void)) {
|
||||
uv_once(&o, callback);
|
||||
}
|
||||
|
||||
private:
|
||||
uv_once_t o = UV_ONCE_INIT;
|
||||
};
|
||||
|
||||
class worker {
|
||||
class worker : public mbgl::util::noncopyable {
|
||||
public:
|
||||
inline worker(uv_loop_t *loop, unsigned int count, const char *name = nullptr) : w(new uv_worker_t) {
|
||||
uv_worker_init(w, loop, count, name);
|
||||
@@ -160,10 +189,10 @@ private:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class work {
|
||||
class work : public mbgl::util::noncopyable {
|
||||
public:
|
||||
typedef void (*work_callback)(T &object);
|
||||
typedef void (*after_work_callback)(T &object);
|
||||
typedef std::function<void (T&)> work_callback;
|
||||
typedef std::function<void (T&)> after_work_callback;
|
||||
|
||||
template<typename... Args>
|
||||
work(worker &worker, work_callback work_cb_, after_work_callback after_work_cb_, Args&&... args)
|
||||
|
||||
@@ -78,13 +78,13 @@ Image::Image(std::string const& data)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto reader = get_image_reader(data.c_str(), data.size());
|
||||
auto reader = getImageReader(data.c_str(), data.size());
|
||||
width = reader->width();
|
||||
height = reader->height();
|
||||
img = ::std::unique_ptr<char[]>(new char[width * height * 4]());
|
||||
reader->read(0, 0, width, height, img.get());
|
||||
}
|
||||
catch (image_reader_exception const& ex)
|
||||
catch (ImageReaderException const& ex)
|
||||
{
|
||||
fprintf(stderr, "Image: %s\n", ex.what());
|
||||
img.reset();
|
||||
|
||||
@@ -42,21 +42,21 @@ inline boost::optional<std::string> type_from_bytes(char const* data, size_t siz
|
||||
return result_type();
|
||||
}
|
||||
|
||||
std::unique_ptr<image_reader> get_image_reader(char const* data, size_t size)
|
||||
std::unique_ptr<ImageReader> getImageReader(char const* data, size_t size)
|
||||
{
|
||||
boost::optional<std::string> type = type_from_bytes(data,size);
|
||||
if (type)
|
||||
{
|
||||
if (*type == "png")
|
||||
{
|
||||
return std::make_unique<png_reader<boost::iostreams::array_source>>(data, size);
|
||||
return std::make_unique<PngReader<boost::iostreams::array_source>>(data, size);
|
||||
}
|
||||
else if (*type == "jpeg")
|
||||
{
|
||||
return std::make_unique<jpeg_reader<boost::iostreams::array_source>>(data, size);
|
||||
return std::make_unique<JpegReader<boost::iostreams::array_source>>(data, size);
|
||||
}
|
||||
}
|
||||
throw image_reader_exception("image_reader: can't determine type from input data");
|
||||
throw ImageReaderException("ImageReader: can't determine type from input data");
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -13,30 +13,30 @@ namespace mbgl { namespace util {
|
||||
|
||||
// ctor
|
||||
template <typename T>
|
||||
jpeg_reader<T>::jpeg_reader(char const* data, size_t size)
|
||||
JpegReader<T>::JpegReader(char const* data, size_t size)
|
||||
: source_(data, size),
|
||||
stream_(source_),
|
||||
width_(0),
|
||||
height_(0)
|
||||
{
|
||||
if (!stream_) throw image_reader_exception("cannot open image stream");
|
||||
if (!stream_) throw ImageReaderException("cannot open image stream");
|
||||
init();
|
||||
}
|
||||
|
||||
// dtor
|
||||
template <typename T>
|
||||
jpeg_reader<T>::~jpeg_reader() {}
|
||||
JpegReader<T>::~JpegReader() {}
|
||||
|
||||
// jpeg stream wrapper
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::init_source (j_decompress_ptr cinfo)
|
||||
void JpegReader<T>::init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
|
||||
wrap->stream->seekg(0,std::ios_base::beg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boolean jpeg_reader<T>::fill_input_buffer (j_decompress_ptr cinfo)
|
||||
boolean JpegReader<T>::fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
|
||||
wrap->stream->read(reinterpret_cast<char*>(&wrap->buffer[0]),BUF_SIZE);
|
||||
@@ -47,7 +47,7 @@ boolean jpeg_reader<T>::fill_input_buffer (j_decompress_ptr cinfo)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::skip(j_decompress_ptr cinfo, long count)
|
||||
void JpegReader<T>::skip(j_decompress_ptr cinfo, long count)
|
||||
{
|
||||
if (count <= 0) return; //A zero or negative skip count should be treated as a no-op.
|
||||
jpeg_stream_wrapper* wrap = reinterpret_cast<jpeg_stream_wrapper*>(cinfo->src);
|
||||
@@ -67,20 +67,20 @@ void jpeg_reader<T>::skip(j_decompress_ptr cinfo, long count)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::term (j_decompress_ptr /*cinfo*/)
|
||||
void JpegReader<T>::term (j_decompress_ptr /*cinfo*/)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::attach_stream (j_decompress_ptr cinfo, input_stream* in)
|
||||
void JpegReader<T>::attach_stream (j_decompress_ptr cinfo, input_stream* in)
|
||||
{
|
||||
if (cinfo->src == 0)
|
||||
{
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper));
|
||||
}
|
||||
jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast<jpeg_reader::jpeg_stream_wrapper*> (cinfo->src);
|
||||
JpegReader::jpeg_stream_wrapper * src = reinterpret_cast<JpegReader::jpeg_stream_wrapper*> (cinfo->src);
|
||||
src->manager.init_source = init_source;
|
||||
src->manager.fill_input_buffer = fill_input_buffer;
|
||||
src->manager.skip_input_data = skip;
|
||||
@@ -92,20 +92,20 @@ void jpeg_reader<T>::attach_stream (j_decompress_ptr cinfo, input_stream* in)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::on_error(j_common_ptr /*cinfo*/)
|
||||
void JpegReader<T>::on_error(j_common_ptr /*cinfo*/)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::on_error_message(j_common_ptr cinfo)
|
||||
void JpegReader<T>::on_error_message(j_common_ptr cinfo)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
(*cinfo->err->format_message)(cinfo, buffer);
|
||||
throw image_reader_exception(std::string("JPEG Reader: libjpeg could not read image: ") + buffer);
|
||||
throw ImageReaderException(std::string("JPEG Reader: libjpeg could not read image: ") + buffer);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::init()
|
||||
void JpegReader<T>::init()
|
||||
{
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_info_guard iguard(&cinfo);
|
||||
@@ -117,35 +117,35 @@ void jpeg_reader<T>::init()
|
||||
attach_stream(&cinfo, &stream_);
|
||||
int ret = jpeg_read_header(&cinfo, TRUE);
|
||||
if (ret != JPEG_HEADER_OK)
|
||||
throw image_reader_exception("JPEG Reader: failed to read header");
|
||||
throw ImageReaderException("JPEG Reader: failed to read header");
|
||||
jpeg_start_decompress(&cinfo);
|
||||
width_ = cinfo.output_width;
|
||||
height_ = cinfo.output_height;
|
||||
|
||||
if (cinfo.out_color_space == JCS_UNKNOWN)
|
||||
{
|
||||
throw image_reader_exception("JPEG Reader: failed to read unknown color space");
|
||||
throw ImageReaderException("JPEG Reader: failed to read unknown color space");
|
||||
}
|
||||
if (cinfo.output_width == 0 || cinfo.output_height == 0)
|
||||
{
|
||||
throw image_reader_exception("JPEG Reader: failed to read image size of");
|
||||
throw ImageReaderException("JPEG Reader: failed to read image size of");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned jpeg_reader<T>::width() const
|
||||
unsigned JpegReader<T>::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned jpeg_reader<T>::height() const
|
||||
unsigned JpegReader<T>::height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void jpeg_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char* image)
|
||||
void JpegReader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char* image)
|
||||
{
|
||||
stream_.clear();
|
||||
stream_.seekg(0, std::ios_base::beg);
|
||||
@@ -159,7 +159,7 @@ void jpeg_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char
|
||||
jpeg_create_decompress(&cinfo);
|
||||
attach_stream(&cinfo, &stream_);
|
||||
int ret = jpeg_read_header(&cinfo, TRUE);
|
||||
if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader read(): failed to read header");
|
||||
if (ret != JPEG_HEADER_OK) throw ImageReaderException("JPEG Reader read(): failed to read header");
|
||||
jpeg_start_decompress(&cinfo);
|
||||
JSAMPARRAY buffer;
|
||||
int row_stride;
|
||||
@@ -198,6 +198,6 @@ void jpeg_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
}
|
||||
|
||||
template class jpeg_reader<boost::iostreams::array_source>;
|
||||
template class JpegReader<boost::iostreams::array_source>;
|
||||
|
||||
}}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace mbgl { namespace util {
|
||||
|
||||
void user_error_fn(png_structp /*png_ptr*/, png_const_charp error_msg)
|
||||
{
|
||||
throw image_reader_exception(std::string("failed to read invalid png: '") + error_msg + "'");
|
||||
throw ImageReaderException(std::string("failed to read invalid png: '") + error_msg + "'");
|
||||
}
|
||||
|
||||
void user_warning_fn(png_structp /*png_ptr*/, png_const_charp warning_msg)
|
||||
@@ -28,7 +28,7 @@ void user_warning_fn(png_structp /*png_ptr*/, png_const_charp warning_msg)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void png_reader<T>::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
void PngReader<T>::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
input_stream * fin = reinterpret_cast<input_stream*>(png_get_io_ptr(png_ptr));
|
||||
fin->read(reinterpret_cast<char*>(data), length);
|
||||
@@ -40,7 +40,7 @@ void png_reader<T>::png_read_data(png_structp png_ptr, png_bytep data, png_size_
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
png_reader<T>::png_reader(char const* data, std::size_t size)
|
||||
PngReader<T>::PngReader(char const* data, std::size_t size)
|
||||
: source_(data,size),
|
||||
stream_(source_),
|
||||
width_(0),
|
||||
@@ -50,36 +50,36 @@ png_reader<T>::png_reader(char const* data, std::size_t size)
|
||||
has_alpha_(false)
|
||||
{
|
||||
|
||||
if (!stream_) throw image_reader_exception("PNG reader: cannot open image stream");
|
||||
if (!stream_) throw ImageReaderException("PNG reader: cannot open image stream");
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
png_reader<T>::~png_reader() {}
|
||||
PngReader<T>::~PngReader() {}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void png_reader<T>::init()
|
||||
void PngReader<T>::init()
|
||||
{
|
||||
png_byte header[8];
|
||||
std::memset(header,0,8);
|
||||
stream_.read(reinterpret_cast<char*>(header),8);
|
||||
if ( stream_.gcount() != 8)
|
||||
{
|
||||
throw image_reader_exception("PNG reader: Could not read image");
|
||||
throw ImageReaderException("PNG reader: Could not read image");
|
||||
}
|
||||
int is_png=!png_sig_cmp(header,0,8);
|
||||
if (!is_png)
|
||||
{
|
||||
throw image_reader_exception("File or stream is not a png");
|
||||
throw ImageReaderException("File or stream is not a png");
|
||||
}
|
||||
png_structp png_ptr = png_create_read_struct
|
||||
(PNG_LIBPNG_VER_STRING,0,0,0);
|
||||
|
||||
if (!png_ptr)
|
||||
{
|
||||
throw image_reader_exception("failed to allocate png_ptr");
|
||||
throw ImageReaderException("failed to allocate png_ptr");
|
||||
}
|
||||
|
||||
// catch errors in a custom way to avoid the need for setjmp
|
||||
@@ -88,7 +88,7 @@ void png_reader<T>::init()
|
||||
png_infop info_ptr;
|
||||
png_struct_guard sguard(&png_ptr,&info_ptr);
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) throw image_reader_exception("failed to create info_ptr");
|
||||
if (!info_ptr) throw ImageReaderException("failed to create info_ptr");
|
||||
|
||||
png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data);
|
||||
|
||||
@@ -103,19 +103,19 @@ void png_reader<T>::init()
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned png_reader<T>::width() const
|
||||
unsigned PngReader<T>::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned png_reader<T>::height() const
|
||||
unsigned PngReader<T>::height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void png_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * image)
|
||||
void PngReader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * image)
|
||||
{
|
||||
stream_.clear();
|
||||
stream_.seekg(0, std::ios_base::beg);
|
||||
@@ -125,7 +125,7 @@ void png_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char
|
||||
|
||||
if (!png_ptr)
|
||||
{
|
||||
throw image_reader_exception("failed to allocate png_ptr");
|
||||
throw ImageReaderException("failed to allocate png_ptr");
|
||||
}
|
||||
|
||||
// catch errors in a custom way to avoid the need for setjmp
|
||||
@@ -134,7 +134,7 @@ void png_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char
|
||||
png_infop info_ptr;
|
||||
png_struct_guard sguard(&png_ptr,&info_ptr);
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) throw image_reader_exception("failed to create info_ptr");
|
||||
if (!info_ptr) throw ImageReaderException("failed to create info_ptr");
|
||||
|
||||
png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
@@ -195,6 +195,6 @@ void png_reader<T>::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char
|
||||
png_read_end(png_ptr,0);
|
||||
}
|
||||
|
||||
template class png_reader<boost::iostreams::array_source>;
|
||||
template class PngReader<boost::iostreams::array_source>;
|
||||
|
||||
}}
|
||||
|
||||
@@ -17,10 +17,6 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_)
|
||||
dirty(true) {
|
||||
}
|
||||
|
||||
GlyphAtlas::~GlyphAtlas() {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
Rect<uint16_t> GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_name,
|
||||
const SDFGlyph& glyph)
|
||||
{
|
||||
@@ -74,7 +70,7 @@ Rect<uint16_t> GlyphAtlas::addGlyph_impl(uint64_t tile_id, const std::string& fa
|
||||
face.emplace(glyph.id, GlyphValue { rect, tile_id });
|
||||
|
||||
// Copy the bitmap
|
||||
char *target = data;
|
||||
char *target = data.get();
|
||||
const char *source = glyph.bitmap.data();
|
||||
for (uint32_t y = 0; y < buffered_height; y++) {
|
||||
uint32_t y1 = width * (rect.y + y) + rect.x;
|
||||
@@ -119,7 +115,7 @@ void GlyphAtlas::removeGlyphs(uint64_t tile_id) {
|
||||
const Rect<uint16_t>& rect = value.rect;
|
||||
|
||||
// Clear out the bitmap.
|
||||
char *target = data;
|
||||
char *target = data.get();
|
||||
for (uint32_t y = 0; y < rect.h; y++) {
|
||||
uint32_t y1 = width * (rect.y + y) + rect.x;
|
||||
for (uint32_t x = 0; x < rect.w; x++) {
|
||||
@@ -157,7 +153,7 @@ void GlyphAtlas::bind() {
|
||||
|
||||
if (dirty) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data.get());
|
||||
dirty = false;
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
151
src/map/map.cpp
151
src/map/map.cpp
@@ -92,9 +92,6 @@ using namespace mbgl;
|
||||
Map::Map(View& view_)
|
||||
: loop(std::make_unique<uv::loop>()),
|
||||
thread(std::make_unique<uv::thread>()),
|
||||
async_terminate(new uv_async_t()),
|
||||
async_render(new uv_async_t()),
|
||||
async_cleanup(new uv_async_t()),
|
||||
view(view_),
|
||||
#ifndef NDEBUG
|
||||
main_thread(uv_thread_self()),
|
||||
@@ -118,10 +115,11 @@ Map::~Map() {
|
||||
}
|
||||
|
||||
// Explicitly reset all pointers.
|
||||
texturepool.reset();
|
||||
activeSources.clear();
|
||||
sprite.reset();
|
||||
glyphStore.reset();
|
||||
style.reset();
|
||||
texturepool.reset();
|
||||
fileSource.reset();
|
||||
workers.reset();
|
||||
|
||||
@@ -147,27 +145,46 @@ void Map::start(bool start_paused) {
|
||||
is_stopped = false;
|
||||
|
||||
// Setup async notifications
|
||||
async_terminate = std::make_unique<uv::async>(**loop, [this]() {
|
||||
assert(uv_thread_self() == map_thread);
|
||||
|
||||
// Iron out the differences between libuv 0.10 and 0.11
|
||||
#ifdef UV_ASYNC_CALLBACK
|
||||
#error Cannot overwrite UV_ASYNC_CALLBACK
|
||||
#endif
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
#define UV_ASYNC_CALLBACK(name) [](uv_async_t *a, int) { return Map::name(a); }
|
||||
#else
|
||||
#define UV_ASYNC_CALLBACK(name) name
|
||||
#endif
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
glyphStore.reset();
|
||||
fileSource.reset();
|
||||
style.reset();
|
||||
workers.reset();
|
||||
activeSources.clear();
|
||||
|
||||
uv_async_init(**loop, async_terminate.get(), UV_ASYNC_CALLBACK(terminate));
|
||||
async_terminate->data = this;
|
||||
terminating = true;
|
||||
|
||||
uv_async_init(**loop, async_render.get(), UV_ASYNC_CALLBACK(render));
|
||||
async_render->data = this;
|
||||
// Closes all open handles on the loop. This means that the loop will automatically terminate.
|
||||
async_cleanup.reset();
|
||||
async_render.reset();
|
||||
async_terminate.reset();
|
||||
});
|
||||
|
||||
uv_async_init(**loop, async_cleanup.get(), UV_ASYNC_CALLBACK(cleanup));
|
||||
async_cleanup->data = this;
|
||||
async_render = std::make_unique<uv::async>(**loop, [this]() {
|
||||
assert(uv_thread_self() == map_thread);
|
||||
|
||||
#undef UV_ASYNC_CALLBACK
|
||||
if (state.hasSize()) {
|
||||
if (is_rendered.test_and_set() == false) {
|
||||
prepare();
|
||||
if (is_clean.test_and_set() == false) {
|
||||
render();
|
||||
is_swapped.clear();
|
||||
view.swap();
|
||||
} else {
|
||||
// We set the rendered flag in the test above, so we have to reset it
|
||||
// now that we're not actually rendering because the map is clean.
|
||||
is_rendered.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async_cleanup = std::make_unique<uv::async>(**loop, [this]() {
|
||||
painter.cleanup();
|
||||
});
|
||||
|
||||
// Do we need to pause first?
|
||||
if (start_paused) {
|
||||
@@ -198,7 +215,7 @@ void Map::stop(stop_callback cb, void *data) {
|
||||
assert(main_thread != map_thread);
|
||||
assert(async);
|
||||
|
||||
uv_async_send(async_terminate.get());
|
||||
async_terminate->send();
|
||||
|
||||
resume();
|
||||
|
||||
@@ -315,7 +332,7 @@ void Map::rerender() {
|
||||
// We only send render events if we want to continuously update the map
|
||||
// (== async rendering).
|
||||
if (async) {
|
||||
uv_async_send(async_render.get());
|
||||
async_render->send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,16 +352,10 @@ void Map::swapped() {
|
||||
|
||||
void Map::cleanup() {
|
||||
if (async_cleanup != nullptr) {
|
||||
uv_async_send(async_cleanup.get());
|
||||
async_cleanup->send();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::cleanup(uv_async_t *async) {
|
||||
Map *map = static_cast<Map *>(async->data);
|
||||
|
||||
map->painter.cleanup();
|
||||
}
|
||||
|
||||
void Map::terminate() {
|
||||
painter.terminate();
|
||||
}
|
||||
@@ -360,47 +371,6 @@ void Map::setReachability(bool reachable) {
|
||||
}
|
||||
}
|
||||
|
||||
void Map::render(uv_async_t *async) {
|
||||
Map *map = static_cast<Map *>(async->data);
|
||||
assert(uv_thread_self() == map->map_thread);
|
||||
|
||||
if (map->state.hasSize()) {
|
||||
if (map->is_rendered.test_and_set() == false) {
|
||||
map->prepare();
|
||||
if (map->is_clean.test_and_set() == false) {
|
||||
map->render();
|
||||
map->is_swapped.clear();
|
||||
map->view.swap();
|
||||
} else {
|
||||
// We set the rendered flag in the test above, so we have to reset it
|
||||
// now that we're not actually rendering because the map is clean.
|
||||
map->is_rendered.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Map::terminate(uv_async_t *async) {
|
||||
// Closes all open handles on the loop. This means that the loop will automatically terminate.
|
||||
Map *map = static_cast<Map *>(async->data);
|
||||
assert(uv_thread_self() == map->map_thread);
|
||||
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
map->glyphStore.reset();
|
||||
map->fileSource.reset();
|
||||
map->style.reset();
|
||||
map->workers.reset();
|
||||
map->activeSources.clear();
|
||||
|
||||
map->view.make_inactive();
|
||||
|
||||
map->terminating = true;
|
||||
|
||||
uv_close((uv_handle_t *)map->async_cleanup.get(), nullptr);
|
||||
uv_close((uv_handle_t *)map->async_render.get(), nullptr);
|
||||
uv_close((uv_handle_t *)map->async_terminate.get(), nullptr);
|
||||
}
|
||||
|
||||
#pragma mark - Setup
|
||||
|
||||
void Map::setup() {
|
||||
@@ -479,12 +449,10 @@ util::ptr<Sprite> Map::getSprite() {
|
||||
|
||||
#pragma mark - Size
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::resize(uint16_t width, uint16_t height, float ratio) {
|
||||
resize(width, height, ratio, width * ratio, height * ratio);
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height) {
|
||||
if (transform.resize(width, height, ratio, fb_width, fb_height)) {
|
||||
update();
|
||||
@@ -493,7 +461,6 @@ void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width
|
||||
|
||||
#pragma mark - Transitions
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::cancelTransitions() {
|
||||
transform.cancelTransitions();
|
||||
|
||||
@@ -503,36 +470,30 @@ void Map::cancelTransitions() {
|
||||
|
||||
#pragma mark - Position
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::moveBy(double dx, double dy, double duration) {
|
||||
transform.moveBy(dx, dy, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setLonLat(double lon, double lat, double duration) {
|
||||
transform.setLonLat(lon, lat, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::getLonLat(double& lon, double& lat) const {
|
||||
transform.getLonLat(lon, lat);
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::startPanning() {
|
||||
transform.startPanning();
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::stopPanning() {
|
||||
transform.stopPanning();
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::resetPosition() {
|
||||
transform.setAngle(0);
|
||||
transform.setLonLat(0, 0);
|
||||
@@ -543,57 +504,47 @@ void Map::resetPosition() {
|
||||
|
||||
#pragma mark - Scale
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::scaleBy(double ds, double cx, double cy, double duration) {
|
||||
transform.scaleBy(ds, cx, cy, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setScale(double scale, double cx, double cy, double duration) {
|
||||
transform.setScale(scale, cx, cy, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
double Map::getScale() const {
|
||||
return transform.getScale();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setZoom(double zoom, double duration) {
|
||||
transform.setZoom(zoom, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
double Map::getZoom() const {
|
||||
return transform.getZoom();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setLonLatZoom(double lon, double lat, double zoom, double duration) {
|
||||
transform.setLonLatZoom(lon, lat, zoom, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::getLonLatZoom(double& lon, double& lat, double& zoom) const {
|
||||
transform.getLonLatZoom(lon, lat, zoom);
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::resetZoom() {
|
||||
setZoom(0);
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::startScaling() {
|
||||
transform.startScaling();
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::stopScaling() {
|
||||
transform.stopScaling();
|
||||
update();
|
||||
@@ -610,42 +561,35 @@ double Map::getMaxZoom() const {
|
||||
|
||||
#pragma mark - Rotation
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::rotateBy(double sx, double sy, double ex, double ey, double duration) {
|
||||
transform.rotateBy(sx, sy, ex, ey, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setBearing(double degrees, double duration) {
|
||||
transform.setAngle(-degrees * M_PI / 180, duration * 1_second);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::setBearing(double degrees, double cx, double cy) {
|
||||
transform.setAngle(-degrees * M_PI / 180, cx, cy);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
double Map::getBearing() const {
|
||||
return -transform.getAngle() / M_PI * 180;
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::resetNorth() {
|
||||
transform.setAngle(0, 500_milliseconds);
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::startRotating() {
|
||||
transform.startRotating();
|
||||
update();
|
||||
}
|
||||
|
||||
// Note: This function is called from another thread. Make sure you only call threadsafe functions!
|
||||
void Map::stopRotating() {
|
||||
transform.stopRotating();
|
||||
update();
|
||||
@@ -709,7 +653,7 @@ void Map::updateSources() {
|
||||
assert(uv_thread_self() == map_thread);
|
||||
|
||||
// First, disable all existing sources.
|
||||
for (const util::ptr<StyleSource> &source : activeSources) {
|
||||
for (const auto& source : activeSources) {
|
||||
source->enabled = false;
|
||||
}
|
||||
|
||||
@@ -717,7 +661,7 @@ void Map::updateSources() {
|
||||
updateSources(style->layers);
|
||||
|
||||
// Then, construct or destroy the actual source object, depending on enabled state.
|
||||
for (const util::ptr<StyleSource> &style_source : activeSources) {
|
||||
for (const auto& style_source : activeSources) {
|
||||
if (style_source->enabled) {
|
||||
if (!style_source->source) {
|
||||
style_source->source = std::make_shared<Source>(style_source->info);
|
||||
@@ -734,10 +678,6 @@ void Map::updateSources() {
|
||||
});
|
||||
}
|
||||
|
||||
const std::set<util::ptr<StyleSource>> Map::getActiveSources() const {
|
||||
return activeSources;
|
||||
}
|
||||
|
||||
void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
|
||||
if (!group) {
|
||||
return;
|
||||
@@ -755,8 +695,11 @@ void Map::updateSources(const util::ptr<StyleLayerGroup> &group) {
|
||||
}
|
||||
|
||||
void Map::updateTiles() {
|
||||
for (const util::ptr<StyleSource> &source : getActiveSources()) {
|
||||
source->source->update(*this, *fileSource);
|
||||
for (const auto& source : activeSources) {
|
||||
source->source->update(*this, getWorker(),
|
||||
style, glyphAtlas, *glyphStore,
|
||||
spriteAtlas, getSprite(),
|
||||
*texturepool, *fileSource, [this](){ update(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
using namespace mbgl;
|
||||
|
||||
|
||||
RasterTileData::RasterTileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
|
||||
: TileData(id_, map_, source_),
|
||||
bucket(map.getTexturepool(), properties) {
|
||||
RasterTileData::RasterTileData(Tile::ID const& id_, Texturepool& texturepool, const SourceInfo& source_)
|
||||
: TileData(id_, source_),
|
||||
bucket(texturepool, properties) {
|
||||
}
|
||||
|
||||
RasterTileData::~RasterTileData() {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Source::Source(const util::ptr<SourceInfo>& info_)
|
||||
Source::Source(SourceInfo& info_)
|
||||
: info(info_)
|
||||
{
|
||||
}
|
||||
@@ -31,12 +31,12 @@ Source::Source(const util::ptr<SourceInfo>& info_)
|
||||
// The reason this isn't part of the constructor is that calling shared_from_this() in
|
||||
// the constructor fails.
|
||||
void Source::load(Map& map, FileSource& fileSource) {
|
||||
if (info->url.empty()) {
|
||||
if (info.url.empty()) {
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = util::mapbox::normalizeSourceURL(info->url, map.getAccessToken());
|
||||
std::string url = util::mapbox::normalizeSourceURL(info.url, map.getAccessToken());
|
||||
util::ptr<Source> source = shared_from_this();
|
||||
|
||||
fileSource.request(ResourceType::JSON, url)->onload([source, &map](const Response &res) {
|
||||
@@ -53,7 +53,7 @@ void Source::load(Map& map, FileSource& fileSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
source->info->parseTileJSONProperties(d);
|
||||
source->info.parseTileJSONProperties(d);
|
||||
source->loaded = true;
|
||||
|
||||
map.update();
|
||||
@@ -61,14 +61,6 @@ void Source::load(Map& map, FileSource& fileSource) {
|
||||
});
|
||||
}
|
||||
|
||||
bool Source::update(Map& map, FileSource& fileSource) {
|
||||
if (loaded && map.getTime() > updated) {
|
||||
return updateTiles(map, fileSource);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Source::updateClipIDs(const std::map<Tile::ID, ClipID> &mapping) {
|
||||
std::for_each(tiles.begin(), tiles.end(), [&mapping](std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair) {
|
||||
Tile &tile = *pair.second;
|
||||
@@ -159,7 +151,13 @@ TileData::State Source::hasTile(const Tile::ID& id) {
|
||||
return TileData::State::invalid;
|
||||
}
|
||||
|
||||
TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID& id) {
|
||||
TileData::State Source::addTile(Map& map, uv::worker& worker,
|
||||
util::ptr<Style> style,
|
||||
GlyphAtlas& glyphAtlas, GlyphStore& glyphStore,
|
||||
SpriteAtlas& spriteAtlas, util::ptr<Sprite> sprite,
|
||||
FileSource& fileSource, Texturepool& texturepool,
|
||||
const Tile::ID& id,
|
||||
std::function<void ()> callback) {
|
||||
const TileData::State state = hasTile(id);
|
||||
|
||||
if (state != TileData::State::invalid) {
|
||||
@@ -186,15 +184,18 @@ TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID
|
||||
|
||||
if (!new_tile.data) {
|
||||
// If we don't find working tile data, we're just going to load it.
|
||||
if (info->type == SourceType::Vector) {
|
||||
new_tile.data = std::make_shared<VectorTileData>(normalized_id, map, info);
|
||||
} else if (info->type == SourceType::Raster) {
|
||||
new_tile.data = std::make_shared<RasterTileData>(normalized_id, map, info);
|
||||
if (info.type == SourceType::Vector) {
|
||||
new_tile.data = std::make_shared<VectorTileData>(normalized_id, map.getMaxZoom(), style,
|
||||
glyphAtlas, glyphStore,
|
||||
spriteAtlas, sprite,
|
||||
texturepool, info);
|
||||
} else if (info.type == SourceType::Raster) {
|
||||
new_tile.data = std::make_shared<RasterTileData>(normalized_id, texturepool, info);
|
||||
} else {
|
||||
throw std::runtime_error("source type not implemented");
|
||||
}
|
||||
|
||||
new_tile.data->request(fileSource);
|
||||
new_tile.data->request(worker, fileSource, map.getState().getPixelRatio(), callback);
|
||||
tile_data.emplace(new_tile.data->id, new_tile.data);
|
||||
}
|
||||
|
||||
@@ -202,7 +203,7 @@ TileData::State Source::addTile(Map& map, FileSource& fileSource, const Tile::ID
|
||||
}
|
||||
|
||||
double Source::getZoom(const TransformState& state) const {
|
||||
double offset = std::log(util::tileSize / info->tile_size) / std::log(2);
|
||||
double offset = std::log(util::tileSize / info.tile_size) / std::log(2);
|
||||
offset += (state.getPixelRatio() > 1.0 ? 1 :0);
|
||||
return state.getZoom() + offset;
|
||||
}
|
||||
@@ -214,8 +215,8 @@ int32_t Source::coveringZoomLevel(const TransformState& state) const {
|
||||
std::forward_list<Tile::ID> Source::coveringTiles(const TransformState& state) const {
|
||||
int32_t z = coveringZoomLevel(state);
|
||||
|
||||
if (z < info->min_zoom) return {{}};
|
||||
if (z > info->max_zoom) z = info->max_zoom;
|
||||
if (z < info.min_zoom) return {{}};
|
||||
if (z > info.max_zoom) z = info.max_zoom;
|
||||
|
||||
// Map four viewport corners to pixel coordinates
|
||||
box points = state.cornersToBox(z);
|
||||
@@ -281,15 +282,23 @@ bool Source::findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Source::updateTiles(Map& map, FileSource& fileSource) {
|
||||
void Source::update(Map& map, uv::worker& worker,
|
||||
util::ptr<Style> style,
|
||||
GlyphAtlas& glyphAtlas, GlyphStore& glyphStore,
|
||||
SpriteAtlas& spriteAtlas, util::ptr<Sprite> sprite,
|
||||
Texturepool& texturepool, FileSource& fileSource,
|
||||
std::function<void ()> callback) {
|
||||
if (!loaded || map.getTime() <= updated)
|
||||
return;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
int32_t zoom = std::floor(getZoom(map.getState()));
|
||||
std::forward_list<Tile::ID> required = coveringTiles(map.getState());
|
||||
|
||||
// Determine the overzooming/underzooming amounts.
|
||||
int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info->min_zoom, info->max_zoom);
|
||||
int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info->min_zoom, info->max_zoom);
|
||||
int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info.min_zoom, info.max_zoom);
|
||||
int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info.min_zoom, info.max_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
|
||||
@@ -298,7 +307,11 @@ bool Source::updateTiles(Map& map, FileSource& fileSource) {
|
||||
|
||||
// Add existing child/parent tiles if the actual tile is not yet loaded
|
||||
for (const Tile::ID& id : required) {
|
||||
const TileData::State state = addTile(map, fileSource, id);
|
||||
const TileData::State state = addTile(map, worker, style,
|
||||
glyphAtlas, glyphStore,
|
||||
spriteAtlas, sprite,
|
||||
fileSource, texturepool,
|
||||
id, callback);
|
||||
|
||||
if (state != TileData::State::parsed) {
|
||||
// The tile we require is not yet loaded. Try to find a parent or
|
||||
@@ -351,8 +364,6 @@ bool Source::updateTiles(Map& map, FileSource& fileSource) {
|
||||
});
|
||||
|
||||
updated = map.getTime();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TileData::TileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
|
||||
TileData::TileData(Tile::ID const& id_, const SourceInfo& source_)
|
||||
: id(id_),
|
||||
state(State::initial),
|
||||
map(map_),
|
||||
source(source_),
|
||||
debugBucket(debugFontBuffer) {
|
||||
// Initialize tile debug coordinates
|
||||
@@ -28,16 +27,23 @@ const std::string TileData::toString() const {
|
||||
return util::sprintf<32>("[tile %d/%d/%d]", id.z, id.x, id.y);
|
||||
}
|
||||
|
||||
void TileData::request(FileSource& fileSource) {
|
||||
if (source->tiles.empty())
|
||||
void TileData::request(uv::worker& worker, FileSource& fileSource,
|
||||
float pixelRatio, std::function<void ()> callback) {
|
||||
if (source.tiles.empty())
|
||||
return;
|
||||
|
||||
std::string url = source->tiles[(id.x + id.y) % source->tiles.size()];
|
||||
std::string url = source.tiles[(id.x + id.y) % source.tiles.size()];
|
||||
url = util::replaceTokens(url, [&](const std::string &token) -> std::string {
|
||||
if (token == "z") return std::to_string(id.z);
|
||||
if (token == "x") return std::to_string(id.x);
|
||||
if (token == "y") return std::to_string(id.y);
|
||||
if (token == "ratio") return (map.getState().getPixelRatio() > 1.0 ? "@2x" : "");
|
||||
if (token == "prefix") {
|
||||
std::string prefix { 2 };
|
||||
prefix[0] = "0123456789abcdef"[id.x % 16];
|
||||
prefix[1] = "0123456789abcdef"[id.y % 16];
|
||||
return prefix;
|
||||
}
|
||||
if (token == "ratio") return pixelRatio > 1.0 ? "@2x" : "";
|
||||
return "";
|
||||
});
|
||||
|
||||
@@ -46,7 +52,7 @@ void TileData::request(FileSource& fileSource) {
|
||||
// Note: Somehow this feels slower than the change to request_http()
|
||||
std::weak_ptr<TileData> weak_tile = shared_from_this();
|
||||
req = fileSource.request(ResourceType::Tile, url);
|
||||
req->onload([weak_tile, url](const Response &res) {
|
||||
req->onload([weak_tile, url, callback, &worker](const Response &res) {
|
||||
util::ptr<TileData> tile = weak_tile.lock();
|
||||
if (!tile || tile->state == State::obsolete) {
|
||||
// noop. Tile is obsolete and we're now just waiting for the refcount
|
||||
@@ -63,7 +69,7 @@ void TileData::request(FileSource& fileSource) {
|
||||
tile->data = res.data;
|
||||
|
||||
// Schedule tile parsing in another thread
|
||||
tile->reparse();
|
||||
tile->reparse(worker, callback);
|
||||
} else {
|
||||
#if defined(DEBUG)
|
||||
fprintf(stderr, "[%s] tile loading failed: %ld, %s\n", url.c_str(), res.code, res.message.c_str());
|
||||
@@ -82,17 +88,17 @@ void TileData::cancel() {
|
||||
}
|
||||
}
|
||||
|
||||
void TileData::reparse()
|
||||
void TileData::reparse(uv::worker& worker, std::function<void()> callback)
|
||||
{
|
||||
// We're creating a new work request. The work request deletes itself after it executed
|
||||
// the after work handler
|
||||
new uv::work<util::ptr<TileData>>(
|
||||
map.getWorker(),
|
||||
[](util::ptr<TileData> &tile) {
|
||||
worker,
|
||||
[](util::ptr<TileData>& tile) {
|
||||
tile->parse();
|
||||
},
|
||||
[](util::ptr<TileData> &tile) {
|
||||
tile->map.update();
|
||||
[callback](util::ptr<TileData>&) {
|
||||
callback();
|
||||
},
|
||||
shared_from_this());
|
||||
}
|
||||
|
||||
@@ -32,9 +32,10 @@ TileParser::~TileParser() = default;
|
||||
TileParser::TileParser(const std::string &data, VectorTileData &tile_,
|
||||
const util::ptr<const Style> &style_,
|
||||
GlyphAtlas & glyphAtlas_,
|
||||
const util::ptr<GlyphStore> &glyphStore_,
|
||||
GlyphStore & glyphStore_,
|
||||
SpriteAtlas & spriteAtlas_,
|
||||
const util::ptr<Sprite> &sprite_)
|
||||
const util::ptr<Sprite> &sprite_,
|
||||
Texturepool& texturePool_)
|
||||
: vector_data(pbf((const uint8_t *)data.data(), data.size())),
|
||||
tile(tile_),
|
||||
style(style_),
|
||||
@@ -42,10 +43,10 @@ TileParser::TileParser(const std::string &data, VectorTileData &tile_,
|
||||
glyphStore(glyphStore_),
|
||||
spriteAtlas(spriteAtlas_),
|
||||
sprite(sprite_),
|
||||
collision(std::make_unique<Collision>(tile.id.z, 4096, tile.source->tile_size, tile.depth)) {
|
||||
texturePool(texturePool_),
|
||||
collision(std::make_unique<Collision>(tile.id.z, 4096, tile.source.tile_size, tile.depth)) {
|
||||
assert(&tile != nullptr);
|
||||
assert(style);
|
||||
assert(glyphStore);
|
||||
assert(sprite);
|
||||
assert(collision);
|
||||
}
|
||||
@@ -100,7 +101,7 @@ std::unique_ptr<Bucket> TileParser::createBucket(util::ptr<StyleBucket> bucket_d
|
||||
}
|
||||
|
||||
// Skip this bucket if we are to not render this
|
||||
if (tile.id.z < std::floor(bucket_desc->min_zoom) && std::floor(bucket_desc->min_zoom) < tile.source->max_zoom) return nullptr;
|
||||
if (tile.id.z < std::floor(bucket_desc->min_zoom) && std::floor(bucket_desc->min_zoom) < tile.source.max_zoom) return nullptr;
|
||||
if (tile.id.z >= std::ceil(bucket_desc->max_zoom)) return nullptr;
|
||||
|
||||
auto layer_it = vector_data.layers.find(bucket_desc->source_layer);
|
||||
@@ -154,7 +155,7 @@ std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& laye
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createRasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster &raster) {
|
||||
std::unique_ptr<Bucket> TileParser::createRasterBucket(Texturepool& texturepool, const StyleBucketRaster &raster) {
|
||||
std::unique_ptr<RasterBucket> bucket = std::make_unique<RasterBucket>(texturepool, raster);
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
@@ -167,7 +168,7 @@ std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& laye
|
||||
|
||||
std::unique_ptr<Bucket> TileParser::createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol) {
|
||||
std::unique_ptr<SymbolBucket> bucket = std::make_unique<SymbolBucket>(symbol, *collision);
|
||||
bucket->addFeatures(layer, filter, tile.id, spriteAtlas, *sprite, glyphAtlas, *glyphStore);
|
||||
bucket->addFeatures(layer, filter, tile.id, spriteAtlas, *sprite, glyphAtlas, glyphStore);
|
||||
return obsolete() ? nullptr : std::move(bucket);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,24 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
VectorTileData::VectorTileData(Tile::ID const& id_, Map &map_, const util::ptr<SourceInfo> &source_)
|
||||
: TileData(id_, map_, source_),
|
||||
depth(id.z >= source->max_zoom ? map.getMaxZoom() - id.z : 1) {
|
||||
VectorTileData::VectorTileData(Tile::ID const& id_,
|
||||
float mapMaxZoom, util::ptr<Style> style_,
|
||||
GlyphAtlas& glyphAtlas_, GlyphStore& glyphStore_,
|
||||
SpriteAtlas& spriteAtlas_, util::ptr<Sprite> sprite_,
|
||||
Texturepool& texturepool_,
|
||||
const SourceInfo& source_)
|
||||
: TileData(id_, source_),
|
||||
glyphAtlas(glyphAtlas_),
|
||||
glyphStore(glyphStore_),
|
||||
spriteAtlas(spriteAtlas_),
|
||||
sprite(sprite_),
|
||||
texturepool(texturepool_),
|
||||
style(style_),
|
||||
depth(id.z >= source.max_zoom ? mapMaxZoom - id.z : 1) {
|
||||
}
|
||||
|
||||
VectorTileData::~VectorTileData() {
|
||||
map.getGlyphAtlas().removeGlyphs(id.to_uint64());
|
||||
glyphAtlas.removeGlyphs(id.to_uint64());
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +38,10 @@ void VectorTileData::parse() {
|
||||
// Parsing creates state that is encapsulated in TileParser. While parsing,
|
||||
// the TileParser object writes results into this objects. All other state
|
||||
// is going to be discarded afterwards.
|
||||
TileParser parser(data, *this, map.getStyle(), map.getGlyphAtlas(),
|
||||
map.getGlyphStore(), map.getSpriteAtlas(), map.getSprite());
|
||||
TileParser parser(data, *this, style,
|
||||
glyphAtlas, glyphStore,
|
||||
spriteAtlas, sprite,
|
||||
texturepool);
|
||||
parser.parse();
|
||||
} catch (const std::exception& ex) {
|
||||
#if defined(DEBUG)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
RasterBucket::RasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster& properties_)
|
||||
RasterBucket::RasterBucket(Texturepool& texturepool, const StyleBucketRaster& properties_)
|
||||
: properties(properties_),
|
||||
texture(properties_),
|
||||
raster(texturepool) {
|
||||
|
||||
@@ -178,14 +178,12 @@ void StyleParser::parseSources(JSVal value) {
|
||||
rapidjson::Value::ConstMemberIterator itr = value.MemberBegin();
|
||||
for (; itr != value.MemberEnd(); ++itr) {
|
||||
std::string name { itr->name.GetString(), itr->name.GetStringLength() };
|
||||
util::ptr<SourceInfo> info = std::make_shared<SourceInfo>();
|
||||
SourceInfo& info = sources.emplace(name, std::make_shared<StyleSource>()).first->second->info;
|
||||
|
||||
parseRenderProperty<SourceTypeClass>(itr->value, info->type, "type");
|
||||
parseRenderProperty(itr->value, info->url, "url");
|
||||
parseRenderProperty(itr->value, info->tile_size, "tileSize");
|
||||
info->parseTileJSONProperties(itr->value);
|
||||
|
||||
sources.emplace(std::move(name), std::make_shared<StyleSource>(info));
|
||||
parseRenderProperty<SourceTypeClass>(itr->value, info.type, "type");
|
||||
parseRenderProperty(itr->value, info.url, "url");
|
||||
parseRenderProperty(itr->value, info.tile_size, "tileSize");
|
||||
info.parseTileJSONProperties(itr->value);
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::ParseStyle, "sources must be an object");
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
Raster::Raster(const util::ptr<Texturepool> &texturepool_)
|
||||
Raster::Raster(Texturepool& texturepool_)
|
||||
: texturepool(texturepool_)
|
||||
{}
|
||||
|
||||
Raster::~Raster() {
|
||||
if (textured) {
|
||||
texturepool->removeTextureID(texture);
|
||||
texturepool.removeTextureID(texture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ void Raster::bind(bool linear) {
|
||||
}
|
||||
|
||||
if (img && !textured) {
|
||||
texture = texturepool->getTextureID();
|
||||
texture = texturepool.getTextureID();
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
@@ -22,16 +22,4 @@ std::string cwd() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void deleter::operator()(uv_async_t *async) {
|
||||
uv_close((uv_handle_t *)async, [](uv_handle_t *handle) {
|
||||
delete (uv_async_t *)handle;
|
||||
});
|
||||
}
|
||||
|
||||
void deleter::operator()(uv_timer_t *timer) {
|
||||
uv_close((uv_handle_t *)timer, [](uv_handle_t *handle) {
|
||||
delete (uv_timer_t *)handle;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user