Revert index buffers to dirty flag instead of timestamps (#2927)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); });
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -74,7 +74,6 @@ void CircleBucket::update(const FeatureStates& states,
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,6 @@ void FillBucket::update(const FeatureStates& states,
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedBasicLineIndexes->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,6 @@ void FillExtrusionBucket::update(const FeatureStates& states,
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -168,7 +168,6 @@ void LineBucket::update(const FeatureStates& states,
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -161,9 +161,6 @@ public:
|
||||
if (sharedOpacityVertices) {
|
||||
sharedOpacityVertices->updateModified();
|
||||
}
|
||||
if (sharedTriangles) {
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<VertexVector> sharedVertices = std::make_shared<VertexVector>();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
Reference in New Issue
Block a user