[core] RenderSource creates render items

This commit is contained in:
Mikhail Pozdnyakov
2019-07-03 15:55:47 +03:00
parent 8b78398190
commit da3b7749b0
14 changed files with 141 additions and 107 deletions

View File

@@ -508,7 +508,7 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
std::sort(renderTiles.begin(), renderTiles.end(), comp);
placementData.clear();
for (RenderTile& renderTile : renderTiles) {
for (const RenderTile& renderTile : renderTiles) {
auto* bucket = static_cast<SymbolBucket*>(renderTile.getBucket(*baseImpl));
if (bucket && bucket->bucketLeaderID == getID()) {
// Only place this layer if it's the "group leader" for the bucket

View File

@@ -90,7 +90,7 @@ void PaintParameters::clearStencil() {
namespace {
// Detects a difference in keys of renderTiles and tileClippingMaskIDs
bool tileIDsIdentical(const std::vector<std::reference_wrapper<RenderTile>>& renderTiles,
bool tileIDsIdentical(const RenderTiles& renderTiles,
const std::map<UnwrappedTileID, int32_t>& tileClippingMaskIDs) {
assert(std::is_sorted(renderTiles.begin(), renderTiles.end(),
[](const RenderTile& a, const RenderTile& b) { return a.id < b.id; }));
@@ -103,7 +103,7 @@ bool tileIDsIdentical(const std::vector<std::reference_wrapper<RenderTile>>& ren
} // namespace
void PaintParameters::renderTileClippingMasks(const std::vector<std::reference_wrapper<RenderTile>>& renderTiles) {
void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
if (renderTiles.empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) {
// The current stencil mask is for this source already; no need to draw another one.
return;

View File

@@ -2,6 +2,7 @@
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_light.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/gfx/depth_mode.hpp>
@@ -23,8 +24,6 @@ class ImageManager;
class LineAtlas;
class PatternAtlas;
class UnwrappedTileID;
class RenderSource;
class RenderTile;
namespace gfx {
class Context;
@@ -89,7 +88,7 @@ public:
// Stencil handling
public:
void renderTileClippingMasks(const std::vector<std::reference_wrapper<RenderTile>>&);
void renderTileClippingMasks(const RenderTiles&);
gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const;
gfx::StencilMode stencilModeFor3D();

View File

@@ -54,10 +54,10 @@ optional<Color> RenderLayer::getSolidBackground() const {
return nullopt;
}
RenderLayer::RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const {
RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const {
RenderTiles filtered;
for (RenderTile& tile : tiles) {
for (const RenderTile& tile : tiles) {
if (tile.holdForFade()) {
continue;
}

View File

@@ -30,7 +30,7 @@ public:
class LayerPlacementData {
public:
std::reference_wrapper<Bucket> bucket;
std::reference_wrapper<RenderTile> tile;
std::reference_wrapper<const RenderTile> tile;
std::shared_ptr<FeatureIndex> featureIndex;
};
@@ -43,6 +43,8 @@ public:
const TransformState& state;
};
using RenderTiles = std::vector<std::reference_wrapper<const RenderTile>>;
class RenderLayer {
protected:
RenderLayer(Immutable<style::LayerProperties>);
@@ -115,7 +117,6 @@ protected:
void checkRenderability(const PaintParameters&, uint32_t activeBindingCount);
protected:
using RenderTiles = std::vector<std::reference_wrapper<RenderTile>>;
// Stores current set of tiles to be rendered for this layer.
RenderTiles renderTiles;

View File

@@ -55,25 +55,11 @@ private:
uint32_t index;
};
class SourceRenderItem final : public RenderItem {
public:
explicit SourceRenderItem(RenderSource& source_)
: source(source_) {}
private:
bool hasRenderPass(RenderPass) const override { return false; }
void upload(gfx::UploadPass& pass) const override { source.get().upload(pass); }
void render(PaintParameters& parameters) const override { source.get().finishRender(parameters); }
const std::string& getName() const override { return source.get().baseImpl->id; }
std::reference_wrapper<RenderSource> source;
};
class RenderTreeImpl final : public RenderTree {
public:
RenderTreeImpl(std::unique_ptr<RenderTreeParameters> parameters_,
std::set<LayerRenderItem> layerRenderItems_,
std::vector<SourceRenderItem> sourceRenderItems_,
std::vector<std::unique_ptr<RenderItem>> sourceRenderItems_,
LineAtlas& lineAtlas_,
PatternAtlas& patternAtlas_)
: RenderTree(std::move(parameters_)),
@@ -87,13 +73,16 @@ public:
return { layerRenderItems.begin(), layerRenderItems.end() };
}
RenderItems getSourceRenderItems() const override {
return { sourceRenderItems.begin(), sourceRenderItems.end() };
RenderItems result;
result.reserve(sourceRenderItems.size());
for (const auto& item : sourceRenderItems) result.emplace_back(*item);
return result;
}
LineAtlas& getLineAtlas() const override { return lineAtlas; }
PatternAtlas& getPatternAtlas() const override { return patternAtlas; }
std::set<LayerRenderItem> layerRenderItems;
std::vector<SourceRenderItem> sourceRenderItems;
std::vector<std::unique_ptr<RenderItem>> sourceRenderItems;
std::reference_wrapper<LineAtlas> lineAtlas;
std::reference_wrapper<PatternAtlas> patternAtlas;
};
@@ -339,12 +328,10 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
return nullptr;
}
std::vector<SourceRenderItem> sourceRenderItems;
// Update all matrices and generate data that we should upload to the GPU.
// Prepare. Update all matrices and generate data that we should upload to the GPU.
for (const auto& entry : renderSources) {
if (entry.second->isEnabled()) {
entry.second->prepare({renderTreeParameters->transformParams, updateParameters.debugOptions, *imageManager});
sourceRenderItems.emplace_back(*entry.second);
}
}
@@ -355,7 +342,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
layersNeedPlacement.emplace_back(renderLayer);
}
}
// Symbol placement.
{
if (!isMapModeContinuous) {
// TODO: Think about right way for symbol index to handle still rendering
@@ -406,6 +393,13 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
imageManager->reduceMemoryUseIfCacheSizeExceedsLimit();
}
std::vector<std::unique_ptr<RenderItem>> sourceRenderItems;
for (const auto& entry : renderSources) {
if (entry.second->isEnabled()) {
sourceRenderItems.emplace_back(entry.second->createRenderItem());
}
}
return std::make_unique<RenderTreeImpl>(
std::move(renderTreeParameters),
std::move(layerRenderItems),

View File

@@ -30,6 +30,7 @@ class CollisionIndex;
class TransformParameters;
class ImageManager;
class ImageSourceRenderData;
class RenderItem;
namespace gfx {
class UploadPass;
@@ -42,6 +43,8 @@ public:
const ImageManager& imageManager;
};
using RenderTiles = std::vector<std::reference_wrapper<const RenderTile>>;
class RenderSource : protected TileObserver {
public:
static std::unique_ptr<RenderSource> create(Immutable<style::Source::Impl>);
@@ -55,14 +58,14 @@ public:
bool needsRendering,
bool needsRelayout,
const TileParameters&) = 0;
virtual void upload(gfx::UploadPass&) = 0;
// Note: calling of this method might reset the contained render data.
virtual std::unique_ptr<RenderItem> createRenderItem() = 0;
// Creates the render data to be passed to the render item.
virtual void prepare(const SourcePrepareParameters&) = 0;
virtual void finishRender(PaintParameters&) = 0;
virtual void updateFadingTiles() = 0;
virtual bool hasFadingTiles() const = 0;
// Returns a list of RenderTiles, sorted by tile id.
virtual std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() = 0;
virtual RenderTiles getRenderTiles() = 0;
virtual const ImageSourceRenderData* getImageRenderData() const { return nullptr; }
virtual const Tile* getRenderedTile(const UnwrappedTileID&) const { return nullptr; }

View File

@@ -91,7 +91,7 @@ const gfx::Texture& RenderTile::getIconAtlasTexture() const {
return renderData->getIconAtlasTexture();
}
void RenderTile::upload(gfx::UploadPass& uploadPass) {
void RenderTile::upload(gfx::UploadPass& uploadPass) const {
assert(renderData);
renderData->upload(uploadPass);
@@ -129,7 +129,7 @@ void RenderTile::prepare(const SourcePrepareParameters& parameters) {
matrix::multiply(nearClippedMatrix, transform.nearClippedProjMatrix, nearClippedMatrix);
}
void RenderTile::finishRender(PaintParameters& parameters) {
void RenderTile::finishRender(PaintParameters& parameters) const {
if (!needsRendering || parameters.debugOptions == MapDebugOptions::NoDebug)
return;

View File

@@ -59,9 +59,9 @@ public:
const gfx::Texture& getGlyphAtlasTexture() const;
const gfx::Texture& getIconAtlasTexture() const;
void upload(gfx::UploadPass&);
void upload(gfx::UploadPass&) const;
void prepare(const SourcePrepareParameters&);
void finishRender(PaintParameters&);
void finishRender(PaintParameters&) const;
mat4 translateVtxMatrix(const mat4& tileMatrix,
const std::array<float, 2>& translation,

View File

@@ -17,55 +17,25 @@ namespace mbgl {
using namespace style;
RenderImageSource::RenderImageSource(Immutable<style::ImageSource::Impl> impl_)
: RenderSource(impl_) {
}
ImageSourceRenderData::~ImageSourceRenderData() = default;
RenderImageSource::~RenderImageSource() = default;
const style::ImageSource::Impl& RenderImageSource::impl() const {
return static_cast<const style::ImageSource::Impl&>(*baseImpl);
}
bool RenderImageSource::isLoaded() const {
return !!bucket;
}
void RenderImageSource::upload(gfx::UploadPass& uploadPass) {
if (bucket->needsUpload()) {
void ImageSourceRenderData::upload(gfx::UploadPass& uploadPass) const {
if (bucket && bucket->needsUpload()) {
bucket->upload(uploadPass);
}
}
void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
if (!isLoaded()) {
void ImageSourceRenderData::render(PaintParameters& parameters) const {
if (!bucket || !(parameters.debugOptions & MapDebugOptions::TileBorders)) {
return;
}
std::vector<mat4> matrices{tileIds.size(), mat4()};
const auto& transformParams = parameters.transform;
for (size_t i = 0u; i < tileIds.size(); ++i) {
mat4& matrix = matrices[i];
matrix::identity(matrix);
transformParams.state.matrixFor(matrix, tileIds[i]);
matrix::multiply(matrix, transformParams.alignedProjMatrix, matrix);
}
renderData = std::make_unique<ImageSourceRenderData>(bucket, std::move(matrices));
}
void RenderImageSource::finishRender(PaintParameters& parameters) {
if (!isLoaded() || !(parameters.debugOptions & MapDebugOptions::TileBorders)) {
return;
}
assert(renderData);
static const style::Properties<>::PossiblyEvaluated properties {};
static const DebugProgram::Binders paintAttributeData(properties, 0);
auto& programInstance = parameters.programs.debug;
for (auto matrix : renderData->matrices) {
for (auto matrix : matrices) {
programInstance.draw(
parameters.context,
*parameters.renderPass,
@@ -96,6 +66,43 @@ void RenderImageSource::finishRender(PaintParameters& parameters) {
}
}
RenderImageSource::RenderImageSource(Immutable<style::ImageSource::Impl> impl_)
: RenderSource(std::move(impl_)) {
}
RenderImageSource::~RenderImageSource() = default;
const style::ImageSource::Impl& RenderImageSource::impl() const {
return static_cast<const style::ImageSource::Impl&>(*baseImpl);
}
bool RenderImageSource::isLoaded() const {
return !!bucket;
}
std::unique_ptr<RenderItem> RenderImageSource::createRenderItem() {
assert(renderData);
return std::move(renderData);
}
void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
assert(!renderData);
if (!isLoaded()) {
renderData = std::make_unique<ImageSourceRenderData>(bucket, std::vector<mat4>{}, baseImpl->id);
return;
}
std::vector<mat4> matrices{tileIds.size(), mat4()};
const auto& transformParams = parameters.transform;
for (size_t i = 0u; i < tileIds.size(); ++i) {
mat4& matrix = matrices[i];
matrix::identity(matrix);
transformParams.state.matrixFor(matrix, tileIds[i]);
matrix::multiply(matrix, transformParams.alignedProjMatrix, matrix);
}
renderData = std::make_unique<ImageSourceRenderData>(bucket, std::move(matrices), baseImpl->id);
}
std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,

View File

@@ -9,14 +9,25 @@ namespace mbgl {
class RasterBucket;
class ImageSourceRenderData {
class ImageSourceRenderData final : public RenderItem {
public:
ImageSourceRenderData(std::shared_ptr<RasterBucket> bucket_,
std::vector<mat4> matrices_)
std::vector<mat4> matrices_,
std::string name_)
: bucket(std::move(bucket_)),
matrices(std::move(matrices_)) {}
std::shared_ptr<RasterBucket> bucket;
std::vector<mat4> matrices;
matrices(std::move(matrices_)),
name(std::move(name_)) {}
~ImageSourceRenderData() override;
const std::shared_ptr<RasterBucket> bucket;
const std::vector<mat4> matrices;
private:
void upload(gfx::UploadPass&) const override;
void render(PaintParameters&) const override;
bool hasRenderPass(RenderPass) const override { return false; }
const std::string& getName() const override { return name; }
std::string name;
};
class RenderImageSource final : public RenderSource {
@@ -26,9 +37,8 @@ public:
bool isLoaded() const final;
void upload(gfx::UploadPass&) final;
std::unique_ptr<RenderItem> createRenderItem() override;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
void updateFadingTiles() final {}
bool hasFadingTiles() const final { return false; }
@@ -38,9 +48,7 @@ public:
bool needsRelayout,
const TileParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final {
return {};
}
RenderTiles getRenderTiles() override { return {}; }
const ImageSourceRenderData* getImageRenderData() const override {
return renderData.get();

View File

@@ -2,6 +2,7 @@
#include <mbgl/renderer/buckets/debug_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/tile_render_data.hpp>
#include <mbgl/tile/vector_tile.hpp>
@@ -10,8 +11,37 @@ namespace mbgl {
using namespace style;
class TileSourceRenderItem : public RenderItem {
public:
TileSourceRenderItem(Immutable<std::vector<RenderTile>> renderTiles_, std::string name_)
: renderTiles(std::move(renderTiles_))
, name(std::move(name_)) {}
private:
void upload(gfx::UploadPass&) const override;
void render(PaintParameters&) const override;
bool hasRenderPass(RenderPass) const override { return false; }
const std::string& getName() const override { return name; }
Immutable<std::vector<RenderTile>> renderTiles;
std::string name;
};
void TileSourceRenderItem::upload(gfx::UploadPass& parameters) const {
for (auto& tile : *renderTiles) {
tile.upload(parameters);
}
}
void TileSourceRenderItem::render(PaintParameters& parameters) const {
for (auto& tile : *renderTiles) {
tile.finishRender(parameters);
}
}
RenderTileSource::RenderTileSource(Immutable<style::Source::Impl> impl_)
: RenderSource(std::move(impl_)) {
: RenderSource(std::move(impl_))
, renderTiles(makeMutable<std::vector<RenderTile>>()) {
tilePyramid.setObserver(this);
}
@@ -21,25 +51,18 @@ bool RenderTileSource::isLoaded() const {
return tilePyramid.isLoaded();
}
void RenderTileSource::upload(gfx::UploadPass& parameters) {
for (auto& tile : renderTiles) {
tile.upload(parameters);
}
std::unique_ptr<RenderItem> RenderTileSource::createRenderItem() {
return std::make_unique<TileSourceRenderItem>(renderTiles, baseImpl->id);
}
void RenderTileSource::prepare(const SourcePrepareParameters& parameters) {
renderTiles.clear();
renderTiles.reserve(tilePyramid.getRenderedTiles().size());
auto tiles = makeMutable<std::vector<RenderTile>>();
tiles->reserve(tilePyramid.getRenderedTiles().size());
for (auto& entry : tilePyramid.getRenderedTiles()) {
renderTiles.emplace_back(entry.first, entry.second);
renderTiles.back().prepare(parameters);
}
}
void RenderTileSource::finishRender(PaintParameters& parameters) {
for (auto& tile : renderTiles) {
tile.finishRender(parameters);
tiles->emplace_back(entry.first, entry.second);
tiles->back().prepare(parameters);
}
renderTiles = std::move(tiles);
}
void RenderTileSource::updateFadingTiles() {
@@ -50,8 +73,8 @@ bool RenderTileSource::hasFadingTiles() const {
return tilePyramid.hasFadingTiles();
}
std::vector<std::reference_wrapper<RenderTile>> RenderTileSource::getRenderTiles() {
return { renderTiles.begin(), renderTiles.end() };
RenderTiles RenderTileSource::getRenderTiles() {
return { renderTiles->begin(), renderTiles->end() };
}
const Tile* RenderTileSource::getRenderedTile(const UnwrappedTileID& tileID) const {

View File

@@ -16,13 +16,12 @@ public:
bool isLoaded() const override;
void upload(gfx::UploadPass&) override;
std::unique_ptr<RenderItem> createRenderItem() override;
void prepare(const SourcePrepareParameters&) override;
void finishRender(PaintParameters&) override;
void updateFadingTiles() override;
bool hasFadingTiles() const override;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() override;
RenderTiles getRenderTiles() override;
const Tile* getRenderedTile(const UnwrappedTileID&) const override;
std::unordered_map<std::string, std::vector<Feature>>
@@ -40,7 +39,7 @@ public:
protected:
TilePyramid tilePyramid;
std::vector<RenderTile> renderTiles;
Immutable<std::vector<RenderTile>> renderTiles;
};
} // namespace mbgl

View File

@@ -172,7 +172,7 @@ bool CrossTileSymbolIndex::addLayer(const RenderLayer& layer, float lng) {
layerIndex.handleWrapJump(lng);
for (const auto& item : layer.getPlacementData()) {
RenderTile& renderTile = item.tile;
const RenderTile& renderTile = item.tile;
Bucket& bucket = item.bucket;
auto result = bucket.registerAtCrossTileIndex(layerIndex, renderTile.getOverscaledTileID(), maxCrossTileID);
assert(result.first != 0u);