Push TileMembers members down hierarchy

This commit is contained in:
John Firebaugh
2015-06-04 17:22:47 -07:00
parent 29a2cd908f
commit 217c376291
6 changed files with 131 additions and 138 deletions

View File

@@ -10,14 +10,15 @@
using namespace mbgl;
RasterTileData::RasterTileData(const TileID& id_, TexturePool &texturePool,
RasterTileData::RasterTileData(const TileID& id_,
TexturePool &texturePool,
const SourceInfo &source_)
: TileData(id_, source_), bucket(texturePool, layout) {
: TileData(id_),
source(source_),
bucket(texturePool, layout) {
}
RasterTileData::~RasterTileData() {
// Cancel in most derived class destructor so that worker tasks are joined before
// any member data goes away.
cancel();
}
@@ -34,7 +35,8 @@ void RasterTileData::request(Worker& worker,
if (res.status != Response::Successful) {
std::stringstream message;
message << "Failed to load [" << url << "]: " << res.message;
setError(message.str());
error = message.str();
state = State::obsolete;
callback();
return;
}
@@ -42,32 +44,36 @@ void RasterTileData::request(Worker& worker,
state = State::loaded;
data = res.data;
// Schedule tile parsing in another thread
reparse(worker, callback);
workRequest = worker.send([this] {
if (getState() != State::loaded) {
return;
}
if (bucket.setImage(data)) {
state = State::parsed;
} else {
state = State::invalid;
}
}, callback);
});
}
bool RasterTileData::reparse(Worker& worker, std::function<void()> callback) {
if (!mayStartParsing()) {
return false;
}
workRequest = worker.send([this] { parse(); endParsing(); }, callback);
return true;
}
void RasterTileData::parse() {
if (getState() != State::loaded) {
return;
}
if (bucket.setImage(data)) {
setState(State::parsed);
} else {
setState(State::invalid);
}
bool RasterTileData::reparse(Worker&, 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();
}

View File

@@ -7,10 +7,11 @@
namespace mbgl {
class Painter;
class SourceInfo;
class Request;
class StyleLayer;
class TexturePool;
class WorkRequest;
class RasterTileData : public TileData {
public:
@@ -23,12 +24,20 @@ public:
bool reparse(Worker&, std::function<void ()> callback) override;
void parse();
void cancel() override;
Bucket* getBucket(StyleLayer const &layer_desc) override;
protected:
private:
const SourceInfo& source;
Request *req = nullptr;
std::string data;
StyleLayoutRaster layout;
RasterBucket bucket;
std::unique_ptr<WorkRequest> workRequest;
};
}

View File

@@ -1,53 +1,11 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/work_request.hpp>
using namespace mbgl;
TileData::TileData(const TileID& id_, const SourceInfo& source_)
TileData::TileData(const TileID& id_)
: id(id_),
name(id),
source(source_),
state(State::initial),
debugBucket(debugFontBuffer) {
debugBucket(debugFontBuffer),
state(State::initial) {
// Initialize tile debug coordinates
debugFontBuffer.addText(name.c_str(), 50, 200, 5);
}
TileData::~TileData() {
cancel();
}
const std::string TileData::toString() const {
return std::string { "[tile " } + name + "]";
}
void TileData::setState(const State& state_) {
assert(!isImmutable());
state = state_;
}
void TileData::cancel() {
if (state != State::obsolete) {
state = State::obsolete;
}
if (req) {
util::ThreadContext::getFileSource()->cancel(req);
req = nullptr;
}
workRequest.reset();
}
bool TileData::mayStartParsing() {
return !parsing.test_and_set(std::memory_order_acquire);
}
void TileData::endParsing() {
parsing.clear(std::memory_order_release);
}
void TileData::setError(const std::string& message) {
error = message;
setState(State::obsolete);
debugFontBuffer.addText(std::string(id).c_str(), 50, 200, 5);
}

View File

@@ -1,26 +1,19 @@
#ifndef MBGL_MAP_TILE_DATA
#define MBGL_MAP_TILE_DATA
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/map/tile_id.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/geometry/debug_font_buffer.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <atomic>
#include <string>
#include <functional>
namespace mbgl {
class Painter;
class SourceInfo;
class StyleLayer;
class Request;
class Worker;
class WorkRequest;
class TransformState;
class TileData : private util::noncopyable {
public:
@@ -74,8 +67,8 @@ public:
return state == State::partial || state == State::parsed;
}
TileData(const TileID&, const SourceInfo&);
~TileData();
TileData(const TileID&);
virtual ~TileData() = default;
virtual void request(Worker&,
float pixelRatio,
@@ -88,72 +81,34 @@ public:
virtual bool reparse(Worker&,
std::function<void ()> callback) = 0;
void cancel();
const std::string toString() const;
// Mark this tile as no longer needed and cancel any pending work.
virtual void cancel() = 0;
inline bool isReady() const {
virtual Bucket* getBucket(const StyleLayer&) = 0;
virtual void redoPlacement(float, bool) {}
bool isReady() const {
return isReadyState(state);
}
// Returns true if the TileData is in a final state and we cannot
// make changes to it anymore.
inline bool isImmutable() const {
return state == State::parsed || state == State::obsolete;
}
// We let subclasses override setState() so they
// can intercept the state change and react accordingly.
virtual void setState(const State& state);
inline State getState() const {
State getState() const {
return state;
}
void endParsing();
// Error message to be set in case of request
// and parsing errors.
void setError(const std::string& message);
std::string getError() const {
return error;
}
// Override this in the child class.
virtual Bucket* getBucket(StyleLayer const &layer_desc) = 0;
virtual void redoPlacement(float, bool) {}
const TileID id;
const std::string name;
std::atomic_flag parsing = ATOMIC_FLAG_INIT;
protected:
// Set the internal parsing state to true so we prevent
// multiple workers to parse the same tile in parallel,
// which can happen if the tile is in the "partial" state.
// It will return true if is possible to start pasing the
// tile or false if not (so some other worker is already
// parsing the tile).
bool mayStartParsing();
const SourceInfo& source;
Request *req = nullptr;
std::string data;
std::unique_ptr<WorkRequest> workRequest;
std::atomic<State> state;
private:
std::string error;
protected:
// Contains the tile ID string for painting debug information.
DebugBucket debugBucket;
DebugFontBuffer debugFontBuffer;
public:
DebugBucket debugBucket;
protected:
std::atomic<State> state;
std::string error;
};
}

View File

@@ -19,7 +19,8 @@ VectorTileData::VectorTileData(const TileID& id_,
const SourceInfo& source_,
float angle,
bool collisionDebug)
: TileData(id_, source_),
: TileData(id_),
source(source_),
worker(style_.workers),
workerData(id_,
style_,
@@ -111,7 +112,9 @@ size_t VectorTileData::countBuckets() const {
}
void VectorTileData::setState(const State& state_) {
TileData::setState(state_);
assert(!isImmutable());
state = state_;
if (isImmutable()) {
workerData.collision->reset(0, 0);
@@ -148,3 +151,27 @@ void VectorTileData::endRedoPlacement() {
redoingPlacement = false;
redoPlacement();
}
void VectorTileData::cancel() {
if (state != State::obsolete) {
state = State::obsolete;
}
if (req) {
util::ThreadContext::getFileSource()->cancel(req);
req = nullptr;
}
workRequest.reset();
}
bool VectorTileData::mayStartParsing() {
return !parsing.test_and_set(std::memory_order_acquire);
}
void VectorTileData::endParsing() {
parsing.clear(std::memory_order_release);
}
void VectorTileData::setError(const std::string& message) {
error = message;
setState(State::obsolete);
}

View File

@@ -4,12 +4,17 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/map/tile_worker.hpp>
#include <atomic>
namespace mbgl {
class SourceInfo;
class Request;
class Bucket;
class SourceInfo;
class StyleLayer;
class Style;
class WorkRequest;
class VectorTileData : public TileData {
public:
@@ -21,7 +26,6 @@ public:
~VectorTileData();
void redoPlacement(float angle, bool collisionDebug) override;
void setState(const State& state) override;
Bucket* getBucket(const StyleLayer&) override;
size_t countBuckets() const;
@@ -32,13 +36,47 @@ public:
bool reparse(Worker&, std::function<void ()> callback) override;
void cancel() override;
protected:
// We let subclasses override setState() so they
// can intercept the state change and react accordingly.
void setState(const State&);
// Set the internal parsing state to true so we prevent
// multiple workers to parse the same tile in parallel,
// which can happen if the tile is in the "partial" state.
// It will return true if is possible to start pasing the
// tile or false if not (so some other worker is already
// parsing the tile).
bool mayStartParsing();
void endParsing();
// Error message to be set in case of request
// and parsing errors.
void setError(const std::string& message);
void redoPlacement();
const SourceInfo& source;
Request *req = nullptr;
std::string data;
Worker& worker;
TileWorker workerData;
std::unique_ptr<WorkRequest> workRequest;
std::atomic_flag parsing = ATOMIC_FLAG_INIT;
private:
// Returns true if the TileData is in a final state and we cannot
// make changes to it anymore.
inline bool isImmutable() const {
return state == State::parsed || state == State::obsolete;
}
float lastAngle = 0;
float currentAngle;
bool lastCollisionDebug = 0;