Skip to content

Commit

Permalink
add support for reference_wrapper
Browse files Browse the repository at this point in the history
integrate with `render_layer`
start on fill conversion
  • Loading branch information
TimSylvester committed Aug 2, 2024
1 parent 09d29cf commit b9b29e1
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 27 deletions.
66 changes: 61 additions & 5 deletions src/mbgl/renderer/layers/render_fill_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <mbgl/style/layers/fill_layer_impl.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/tile_diff.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/intersection_tests.hpp>
#include <mbgl/util/logging.hpp>
Expand Down Expand Up @@ -357,15 +358,70 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
builder.setEnableStencil(true);
};

stats.drawablesRemoved += fillTileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
const auto& tileID = drawable.getTileID();
return tileID && !hasRenderTile(*tileID);
});
// Remove drawables for removed tiles
for (const auto& tileID : renderTileDiff->removed) {
removeTile(renderPass, tileID);
}

fillTileLayerGroup->setStencilTiles(renderTiles);

StringIDSetsPair propertiesAsUniforms;

// Update tiles that weren't added or removed
std::vector<OverscaledTileID> resetTileIDs;
for (const auto& tileID : renderTileDiff->remainder) {
const auto tileRef = getRenderTile(tileID);
if (!tileRef) {
assert(false);
continue;
}
const RenderTile& tile = tileRef->get();

const LayerRenderData* renderData = getRenderDataForPass(tile, renderPass);
if (!renderData || !renderData->bucket || !renderData->bucket->hasData()) {
removeTile(renderPass, tileID);

if (renderData && !renderData->bucket) {
// We'll need to treat this tile as an add
resetTileIDs.push_back(tileID);
}
continue;
}

auto& bucket = static_cast<FillBucket&>(*renderData->bucket);

const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
// This tile was previously set up from a different bucket, drop and re-create any drawables for it.
removeTile(renderPass, tileID);

// We'll need to treat this tile as an add
resetTileIDs.push_back(tileID);
}
setRenderTileBucketID(tileID, bucket.getID());
}

// Create drawables for new tiles
const auto newTile = [&](const OverscaledTileID& tileID) {
const auto tileRef = getRenderTile(tileID);
if (!tileRef) {
assert(false);
return;
}
const RenderTile& tile = tileRef->get();

const LayerRenderData* renderData = getRenderDataForPass(tile, renderPass);
if (!renderData || !renderData->bucket || !renderData->bucket->hasData()) {
return;
}

auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
setRenderTileBucketID(tileID, bucket.getID());
};
// With C++20 we can chain iterator ranges and use `for(:)`
std::for_each(renderTileDiff->added.begin(), renderTileDiff->added.end(), newTile);
std::for_each(resetTileIDs.begin(), resetTileIDs.end(), newTile);

for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();

Expand Down
23 changes: 23 additions & 0 deletions src/mbgl/renderer/render_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/tile_diff.hpp>
#include <mbgl/util/instrumentation.hpp>
#include <mbgl/util/logging.hpp>

