Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

TileData + Worker refactor #1691

Merged
merged 20 commits into from
Jul 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/mbgl/storage/file_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace mbgl {

struct Resource;
class Response;
class WorkRequest;

class FileCache : private util::noncopyable {
public:
Expand All @@ -18,7 +19,7 @@ class FileCache : private util::noncopyable {
enum class Hint : uint8_t { Full, Refresh, No };
using Callback = std::function<void(std::unique_ptr<Response>)>;

virtual void get(const Resource &resource, Callback callback) = 0;
virtual std::unique_ptr<WorkRequest> get(const Resource &resource, Callback callback) = 0;
virtual void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) = 0;
};

Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/storage/sqlite_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SQLiteCache : public FileCache {
~SQLiteCache() override;

// FileCache API
void get(const Resource &resource, Callback callback) override;
std::unique_ptr<WorkRequest> get(const Resource &resource, Callback callback) override;
void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) override;

class Impl;
Expand Down
12 changes: 6 additions & 6 deletions platform/default/sqlite_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,15 @@ void SQLiteCache::Impl::createSchema() {
}
}

void SQLiteCache::get(const Resource &resource, Callback callback) {
std::unique_ptr<WorkRequest> SQLiteCache::get(const Resource &resource, Callback callback) {
// Can be called from any thread, but most likely from the file source thread.
// Will try to load the URL from the SQLite database and call the callback when done.
// Note that the callback is probably going to invoked from another thread, so the caller
// must make sure that it can run in that thread.
thread->invokeWithResult(&Impl::get, std::move(callback), resource);
return thread->invokeWithCallback(&Impl::get, callback, resource);
}

std::unique_ptr<Response> SQLiteCache::Impl::get(const Resource &resource) {
void SQLiteCache::Impl::get(const Resource &resource, Callback callback) {
try {
// This is called in the SQLite event loop.
if (!db) {
Expand Down Expand Up @@ -167,14 +167,14 @@ std::unique_ptr<Response> SQLiteCache::Impl::get(const Resource &resource) {
if (getStmt->get<int>(5)) { // == compressed
response->data = util::decompress(response->data);
}
return std::move(response);
callback(std::move(response));
} else {
// There is no data.
return nullptr;
callback(nullptr);
}
} catch (mapbox::sqlite::Exception& ex) {
Log::Error(Event::Database, ex.code, ex.what());
return nullptr;
callback(nullptr);
}
}

Expand Down
2 changes: 1 addition & 1 deletion platform/default/sqlite_cache_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SQLiteCache::Impl {
Impl(uv_loop_t*, const std::string &path = ":memory:");
~Impl();

std::unique_ptr<Response> get(const Resource&);
void get(const Resource&, Callback);
void put(const Resource& resource, std::shared_ptr<const Response> response);
void refresh(const Resource& resource, int64_t expires);

Expand Down
65 changes: 32 additions & 33 deletions src/mbgl/map/live_tile_data.cpp
Original file line number Diff line number Diff line change
@@ -1,59 +1,58 @@
#include <mbgl/map/annotation.hpp>
#include <mbgl/map/live_tile_data.hpp>
#include <mbgl/map/live_tile.hpp>
#include <mbgl/map/tile_parser.hpp>
#include <mbgl/map/source.hpp>
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_request.hpp>

#include <sstream>

using namespace mbgl;

LiveTileData::LiveTileData(const TileID& id_,
AnnotationManager& annotationManager_,
const std::vector<util::ptr<StyleLayer>>& layers_,
Worker& workers_,
GlyphAtlas& glyphAtlas_,
GlyphStore& glyphStore_,
SpriteAtlas& spriteAtlas_,
util::ptr<Sprite> sprite_,
Style& style_,
const SourceInfo& source_,
float angle_,
bool collisionDebug_)
: VectorTileData::VectorTileData(id_, layers_, workers_, glyphAtlas_, glyphStore_,
spriteAtlas_, sprite_, source_, angle_, collisionDebug_),
: VectorTileData(id_, style_, source_, angle_, collisionDebug_),
annotationManager(annotationManager_) {
// live features are always ready
setState(State::loaded);
// live features are always loaded
state = State::loaded;
}

LiveTileData::~LiveTileData() {
// Cancel in most derived class destructor so that worker tasks are joined before
// any member data goes away.
cancel();
}

void LiveTileData::parse() {
if (getState() != State::loaded) {
return;
bool LiveTileData::reparse(std::function<void()> callback) {
if (parsing || (state != State::loaded && state != State::partial)) {
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we store this as a dirty flag so we know that we weren't able to start parsing and have to try again some time later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand partial parsing yet but I assume this is handled by the return value here and the code in Style::handlePartialTile.

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments are very helpful. Any reason to remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My eventual plan was to have a flat hierarchy, with LiveTileData not inheriting from VectorTileData, so that (among other things) this would become moot. If we end up not doing that I'll add the comments back.


const LiveTile* tile = annotationManager.getTile(id);
if (!tile) {
state = State::parsed;
return true;
}

parsing = true;

if (tile) {
try {
// 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(*tile, *this, layers, glyphAtlas, glyphStore, spriteAtlas, sprite);
parser.parse();
} catch (const std::exception& ex) {
Log::Error(Event::ParseTile, "Live-parsing [%d/%d/%d] failed: %s", id.z, id.x, id.y, ex.what());
setState(State::obsolete);
workRequest = worker.parseLiveTile(tileWorker, *tile, [this, callback] (TileParseResult result) {
parsing = false;

if (state == State::obsolete) {
return;
}
}

if (getState() != State::obsolete) {
setState(State::parsed);
}
if (result.is<State>()) {
state = result.get<State>();
} else {
error = result.get<std::string>();
state = State::obsolete;
}

callback();
});

return true;
}
9 changes: 2 additions & 7 deletions src/mbgl/map/live_tile_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,13 @@ class LiveTileData : public VectorTileData {
public:
LiveTileData(const TileID&,
AnnotationManager&,
const std::vector<util::ptr<StyleLayer>>&,
Worker&,
GlyphAtlas&,
GlyphStore&,
SpriteAtlas&,
util::ptr<Sprite>,
Style&,
const SourceInfo&,
float angle_,
bool collisionDebug_);
~LiveTileData();

void parse() override;
bool reparse(std::function<void ()> callback) override;

private:
AnnotationManager& annotationManager;
Expand Down
80 changes: 65 additions & 15 deletions src/mbgl/map/raster_tile_data.cpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,81 @@
#include <mbgl/map/raster_tile_data.hpp>
#include <mbgl/style/style.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>

#include <sstream>

using namespace mbgl;

RasterTileData::RasterTileData(const TileID& id_, TexturePool &texturePool,
const SourceInfo &source_)
: TileData(id_, source_), bucket(texturePool, layout) {
RasterTileData::RasterTileData(const TileID& id_,
TexturePool &texturePool,
const SourceInfo &source_,
Worker& worker_)
: TileData(id_),
source(source_),
worker(worker_),
bucket(texturePool, layout) {
}

RasterTileData::~RasterTileData() {
// Cancel in most derived class destructor so that worker tasks are joined before
// any member data goes away.
cancel();
}

void RasterTileData::parse() {
if (getState() != State::loaded) {
return;
}
void RasterTileData::request(float pixelRatio,
const std::function<void()>& callback) {
std::string url = source.tileURL(id, pixelRatio);
state = State::loading;

if (bucket.setImage(data)) {
setState(State::parsed);
} else {
setState(State::invalid);
}
FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Tile, url }, util::RunLoop::current.get()->get(), [url, callback, this](const Response &res) {
req = nullptr;

if (res.status != Response::Successful) {
std::stringstream message;
message << "Failed to load [" << url << "]: " << res.message;
error = message.str();
state = State::obsolete;
callback();
return;
}

state = State::loaded;

workRequest = worker.parseRasterTile(bucket, res.data, [this, callback] (bool result) {
if (state != State::loaded) {
return;
}

if (result) {
state = State::parsed;
} else {
state = State::invalid;
}

callback();
});
});
}

bool RasterTileData::reparse(std::function<void()>) {
assert(false);
return false;
}

Bucket* RasterTileData::getBucket(StyleLayer const&) {
return &bucket;
}

void RasterTileData::cancel() {
if (state != State::obsolete) {
state = State::obsolete;
}
if (req) {
util::ThreadContext::getFileSource()->cancel(req);
req = nullptr;
}
workRequest.reset();
}
23 changes: 17 additions & 6 deletions src/mbgl/map/raster_tile_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,35 @@

namespace mbgl {

class Painter;
class SourceInfo;
class Request;
class StyleLayer;
class TexturePool;
class WorkRequest;

class RasterTileData : public TileData {
friend class TileParser;

public:
RasterTileData(const TileID&, TexturePool&, const SourceInfo&);
RasterTileData(const TileID&, TexturePool&, const SourceInfo&, Worker&);
~RasterTileData();

void parse() override;
void request(float pixelRatio,
const std::function<void()>& callback) override;

bool reparse(std::function<void ()> callback) override;

void cancel() override;

Bucket* getBucket(StyleLayer const &layer_desc) override;

protected:
private:
const SourceInfo& source;
Worker& worker;
Request* req = nullptr;

StyleLayoutRaster layout;
RasterBucket bucket;

std::unique_ptr<WorkRequest> workRequest;
};

}
Expand Down
Loading