Revert index buffers to dirty flag instead of timestamps (#2927)

This commit is contained in:
Alex Cristici
2024-10-16 17:48:46 +03:00
committed by GitHub
parent ff62309e5d
commit e937b0d555
23 changed files with 27 additions and 119 deletions

View File

@@ -113,10 +113,6 @@ public:
void reduceMemoryUse();
void clearData();
#if MLN_RENDER_BACKEND_OPENGL
void enableAndroidEmulatorGoldfishMitigation(bool enable);
#endif
private:
class Impl;
std::unique_ptr<Impl> impl;

View File

@@ -13,27 +13,6 @@
#include "android_renderer_backend.hpp"
#include "map_renderer_runnable.hpp"
#if MLN_RENDER_BACKEND_OPENGL
#include <sys/system_properties.h>
namespace {
std::string androidSysProp(const char* key) {
assert(strlen(key) < PROP_NAME_MAX);
if (__system_property_find(key) == nullptr) {
return "";
}
char prop[PROP_VALUE_MAX + 1];
__system_property_get(key, prop);
return prop;
}
bool inEmulator() {
return androidSysProp("ro.kernel.qemu") == "1" || androidSysProp("ro.boot.qemu") == "1" ||
androidSysProp("ro.hardware.egl") == "emulation";
}
} // namespace
#endif
namespace mbgl {
namespace android {
@@ -253,14 +232,6 @@ void MapRenderer::onSurfaceCreated(JNIEnv& env, const jni::Object<AndroidSurface
renderer = std::make_unique<Renderer>(backend->getImpl(), pixelRatio, localIdeographFontFamily);
rendererRef = std::make_unique<ActorRef<Renderer>>(*renderer, mailboxData.getMailbox());
#if MLN_RENDER_BACKEND_OPENGL
// If we're running the emulator with the OpenGL backend, we're going to crash eventually,
// unless we enable this mitigation.
if (inEmulator()) {
renderer->enableAndroidEmulatorGoldfishMitigation(true);
}
#endif
backend->setSwapBehavior(swapBehaviorFlush ? gfx::Renderable::SwapBehaviour::Flush
: gfx::Renderable::SwapBehaviour::NoFlush);

View File

@@ -2,7 +2,6 @@
#include <mbgl/gfx/draw_mode.hpp>
#include <mbgl/util/ignore.hpp>
#include <mbgl/util/monotonic_timer.hpp>
#include <memory>
#include <vector>
@@ -41,15 +40,8 @@ public:
void setBuffer(std::unique_ptr<IndexBufferBase>&& value) { buffer = std::move(value); }
#endif // MLN_DRAWABLE_RENDERER
std::chrono::duration<double> getLastModified() const { return lastModified; }
bool isModifiedAfter(std::chrono::duration<double> t) const { return t < lastModified; }
void updateModified() {
if (dirty) {
lastModified = util::MonotonicTimer::now();
dirty = false;
}
}
bool getDirty() const { return dirty; }
void setDirty(bool value = true) { dirty = value; }
bool isReleased() const { return released; }
@@ -107,8 +99,6 @@ protected:
#endif // MLN_DRAWABLE_RENDERER
bool dirty = true;
bool released = false;
std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
};
using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;

View File

@@ -18,7 +18,6 @@ DrawableGL::DrawableGL(std::string name_)
impl(std::make_unique<Impl>()) {}
DrawableGL::~DrawableGL() {
impl->indexBuffer = {0, nullptr};
impl->attributeBuffers.clear();
}
@@ -192,12 +191,8 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
auto& glContext = static_cast<gl::Context&>(context);
constexpr auto usage = gfx::BufferUsageType::StaticDraw;
// Create an index buffer if necessary
if (impl->indexes) {
impl->indexes->updateModified();
}
if (impl->indexes &&
(!impl->indexes->getBuffer() || !attributeUpdateTime || impl->indexes->isModifiedAfter(*attributeUpdateTime))) {
// Create an index buffer if necessary}
if (impl->indexes && (!impl->indexes->getBuffer() || impl->indexes->getDirty())) {
MLN_TRACE_ZONE(build indexes);
auto indexBufferResource{
uploadPass.createIndexBufferResource(impl->indexes->data(), impl->indexes->bytes(), usage)};
@@ -205,6 +200,7 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
std::move(indexBufferResource));
auto buffer = std::make_unique<IndexBufferGL>(std::move(indexBuffer));
impl->indexes->setBuffer(std::move(buffer));
impl->indexes->setDirty(false);
}
// Build the vertex attributes and bindings, if necessary

View File

@@ -39,8 +39,6 @@ public:
gfx::AttributeDataType vertexType = static_cast<gfx::AttributeDataType>(-1);
AttributeBindingArray attributeBindings;
gfx::IndexBuffer indexBuffer = {0, nullptr};
std::vector<gfx::UniqueVertexBufferResource> attributeBuffers;
UniformBufferArrayGL uniformBuffers;

View File

@@ -191,13 +191,13 @@ void Drawable::draw(PaintParameters& parameters) const {
bindUniformBuffers(renderPass);
bindTextures(renderPass);
if (!impl->indexes->getBuffer() || !attributeUpdateTime || impl->indexes->isModifiedAfter(*attributeUpdateTime)) {
if (!impl->indexes->getBuffer() || impl->indexes->getDirty()) {
assert(!"Index buffer not uploaded");
return;
}
const auto* indexBuffer = getMetalBuffer(impl->indexes);
if (!indexBuffer || !attributeUpdateTime || impl->indexes->isModifiedAfter(*attributeUpdateTime)) {
if (!indexBuffer || impl->indexes->getDirty()) {
assert(!"Index buffer not uploaded");
return;
}
@@ -546,19 +546,14 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
auto& context = static_cast<Context&>(contextBase);
constexpr auto usage = gfx::BufferUsageType::StaticDraw;
if (impl->indexes) {
impl->indexes->updateModified();
}
// We need either raw index data or a buffer already created from them.
// We can have a buffer and no indexes, but only if it's not marked dirty.
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || !attributeUpdateTime ||
impl->indexes->isModifiedAfter(*attributeUpdateTime)))) {
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || impl->indexes->getDirty()))) {
assert(!"Missing index data");
return;
}
if (!impl->indexes->getBuffer() || !attributeUpdateTime || impl->indexes->isModifiedAfter(*attributeUpdateTime)) {
if (!impl->indexes->getBuffer() || impl->indexes->getDirty()) {
// Create or update a buffer for the index data. We don't update any
// existing buffer because it may still be in use by the previous frame.
auto indexBufferResource{uploadPass.createIndexBufferResource(
@@ -568,6 +563,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
auto buffer = std::make_unique<IndexBuffer>(std::move(indexBuffer));
impl->indexes->setBuffer(std::move(buffer));
impl->indexes->setDirty(false);
}
const bool buildAttribs = !impl->vertexDesc || !vertexAttributes || !attributeUpdateTime ||
@@ -593,7 +589,6 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
usage,
attributeUpdateTime,
vertexBuffers);
impl->attributeBuffers = std::move(vertexBuffers);
vertexAttributes->visitAttributes([](gfx::VertexAttribute& attrib) { attrib.setDirty(false); });
@@ -667,7 +662,6 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
usage,
attributeUpdateTime,
instanceBuffers);
impl->instanceBuffers = std::move(instanceBuffers);
// clear dirty flag
instanceAttributes->visitAttributes([](gfx::VertexAttribute& attrib) { attrib.setDirty(false); });

View File

@@ -45,10 +45,7 @@ public:
std::size_t vertexCount = 0;
gfx::AttributeDataType vertexType = gfx::AttributeDataType::Invalid;
std::vector<gfx::UniqueVertexBufferResource> attributeBuffers;
gfx::AttributeBindingArray attributeBindings;
std::vector<gfx::UniqueVertexBufferResource> instanceBuffers;
gfx::AttributeBindingArray instanceBindings;
UniformBufferArray uniformBuffers;

View File

@@ -159,7 +159,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
const gfx::VertexAttributeArray& overrides,
const gfx::BufferUsageType usage,
const std::optional<std::chrono::duration<double>> lastUpdate,
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) {
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>&) {
MLN_TRACE_FUNC();
gfx::AttributeBindingArray bindings;

View File

@@ -74,7 +74,6 @@ void CircleBucket::update(const FeatureStates& states,
uploaded = false;
sharedVertices->updateModified();
sharedTriangles->updateModified();
}
}

View File

@@ -113,8 +113,6 @@ void FillBucket::update(const FeatureStates& states,
uploaded = false;
sharedVertices->updateModified();
sharedBasicLineIndexes->updateModified();
sharedTriangles->updateModified();
}
}

View File

@@ -206,7 +206,6 @@ void FillExtrusionBucket::update(const FeatureStates& states,
uploaded = false;
sharedVertices->updateModified();
sharedTriangles->updateModified();
}
}

View File

@@ -57,7 +57,6 @@ void HillshadeBucket::clear() {
indices.clear();
vertices.updateModified();
indices.updateModified();
uploaded = false;
}
@@ -121,7 +120,6 @@ void HillshadeBucket::setMask(TileMask&& mask_) {
}
vertices.updateModified();
indices.updateModified();
}
bool HillshadeBucket::hasData() const {

View File

@@ -168,7 +168,6 @@ void LineBucket::update(const FeatureStates& states,
uploaded = false;
sharedVertices->updateModified();
sharedTriangles->updateModified();
}
}

View File

@@ -47,7 +47,6 @@ void RasterBucket::clear() {
indices.clear();
vertices.updateModified();
indices.updateModified();
uploaded = false;
}
@@ -118,7 +117,6 @@ void RasterBucket::setMask(TileMask&& mask_) {
}
vertices.updateModified();
indices.updateModified();
}
bool RasterBucket::hasData() const {

View File

@@ -161,9 +161,6 @@ public:
if (sharedOpacityVertices) {
sharedOpacityVertices->updateModified();
}
if (sharedTriangles) {
sharedTriangles->updateModified();
}
}
std::shared_ptr<VertexVector> sharedVertices = std::make_shared<VertexVector>();

View File

@@ -33,10 +33,6 @@ public:
const std::shared_ptr<UpdateParameters>&,
const RenderTree&,
UniqueChangeRequestVec&) override;
/// Remove all the drawables for tiles
/// @return The number of drawables actually removed.
std::size_t removeAllDrawables() override;
#endif
private:
@@ -67,6 +63,10 @@ private:
/// Remove all drawables for the tile from the layer group
/// @return The number of drawables actually removed.
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
/// @return The number of drawables actually removed.
std::size_t removeAllDrawables() override;
#endif
// Paint properties

View File

@@ -340,8 +340,8 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
[&](const gfx::UniqueDrawableBuilder& builder, gfx::Drawable* drawable, const RasterBucket& bucket) {
// The bucket may later add, remove, or change masking. In that case, the tile's
// shared data and segments are not updated, and it needs to be re-created.
if (drawable && (bucket.sharedVertices->isModifiedAfter(drawable->createTime) ||
bucket.sharedTriangles->isModifiedAfter(drawable->createTime))) {
if (drawable &&
(bucket.sharedVertices->isModifiedAfter(drawable->createTime) || bucket.sharedTriangles->getDirty())) {
return false;
}
@@ -464,8 +464,7 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
}
});
if (tileUpdateTime && (bucket.vertices.isModifiedAfter(*tileUpdateTime) ||
bucket.indices.isModifiedAfter(*tileUpdateTime))) {
if (tileUpdateTime && (bucket.vertices.isModifiedAfter(*tileUpdateTime) || bucket.indices.getDirty())) {
removeTile(renderPass, tileID);
cleared = true;
}

View File

@@ -98,9 +98,6 @@ public:
const std::shared_ptr<UpdateParameters>&,
const RenderTree&,
UniqueChangeRequestVec&) override;
/// Remove all the drawables for tiles
std::size_t removeAllDrawables() override;
#endif // MLN_DRAWABLE_RENDERER
protected:
@@ -122,6 +119,9 @@ protected:
/// Remove all drawables for the tile from the layer group
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
std::size_t removeAllDrawables() override;
#endif // MLN_DRAWABLE_RENDERER
private:

View File

@@ -191,9 +191,6 @@ public:
/// Returns the current renderability mode of the layer
bool isLayerRenderable() const noexcept { return isRenderable; }
/// Remove all the drawables for tiles
virtual std::size_t removeAllDrawables();
#endif
using Dependency = style::expression::Dependency;
@@ -250,6 +247,9 @@ protected:
/// @return The number of drawables actually removed.
virtual std::size_t removeTile(RenderPass, const OverscaledTileID&);
/// Remove all the drawables for tiles
virtual std::size_t removeAllDrawables();
/// Update `renderTileIDs` from `renderTiles`
void updateRenderTileIDs();

View File

@@ -993,13 +993,6 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders,
for (const auto& item : items) {
auto& renderLayer = item.layer.get();
#if MLN_RENDER_BACKEND_OPENGL
// Android Emulator: Goldfish is *very* broken. This will prevent a crash
// inside the GL translation layer at the cost of emulator performance.
if (androidGoldfishMitigationEnabled) {
renderLayer.removeAllDrawables();
}
#endif
renderLayer.update(shaders, context, state, updateParameters, renderTree, changes);
}
addChanges(changes);

View File

@@ -61,10 +61,6 @@ public:
const std::optional<std::string>& localFontFamily_);
~RenderOrchestrator() override;
#if MLN_RENDER_BACKEND_OPENGL
void enableAndroidEmulatorGoldfishMitigation(bool enable) { androidGoldfishMitigationEnabled = enable; }
#endif
void markContextLost() { contextLost = true; };
// TODO: Introduce RenderOrchestratorObserver.
void setObserver(RendererObserver*);
@@ -216,10 +212,6 @@ private:
bool placedSymbolDataCollected = false;
bool tileCacheEnabled = true;
#if MLN_RENDER_BACKEND_OPENGL
bool androidGoldfishMitigationEnabled{false};
#endif
// Vectors with reserved capacity of layerImpls->size() to avoid
// reallocation on each frame.
std::vector<Immutable<style::LayerProperties>> filteredLayersForSource;

View File

@@ -152,10 +152,4 @@ void Renderer::clearData() {
impl->orchestrator.clearData();
}
#if MLN_RENDER_BACKEND_OPENGL
void Renderer::enableAndroidEmulatorGoldfishMitigation(bool enable) {
impl->orchestrator.enableAndroidEmulatorGoldfishMitigation(enable);
}
#endif
} // namespace mbgl

View File

@@ -144,13 +144,12 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
// We need either raw index data or a buffer already created from them.
// We can have a buffer and no indexes, but only if it's not marked dirty.
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || !attributeUpdateTime ||
impl->indexes->isModifiedAfter(*attributeUpdateTime)))) {
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || impl->indexes->getDirty()))) {
assert(!"Missing index data");
return;
}
if (!impl->indexes->getBuffer() || !attributeUpdateTime || impl->indexes->isModifiedAfter(*attributeUpdateTime)) {
if (!impl->indexes->getBuffer() || impl->indexes->getDirty()) {
// Create a buffer for the index data. We don't update any
// existing buffer because it may still be in use by the previous frame.
auto indexBufferResource{uploadPass.createIndexBufferResource(
@@ -160,6 +159,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
auto buffer = std::make_unique<IndexBuffer>(std::move(indexBuffer));
impl->indexes->setBuffer(std::move(buffer));
impl->indexes->setDirty(false);
}
const bool buildAttribs = !vertexAttributes || !attributeUpdateTime ||