#if MLN_DRAWABLE_RENDERER
Expand Down Expand Up @@ -58,6 +60,7 @@ void RenderLayer::prepare(const LayerPrepareParameters& params) {
assert(params.source);
assert(params.source->isEnabled());
renderTiles = params.source->getRenderTiles();
renderTileDiff = params.source->getRenderTileDiff();
addRenderPassesFromTiles();

#if MLN_DRAWABLE_RENDERER
Expand Down Expand Up @@ -140,6 +143,24 @@ const LayerRenderData* RenderLayer::getRenderDataForPass(const RenderTile& tile,
return nullptr;
}

std::optional<std::reference_wrapper<const RenderTile>> RenderLayer::getRenderTile(
const OverscaledTileID& tileID) const {
// Search `RenderTiles` for a tile ID without creating a "key" instance of `RenderTile`
struct Comp {
bool operator()(const std::reference_wrapper<const RenderTile>& tile, const OverscaledTileID& id) const {
return tile.get().getOverscaledTileID() < id;
}
bool operator()(const OverscaledTileID& id, const std::reference_wrapper<const RenderTile>& tile) const {
return id < tile.get().getOverscaledTileID();
}
};
const auto result = std::lower_bound(renderTiles->begin(), renderTiles->end(), tileID, Comp());
if (result != renderTiles->end() && result->get().getOverscaledTileID() == tileID) {
return *result;
}
return std::nullopt;
}

#if MLN_DRAWABLE_RENDERER
std::size_t RenderLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
if (const auto tileGroup = static_cast<TileLayerGroup*>(layerGroup.get())) {
Expand All @@ -161,6 +182,8 @@ std::size_t RenderLayer::removeAllDrawables() {
}

void RenderLayer::updateRenderTileIDs() {
MLN_TRACE_FUNC()

if (!renderTiles || renderTiles->empty()) {
renderTileIDs.clear();
return;
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/renderer/render_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ class RenderLayer {

const LayerRenderData* getRenderDataForPass(const RenderTile&, RenderPass) const;

std::optional<std::reference_wrapper<const RenderTile>> getRenderTile(const OverscaledTileID& tileID) const;

#if MLN_DRAWABLE_RENDERER
void setLayerGroup(LayerGroupBasePtr, UniqueChangeRequestVec&);

Expand Down Expand Up @@ -275,6 +277,7 @@ class RenderLayer {
protected:
// Stores current set of tiles to be rendered for this layer.
RenderTiles renderTiles;
std::shared_ptr<TileDifference> renderTileDiff;

// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/renderer/render_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class RenderTile;
class Scheduler;
class SourceQueryOptions;
class Tile;
class TileDifference;
class TileParameters;
class TransformParameters;
class TransformState;
Expand Down Expand Up @@ -69,6 +70,8 @@ class RenderSource : protected TileObserver {
// If supported, returns a shared list of RenderTiles, sorted by tile id and
// excluding tiles hold for fade; returns nullptr otherwise.
virtual RenderTiles getRenderTiles() const { return nullptr; }
// If supported, returns a description of the tile IDs which were added and removed in the last `prepare`
virtual std::shared_ptr<TileDifference> getRenderTileDiff() const { return nullptr; }
// If supported, returns a shared list of RenderTiles, sorted in opposite y
// position, so tiles with overlapping symbols are drawn on top of each other,
// with lower symbols being drawn on top of higher symbols; returns nullptr otherwise.
Expand Down
16 changes: 15 additions & 1 deletion src/mbgl/renderer/sources/render_tile_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/renderer/tile_render_data.hpp>
#include <mbgl/tile/tile_diff.hpp>
#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/instrumentation.hpp>
Expand Down Expand Up @@ -387,7 +388,8 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
RenderTileSource::RenderTileSource(Immutable<style::Source::Impl> impl_, const TaggedScheduler& threadPool_)
: RenderSource(std::move(impl_)),
tilePyramid(threadPool_),
renderTiles(makeMutable<std::vector<RenderTile>>()) {
renderTiles(makeMutable<std::vector<RenderTile>>()),
previousRenderTiles(makeMutable<std::vector<RenderTile>>()) {
tilePyramid.setObserver(this);
}

Expand All @@ -414,6 +416,9 @@ void RenderTileSource::prepare(const SourcePrepareParameters& parameters) {
tiles->back().prepare(parameters);
}
featureState.coalesceChanges(*tiles);

renderTileDiff.reset();
previousRenderTiles = std::move(renderTiles);
renderTiles = std::move(tiles);
}

Expand All @@ -439,6 +444,15 @@ RenderTiles RenderTileSource::getRenderTiles() const {
return filteredRenderTiles;
}

std::shared_ptr<TileDifference> RenderTileSource::getRenderTileDiff() const {
if (!renderTileDiff) {
const auto tiles = getRenderTiles();
renderTileDiff = std::make_shared<TileDifference>(
diffTiles(previousRenderTiles->begin(), previousRenderTiles->end(), tiles->begin(), tiles->end()));
}
return renderTileDiff;
}

RenderTiles RenderTileSource::getRenderTilesSortedByYPosition() const {
if (!renderTilesSortedByY) {
const auto comp = [sourceBearing = this->bearing](const RenderTile& a, const RenderTile& b) {
Expand Down
7 changes: 6 additions & 1 deletion src/mbgl/renderer/sources/render_tile_source.hpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
#pragma once

#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/source_state.hpp>
#include <mbgl/renderer/tile_pyramid.hpp>
#include <mbgl/style/sources/vector_source_impl.hpp>
#include <mbgl/renderer/render_tree.hpp>

#if MLN_DRAWABLE_RENDERER
#include <mbgl/gfx/context.hpp>
#endif

namespace mbgl {

class TileDifference;

/**
* @brief Base class for render sources that provide render tiles.
*/
Expand All @@ -27,6 +29,7 @@ class RenderTileSource : public RenderSource {
bool hasFadingTiles() const override;

RenderTiles getRenderTiles() const override;
std::shared_ptr<TileDifference> getRenderTileDiff() const override;
RenderTiles getRenderTilesSortedByYPosition() const override;
const Tile* getRenderedTile(const UnwrappedTileID&) const override;

Expand Down Expand Up @@ -55,6 +58,8 @@ class RenderTileSource : public RenderSource {
RenderTileSource(Immutable<style::Source::Impl>, const TaggedScheduler&);
TilePyramid tilePyramid;
Immutable<std::vector<RenderTile>> renderTiles;
Immutable<std::vector<RenderTile>> previousRenderTiles;
mutable std::shared_ptr<TileDifference> renderTileDiff;
mutable RenderTiles filteredRenderTiles;
mutable RenderTiles renderTilesSortedByY;

Expand Down
55 changes: 35 additions & 20 deletions src/mbgl/tile/tile_diff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,38 @@ namespace mbgl {

class RenderTile;

class TileDifference {
public:
std::vector<UnwrappedTileID> added;
std::vector<UnwrappedTileID> removed;
std::vector<UnwrappedTileID> remainder;
struct TileDifference {
const std::vector<OverscaledTileID> added;
const std::vector<OverscaledTileID> removed;
const std::vector<OverscaledTileID> remainder;
};

namespace detail {
// Iterate a collection of `RenderTile` as if they were tile IDs
namespace tile_diff_detail {

template <typename W, typename T>
inline constexpr bool is_ref_wrap = std::is_same_v<std::remove_cv_t<typename W::value_type>, std::reference_wrapper<T>>;
template <typename T, typename TI>
using adaptor_base = boost::iterator_adaptor<TI, T, boost::use_default, boost::use_default, const OverscaledTileID&>;

// Iterate a collection of `RenderTile` (or `reference_wrapper` thereto) as if they were tile IDs
template <typename T, bool wrap = is_ref_wrap<T, RenderTile> || is_ref_wrap<T, const RenderTile>>
struct TileIDIterator : public adaptor_base<T, TileIDIterator<T>> {
const OverscaledTileID& dereference() const { return this->base()->get().getOverscaledTileID(); }
TileIDIterator(const TileIDIterator<T>::iterator_adaptor_::base_type& p)
: TileIDIterator<T>::iterator_adaptor_(p) {}
};
template <typename T>
struct TileIDIterator : public boost::iterator_adaptor<TileIDIterator<T>,
T,
UnwrappedTileID,
boost::random_access_traversal_tag,
const UnwrappedTileID&> {
const UnwrappedTileID& dereference() const { return this->base()->id; }
struct TileIDIterator<T, false> : public adaptor_base<T, TileIDIterator<T>> {
const OverscaledTileID& dereference() const { return this->base()->getOverscaledTileID(); }
TileIDIterator(const TileIDIterator<T>::iterator_adaptor_::base_type& p)
: TileIDIterator<T>::iterator_adaptor_(p) {}
};
} // namespace detail
} // namespace tile_diff_detail

/// @brief Compute the differences in tile IDs between two containers of `RenderTile` ordered by tile ID
template <typename TIterA, typename TIterB>
TileDifference diffTiles(TIterA aBeg_, TIterA aEnd_, TIterB bBeg_, TIterB bEnd_) {
using namespace detail;
using namespace tile_diff_detail;
const TileIDIterator<TIterA> aBeg = aBeg_;
const TileIDIterator<TIterA> aEnd = aEnd_;
const TileIDIterator<TIterB> bBeg = bBeg_;
Expand All @@ -45,12 +52,20 @@ TileDifference diffTiles(TIterA aBeg_, TIterA aEnd_, TIterB bBeg_, TIterB bEnd_)
assert(std::is_sorted(aBeg, aEnd));
assert(std::is_sorted(bBeg, bEnd));

TileDifference result;
std::set_difference(aBeg, aEnd, bBeg, bEnd, std::back_inserter(result.removed));
std::set_difference(bBeg, bEnd, aBeg, aEnd, std::back_inserter(result.added));
std::set_intersection(aBeg, aEnd, bBeg, bEnd, std::back_inserter(result.remainder));
std::vector<OverscaledTileID> added;
std::set_difference(bBeg, bEnd, aBeg, aEnd, std::back_inserter(added));

std::vector<OverscaledTileID> removed;
std::set_difference(aBeg, aEnd, bBeg, bEnd, std::back_inserter(removed));

std::vector<OverscaledTileID> remainder;
std::set_intersection(aBeg, aEnd, bBeg, bEnd, std::back_inserter(remainder));

return result;
return {
std::move(added),
std::move(removed),
std::move(remainder),
};
}

} // namespace mbgl

0 comments on commit b9b29e1

Please sign in to comment.