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

Commit

Permalink
[core] generate masks for raster tiles to avoid painting over children
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Jul 11, 2017
1 parent f3815fd commit 23cfe73
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 20 deletions.
2 changes: 2 additions & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/style_diff.cpp
src/mbgl/renderer/style_diff.hpp
src/mbgl/renderer/tile_mask.hpp
src/mbgl/renderer/tile_mask_repository.cpp
src/mbgl/renderer/tile_mask_repository.hpp
src/mbgl/renderer/tile_parameters.hpp
src/mbgl/renderer/tile_pyramid.cpp
src/mbgl/renderer/tile_pyramid.hpp
Expand Down
1 change: 1 addition & 0 deletions cmake/test-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ set(MBGL_TEST_FILES
# renderer
test/renderer/group_by_layout.test.cpp
test/renderer/image_manager.test.cpp
test/renderer/tile_mask_repository.test.cpp

# sprite
test/sprite/sprite_loader.test.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/buckets/raster_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void RasterBucket::render(Painter& painter,
const RenderLayer& layer,
const RenderTile& tile) {
painter.renderRaster(parameters, *this, *layer.as<RenderRasterLayer>(), tile.matrix,
painter.rasterDrawable);
painter.tileMaskRepository.getDrawable(painter.context, tile.mask));
}

void RasterBucket::render(Painter& painter,
Expand Down
22 changes: 5 additions & 17 deletions src/mbgl/renderer/painter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,6 @@ namespace mbgl {

using namespace style;

static auto rasterPrimitives() {
IndexedPrimitives<gl::Triangles, RasterLayoutVertex, RasterAttributes> primitives;
primitives.add(
{
RasterProgram::layoutVertex({ 0, 0 }, { 0, 0 }),
RasterProgram::layoutVertex({ util::EXTENT, 0 }, { 32767, 0 }),
RasterProgram::layoutVertex({ 0, util::EXTENT }, { 0, 32767 }),
RasterProgram::layoutVertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }),
}, {
{{ 0, 1, 2 }},
{{ 1, 2, 3 }},
}
);
return primitives;
}

