From 1fbaa95b026c2e56c713be689a68e4cddb629308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 5 Mar 2014 16:24:10 +0100 Subject: [PATCH] fix tile loading --- src/map/map.cpp | 19 ++++++++++++++++--- src/map/tile_data.cpp | 13 ++++++++----- src/renderer/painter.cpp | 4 ++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/map/map.cpp b/src/map/map.cpp index a57396280..48b7a844e 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -381,10 +381,13 @@ bool Map::updateTiles() { // Remove tiles that we definitely don't need, i.e. tiles that are not on // the required list. - tiles.remove_if([&retain, &changed](const Tile & tile) { + std::forward_list retain_data; + tiles.remove_if([&retain, &retain_data, &changed](const Tile & tile) { bool obsolete = std::find(retain.begin(), retain.end(), tile.id) == retain.end(); if (obsolete) { changed = true; + } else { + retain_data.push_front(tile.data->id); } return obsolete; }); @@ -397,8 +400,18 @@ bool Map::updateTiles() { }); // Remove all the expired pointers from the list. - tile_data.remove_if([](const std::weak_ptr& tile_data) { - return tile_data.expired(); + tile_data.remove_if([&retain_data](const std::weak_ptr& tile_data) { + const std::shared_ptr tile = tile_data.lock(); + if (!tile) { + return true; + } + bool obsolete = std::find(retain_data.begin(), retain_data.end(), tile->id) == retain_data.end(); + if (obsolete) { + tile->cancel(); + return true; + } else { + return false; + } }); return changed; diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index aadb60785..d62b323db 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -34,6 +34,7 @@ TileData::TileData(Tile::ID id, const Style& style) } TileData::~TileData() { + cancel(); } const std::string TileData::toString() const { @@ -48,13 +49,17 @@ void TileData::request() { id.z, id.x, id.y); // Note: Somehow this feels slower than the change to request_http() - std::shared_ptr tile = shared_from_this(); + std::weak_ptr weak_tile = shared_from_this(); platform::Request *request = platform::request_http(url, [=](platform::Response& res) { - if (res.code == 200 && tile->state != State::obsolete) { + std::shared_ptr tile = weak_tile.lock(); + if (!tile || tile->state == State::obsolete) { + // noop. Tile is obsolete and we're now just waiting for the refcount + // to drop to zero for destruction. + } else if (res.code == 200) { tile->state = State::loaded; tile->data.swap(res.body); tile->parse(); - } else if (tile->state != State::obsolete) { + } else { fprintf(stderr, "tile loading failed\n"); } }, []() { @@ -67,8 +72,6 @@ void TileData::cancel() { if (state != State::obsolete) { state = State::obsolete; platform::cancel_request_http(req); - } else { - assert((!"logic error? multiple cancelleations")); } } diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 8b4ff0777..d521d22b5 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -40,7 +40,7 @@ void Painter::setup() { // Blending // We are blending the new pixels *behind* the existing pixels. That way we can - // draw front-to-back and use then stencil buffer to cull opaque pixels early. + // draw front-to-back and use the depth buffer to cull opaque pixels early. glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); @@ -126,7 +126,7 @@ void Painter::finishClippingMask() { void Painter::clear() { glStencilMask(0xFF); depthMask(true); - // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }