rename prepare => upload and determine passes per layer instead of per bucket
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef MBGL_RENDERER_BUCKET
|
||||
#define MBGL_RENDERER_BUCKET
|
||||
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/mat4.hpp>
|
||||
|
||||
@@ -10,17 +11,11 @@ class Painter;
|
||||
class StyleLayer;
|
||||
class TileID;
|
||||
|
||||
enum class RenderPass : uint8_t {
|
||||
Prepare = 1 << 0,
|
||||
Opaque = 1 << 1,
|
||||
Translucent = 1 << 2,
|
||||
};
|
||||
|
||||
class Bucket : private util::noncopyable {
|
||||
public:
|
||||
// As long as this bucket has a Prepare render pass, this function is getting called. Typically,
|
||||
// this only happens once when the bucket is being rendered for the first time.
|
||||
virtual void prepare() = 0;
|
||||
virtual void upload() = 0;
|
||||
|
||||
// Every time this bucket is getting rendered, this function is called. This happens either
|
||||
// once or twice (for Opaque and Transparent render passes).
|
||||
@@ -28,13 +23,12 @@ public:
|
||||
|
||||
virtual ~Bucket() {}
|
||||
|
||||
inline bool hasRenderPass(RenderPass pass) const {
|
||||
return static_cast<std::underlying_type<RenderPass>::type>(renderPass) &
|
||||
static_cast<std::underlying_type<RenderPass>::type>(pass);
|
||||
inline bool needsUpload() const {
|
||||
return uploaded;
|
||||
}
|
||||
|
||||
protected:
|
||||
RenderPass renderPass = RenderPass::Prepare;
|
||||
bool uploaded = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ DebugBucket::DebugBucket(DebugFontBuffer& fontBuffer_)
|
||||
: fontBuffer(fontBuffer_) {
|
||||
}
|
||||
|
||||
void DebugBucket::prepare() {
|
||||
void DebugBucket::upload() {
|
||||
fontBuffer.upload();
|
||||
|
||||
renderPass = RenderPass::Translucent;
|
||||
uploaded = true;
|
||||
}
|
||||
|
||||
void DebugBucket::render(Painter& painter, const StyleLayer&, const TileID&, const mat4& matrix) {
|
||||
|
||||
@@ -15,7 +15,7 @@ class DebugBucket : public Bucket {
|
||||
public:
|
||||
DebugBucket(DebugFontBuffer& fontBuffer);
|
||||
|
||||
void prepare() override;
|
||||
void upload() override;
|
||||
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
|
||||
|
||||
void drawLines(PlainShader& shader);
|
||||
|
||||
@@ -200,15 +200,13 @@ void FillBucket::tessellate() {
|
||||
lineGroup.vertex_length += total_vertex_count;
|
||||
}
|
||||
|
||||
void FillBucket::prepare() {
|
||||
void FillBucket::upload() {
|
||||
vertexBuffer.upload();
|
||||
triangleElementsBuffer.upload();
|
||||
lineElementsBuffer.upload();
|
||||
|
||||
// From now on, we're going to render during the opaque and translucent pass.
|
||||
renderPass = static_cast<RenderPass>(
|
||||
static_cast<std::underlying_type<RenderPass>::type>(RenderPass::Opaque) |
|
||||
static_cast<std::underlying_type<RenderPass>::type>(RenderPass::Translucent));
|
||||
uploaded = true;
|
||||
}
|
||||
|
||||
void FillBucket::render(Painter& painter,
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
LineElementsBuffer &lineElementsBuffer);
|
||||
~FillBucket() override;
|
||||
|
||||
void prepare() override;
|
||||
void upload() override;
|
||||
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
|
||||
bool hasData() const;
|
||||
|
||||
|
||||
@@ -342,12 +342,12 @@ void LineBucket::addCurrentVertex(const Coordinate& currentVertex,
|
||||
e2 = e3;
|
||||
}
|
||||
|
||||
void LineBucket::prepare() {
|
||||
void LineBucket::upload() {
|
||||
vertexBuffer.upload();
|
||||
triangleElementsBuffer.upload();
|
||||
|
||||
// From now on, we're only going to render during the translucent pass.
|
||||
renderPass = RenderPass::Translucent;
|
||||
uploaded = true;
|
||||
}
|
||||
|
||||
void LineBucket::render(Painter& painter,
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
LineBucket(LineVertexBuffer &vertexBuffer, TriangleElementsBuffer &triangleElementsBuffer);
|
||||
~LineBucket() override;
|
||||
|
||||
void prepare() override;
|
||||
void upload() override;
|
||||
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
|
||||
bool hasData() const;
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time)
|
||||
}
|
||||
}
|
||||
|
||||
// - PREPARATION PASS --------------------------------------------------------------------------
|
||||
// - UPLOAD PASS -------------------------------------------------------------------------------
|
||||
// Uploads all required buffers and images before we do any actual rendering.
|
||||
|
||||
// Figure out what buckets we have to draw and what order we have to draw them in.
|
||||
@@ -231,8 +231,8 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time)
|
||||
glyphAtlas.upload();
|
||||
|
||||
for (const auto& item : order) {
|
||||
if (item.bucket && item.bucket->hasRenderPass(RenderPass::Prepare)) {
|
||||
item.bucket->prepare();
|
||||
if (item.bucket && item.bucket->needsUpload()) {
|
||||
item.bucket->upload();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time)
|
||||
for (auto it = order.rbegin(), end = order.rend(); it != end; ++it, ++i) {
|
||||
const auto& item = *it;
|
||||
if (item.bucket && item.tile) {
|
||||
if (item.bucket->hasRenderPass(RenderPass::Opaque)) {
|
||||
if (item.hasRenderPass(RenderPass::Opaque)) {
|
||||
setStrata(i * strata_thickness);
|
||||
prepareTile(*item.tile);
|
||||
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
|
||||
@@ -296,7 +296,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time)
|
||||
for (auto it = order.begin(), end = order.end(); it != end; ++it, --i) {
|
||||
const auto& item = *it;
|
||||
if (item.bucket && item.tile) {
|
||||
if (item.bucket->hasRenderPass(RenderPass::Translucent)) {
|
||||
if (item.hasRenderPass(RenderPass::Translucent)) {
|
||||
setStrata(i * strata_thickness);
|
||||
prepareTile(*item.tile);
|
||||
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
|
||||
@@ -360,6 +360,9 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine what render passes we need for this layer.
|
||||
const RenderPass passes = determineRenderPasses(layer);
|
||||
|
||||
const auto& tiles = layer.bucket->source->getTiles();
|
||||
for (auto tile : tiles) {
|
||||
assert(tile);
|
||||
@@ -369,7 +372,7 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
|
||||
|
||||
auto bucket = tile->data->getBucket(layer);
|
||||
if (bucket) {
|
||||
order.emplace_back(layer, tile, bucket);
|
||||
order.emplace_back(layer, tile, bucket, passes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,6 +380,28 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
|
||||
return order;
|
||||
}
|
||||
|
||||
RenderPass Painter::determineRenderPasses(const StyleLayer& layer) {
|
||||
RenderPass passes = RenderPass::None;
|
||||
|
||||
if (layer.properties.is<FillProperties>()) {
|
||||
const FillProperties &properties = layer.properties.get<FillProperties>();
|
||||
const float alpha = properties.fill_color[3] * properties.opacity;
|
||||
|
||||
if (properties.antialias) {
|
||||
passes |= RenderPass::Translucent;
|
||||
}
|
||||
if (properties.image.from.size() || alpha < 1.0f) {
|
||||
passes |= RenderPass::Translucent;
|
||||
} else {
|
||||
passes |= RenderPass::Opaque;
|
||||
}
|
||||
} else {
|
||||
passes |= RenderPass::Translucent;
|
||||
}
|
||||
|
||||
return passes;
|
||||
}
|
||||
|
||||
void Painter::renderBackground(const StyleLayer &layer_desc) {
|
||||
const BackgroundProperties& properties = layer_desc.getProperties<BackgroundProperties>();
|
||||
|
||||
|
||||
@@ -59,13 +59,19 @@ struct ClipID;
|
||||
struct RenderItem {
|
||||
inline RenderItem(const StyleLayer& layer_,
|
||||
const Tile* tile_ = nullptr,
|
||||
Bucket* bucket_ = nullptr)
|
||||
: tile(tile_), bucket(bucket_), layer(layer_) {
|
||||
Bucket* bucket_ = nullptr,
|
||||
RenderPass passes_ = RenderPass::Opaque)
|
||||
: tile(tile_), bucket(bucket_), layer(layer_), passes(passes_) {
|
||||
}
|
||||
|
||||
const Tile* const tile;
|
||||
Bucket* const bucket;
|
||||
const StyleLayer& layer;
|
||||
const RenderPass passes;
|
||||
|
||||
inline bool hasRenderPass(RenderPass pass) const {
|
||||
return bool(passes & pass);
|
||||
}
|
||||
};
|
||||
|
||||
class Painter : private util::noncopyable {
|
||||
@@ -138,6 +144,7 @@ private:
|
||||
mat4 translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const TileID &id, TranslateAnchorType anchor);
|
||||
|
||||
std::vector<RenderItem> determineRenderOrder(const Style& style);
|
||||
static RenderPass determineRenderPasses(const StyleLayer&);
|
||||
|
||||
void prepareTile(const Tile& tile);
|
||||
|
||||
|
||||
@@ -13,9 +13,10 @@ RasterBucket::RasterBucket(TexturePool& texturePool, const StyleLayoutRaster& la
|
||||
raster(texturePool) {
|
||||
}
|
||||
|
||||
void RasterBucket::prepare() {
|
||||
void RasterBucket::upload() {
|
||||
if (hasData()) {
|
||||
raster.upload();
|
||||
uploaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class RasterBucket : public Bucket {
|
||||
public:
|
||||
RasterBucket(TexturePool&, const StyleLayoutRaster&);
|
||||
|
||||
void prepare() override;
|
||||
void upload() override;
|
||||
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
|
||||
bool hasData() const;
|
||||
|
||||
|
||||
31
src/mbgl/renderer/render_pass.hpp
Normal file
31
src/mbgl/renderer/render_pass.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef MBGL_RENDERER_RENDER_PASS
|
||||
#define MBGL_RENDERER_RENDER_PASS
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class RenderPass : uint8_t {
|
||||
None = 0,
|
||||
Opaque = 1 << 0,
|
||||
Translucent = 1 << 1,
|
||||
};
|
||||
|
||||
constexpr inline RenderPass operator|(RenderPass a, RenderPass b) {
|
||||
return static_cast<RenderPass>(static_cast<std::underlying_type<RenderPass>::type>(a) |
|
||||
static_cast<std::underlying_type<RenderPass>::type>(b));
|
||||
}
|
||||
|
||||
inline RenderPass operator|=(RenderPass& a, RenderPass b) {
|
||||
return (a = a | b);
|
||||
}
|
||||
|
||||
constexpr inline RenderPass operator&(RenderPass a, RenderPass b) {
|
||||
return static_cast<RenderPass>(static_cast<std::underlying_type<RenderPass>::type>(a) &
|
||||
static_cast<std::underlying_type<RenderPass>::type>(b));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -36,7 +36,7 @@ SymbolBucket::~SymbolBucket() {
|
||||
// Do not remove. header file only contains forward definitions to unique pointers.
|
||||
}
|
||||
|
||||
void SymbolBucket::prepare() {
|
||||
void SymbolBucket::upload() {
|
||||
if (hasTextData()) {
|
||||
text.vertices.upload();
|
||||
text.triangles.upload();
|
||||
@@ -46,8 +46,7 @@ void SymbolBucket::prepare() {
|
||||
icon.triangles.upload();
|
||||
}
|
||||
|
||||
// From now on, we're going to render during the opaque and translucent pass.
|
||||
renderPass = RenderPass::Translucent;
|
||||
uploaded = true;
|
||||
}
|
||||
|
||||
void SymbolBucket::render(Painter& painter,
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
SymbolBucket(Collision &collision);
|
||||
~SymbolBucket() override;
|
||||
|
||||
void prepare() override;
|
||||
void upload() override;
|
||||
void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override;
|
||||
bool hasData() const;
|
||||
bool hasTextData() const;
|
||||
|
||||
Reference in New Issue
Block a user