static auto borderPrimitives() {
IndexedPrimitives<gl::LineStrip, DebugLayoutVertex, DebugAttributes> primitives;
primitives.add(
Expand Down Expand Up @@ -116,7 +100,6 @@ Painter::Painter(gl::Context& context_,
const optional<std::string>& programCacheDir)
: context(context_),
state(state_),
rasterDrawable(context, rasterPrimitives()),
fillDrawable(context, fillPrimitives()),
borderDrawable(context, borderPrimitives()),
extrusionTextureDrawable(context, extrusionTexturePrimitives()) {
Expand Down Expand Up @@ -177,6 +160,8 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) {
frameHistory.record(frame.timePoint, state.getZoom(),
frame.mapMode == MapMode::Continuous ? util::DEFAULT_TRANSITION_DURATION : Milliseconds(0));

// Marks all tile masks as stale so that unused masks can be deleted later on.
tileMaskRepository.mark();

// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
Expand Down Expand Up @@ -273,6 +258,9 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) {
{
MBGL_DEBUG_GROUP(context, "cleanup");

// Deletes all tile masks that were unused during this frame.
tileMaskRepository.sweep();

context.activeTexture = 1;
context.texture[1] = 0;
context.activeTexture = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/painter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/render_light.hpp>
#include <mbgl/renderer/drawable.hpp>
#include <mbgl/renderer/tile_mask_repository.hpp>

#include <mbgl/gl/context.hpp>
#include <mbgl/programs/debug_program.hpp>
Expand Down Expand Up @@ -168,7 +169,7 @@ class Painter : private util::noncopyable {
std::unique_ptr<Programs> overdrawPrograms;
#endif

const Drawable<gl::Triangles, RasterLayoutVertex, RasterAttributes> rasterDrawable;
TileMaskRepository tileMaskRepository;
const Drawable<gl::Triangles, FillLayoutVertex, FillAttributes> fillDrawable;
const Drawable<gl::LineStrip, DebugLayoutVertex, DebugAttributes> borderDrawable;
const Drawable<gl::Triangles, ExtrusionTextureLayoutVertex, ExtrusionTextureAttributes> extrusionTextureDrawable;
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/renderer/render_tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/clip_id.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/renderer/tile_mask.hpp>

#include <array>

Expand All @@ -24,6 +25,7 @@ class RenderTile final {
const UnwrappedTileID id;
Tile& tile;
ClipID clip;
TileMask mask;
mat4 matrix;
mat4 nearClippedMatrix;
bool used = false;
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/renderer/sources/render_raster_source.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <mbgl/renderer/sources/render_raster_source.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/tile/raster_tile.hpp>
#include <mbgl/algorithm/update_tile_masks.hpp>

namespace mbgl {

Expand Down Expand Up @@ -57,6 +58,7 @@ void RenderRasterSource::update(Immutable<style::Source::Impl> baseImpl_,
}

void RenderRasterSource::startRender(Painter& painter) {
algorithm::updateTileMasks(tilePyramid.getRenderTiles());
tilePyramid.startRender(painter);
}

Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/renderer/tile_mask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace mbgl {

// A TileMask is a set of TileIDs that describe what part of a tile should be rendered. I.e. it
// denotes the part of a tile that is covered by other/better tiles. If the entire tile should be
// rendered, it contains the { 0, 0, 0 } tile. If it's empty, no part of the tile will be rendered.
// TileMasks are typically generated with algorithm::updateTileMasks().
using TileMask = std::set<CanonicalTileID>;

} // namespace mbgl
76 changes: 76 additions & 0 deletions src/mbgl/renderer/tile_mask_repository.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <mbgl/renderer/tile_mask_repository.hpp>
#include <mbgl/util/constants.hpp>

namespace mbgl {

void TileMaskRepository::mark() {
// Mark all drawables as stale.
for (auto& pair : drawables) {
pair.second.stale = true;
}
}

void TileMaskRepository::sweep() {
// Delete all drawables that are still marked stale.
for (auto it = drawables.begin(); it != drawables.end();) {
if (it->second.stale) {
drawables.erase(it++);
} else {
++it;
}
}
}

const Drawable<gl::Triangles, RasterLayoutVertex, RasterAttributes>&
TileMaskRepository::getDrawable(gl::Context& context, const TileMask& mask) {
auto it = drawables.find(mask);
if (it == drawables.end()) {
it = drawables
.emplace(std::piecewise_construct, std::forward_as_tuple(mask),
std::forward_as_tuple(context, getPrimitives(mask)))
.first;
} else {
it->second.stale = false;
}
return it->second.drawable;
}

IndexedPrimitives<gl::Triangles, RasterLayoutVertex, RasterAttributes>
TileMaskRepository::getPrimitives(const TileMask& mask) {
IndexedPrimitives<gl::Triangles, RasterLayoutVertex, RasterAttributes> primitives;

for (const auto& id : mask) {
// Create a quad for every masked tile.
const int32_t vertexExtent = util::EXTENT >> id.z;
const int32_t textureExtent = 32768 >> id.z;

const Point<int16_t> tlVertex = { static_cast<int16_t>(id.x * vertexExtent),
static_cast<int16_t>(id.y * vertexExtent) };
const Point<int16_t> brVertex = { static_cast<int16_t>(tlVertex.x + vertexExtent),
static_cast<int16_t>(tlVertex.y + vertexExtent) };
const Point<uint16_t> tlTexture = { static_cast<uint16_t>(id.x * textureExtent),
static_cast<uint16_t>(id.y * textureExtent) };
const Point<uint16_t> brTexture = { static_cast<uint16_t>(tlTexture.x + textureExtent),
static_cast<uint16_t>(tlTexture.y + textureExtent) };

primitives.add(
{
RasterProgram::layoutVertex({ tlVertex.x, tlVertex.y },
{ tlTexture.x, tlTexture.y }),
RasterProgram::layoutVertex({ brVertex.x, tlVertex.y },
{ brTexture.x, tlTexture.y }),
RasterProgram::layoutVertex({ tlVertex.x, brVertex.y },
{ tlTexture.x, brTexture.y }),
RasterProgram::layoutVertex({ brVertex.x, brVertex.y },
{ brTexture.x, brTexture.y }),
},
{
{{ 0, 1, 2 }},
{{ 1, 2, 3 }},
});
}

return primitives;
}

} // namespace mbgl
42 changes: 42 additions & 0 deletions src/mbgl/renderer/tile_mask_repository.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include <mbgl/renderer/tile_mask.hpp>
#include <mbgl/renderer/indexed_primitives.hpp>
#include <mbgl/renderer/drawable.hpp>
#include <mbgl/gl/draw_mode.hpp>
#include <mbgl/programs/raster_program.hpp>

namespace mbgl {

namespace gl {
class Context;
} // namespace gl

class TileMaskRepository {
public:
// Call this function at the beginning of a frame to mark all drawables as "stale".
void mark();

// Delete all drawables that are still marked stale. Call this function at the end of a frame
// during the cleanup phase.
void sweep();

// Obtains a drawable with the specified mask. Creates a new drawable if it doesn't exist, or
// marks the existing as not "stale".
const Drawable<gl::Triangles, RasterLayoutVertex, RasterAttributes>&
getDrawable(gl::Context&, const TileMask&);

static IndexedPrimitives<gl::Triangles, RasterLayoutVertex, RasterAttributes>
getPrimitives(const TileMask&);

private:
struct Entry {
template <class... Args>
Entry(Args&&... args) : drawable(std::forward<Args>(args)...) {}
const Drawable<gl::Triangles, RasterLayoutVertex, RasterAttributes> drawable;
bool stale = false;
};
std::map<TileMask, Entry> drawables;
};

} // namespace mbgl
Loading

0 comments on commit 23cfe73

Please sign in to comment.