150 lines
6.2 KiB
C++
150 lines
6.2 KiB
C++
#include <mbgl/renderer/retained_underlay_cache.hpp>
|
|
|
|
#include <mbgl/gfx/color_mode.hpp>
|
|
#include <mbgl/gfx/context.hpp>
|
|
#include <mbgl/gfx/cull_face_mode.hpp>
|
|
#include <mbgl/gfx/drawable_builder.hpp>
|
|
#include <mbgl/gfx/offscreen_texture.hpp>
|
|
#include <mbgl/gfx/render_pass.hpp>
|
|
#include <mbgl/gfx/upload_pass.hpp>
|
|
#include <mbgl/gfx/vertex_attribute.hpp>
|
|
#include <mbgl/particle/renderer_debug_counters.hpp>
|
|
#include <mbgl/renderer/buckets/heatmap_bucket.hpp>
|
|
#include <mbgl/renderer/layer_group.hpp>
|
|
#include <mbgl/renderer/paint_parameters.hpp>
|
|
#include <mbgl/renderer/render_orchestrator.hpp>
|
|
#include <mbgl/renderer/render_static_data.hpp>
|
|
#include <mbgl/shaders/shader_defines.hpp>
|
|
|
|
namespace mbgl {
|
|
|
|
namespace {
|
|
constexpr auto CompositeShaderName = "RetainedUnderlayCompositeShader";
|
|
}
|
|
|
|
RetainedUnderlayCache::RetainedUnderlayCache() = default;
|
|
RetainedUnderlayCache::~RetainedUnderlayCache() = default;
|
|
|
|
RetainedUnderlayDecision RetainedUnderlayCache::evaluate(const std::optional<RetainedUnderlayKey>& nextKey,
|
|
bool supported,
|
|
const char* fallbackReason) {
|
|
if (!nextKey) return RetainedUnderlayDecision::Disabled;
|
|
if (!supported) {
|
|
++fallbackCount;
|
|
particle::incrementRendererDebugCounter(particle::RendererDebugCounter::RetainedUnderlayFallback);
|
|
invalidate(fallbackReason ? fallbackReason : "unsupported");
|
|
return RetainedUnderlayDecision::Fallback;
|
|
}
|
|
if (!key || *key != *nextKey) {
|
|
const char* reason = !key ? "first-frame" : (key->viewport != nextKey->viewport ? "viewport" : "camera-or-boundary");
|
|
invalidate(reason);
|
|
key = nextKey;
|
|
}
|
|
if (valid) {
|
|
++reuseCount;
|
|
particle::incrementRendererDebugCounter(particle::RendererDebugCounter::RetainedUnderlayReuse);
|
|
return RetainedUnderlayDecision::Reuse;
|
|
}
|
|
return RetainedUnderlayDecision::Build;
|
|
}
|
|
|
|
bool RetainedUnderlayCache::prepareResources(gfx::Context& context,
|
|
gfx::ShaderRegistry& shaders,
|
|
const RetainedUnderlayKey& nextKey) {
|
|
try {
|
|
if (!offscreenTexture || offscreenTexture->getSize() != nextKey.viewport) {
|
|
offscreenTexture = context.createOffscreenTexture(
|
|
nextKey.viewport, gfx::TextureChannelDataType::UnsignedByte, true, true);
|
|
compositeLayerGroup.reset();
|
|
}
|
|
if (!offscreenTexture || !offscreenTexture->isRenderable()) return false;
|
|
return compositeLayerGroup || rebuildComposite(context, shaders);
|
|
} catch (...) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool RetainedUnderlayCache::rebuildComposite(gfx::Context& context, gfx::ShaderRegistry& shaders) {
|
|
auto shader = context.getGenericShader(shaders, CompositeShaderName);
|
|
auto group = context.createLayerGroup(0, 1, "retained-underlay-composite");
|
|
if (!shader || !group || !offscreenTexture) return false;
|
|
|
|
auto vertices = std::make_shared<gfx::VertexVector<HeatmapTextureLayoutVertex>>(
|
|
RenderStaticData::heatmapTextureVertices());
|
|
auto attributes = context.createVertexAttributeArray();
|
|
if (const auto& attribute = attributes->set(shaders::idRetainedUnderlayCompositePosVertexAttribute)) {
|
|
attribute->setSharedRawData(vertices,
|
|
offsetof(HeatmapTextureLayoutVertex, a1),
|
|
0,
|
|
sizeof(HeatmapTextureLayoutVertex),
|
|
gfx::AttributeDataType::Short2);
|
|
}
|
|
|
|
auto builder = context.createDrawableBuilder("retained-underlay-composite");
|
|
builder->setShader(std::move(shader));
|
|
builder->setEnableDepth(false);
|
|
builder->setColorMode(gfx::ColorMode::alphaBlended());
|
|
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
|
builder->setRenderPass(RenderPass::Translucent);
|
|
builder->setVertexAttributes(std::move(attributes));
|
|
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
|
|
auto segments = RenderStaticData::heatmapTextureSegments();
|
|
builder->setSegments(gfx::Triangles(),
|
|
RenderStaticData::quadTriangleIndices().vector(),
|
|
segments.data(),
|
|
segments.size());
|
|
builder->setTexture(offscreenTexture->getTexture(), shaders::idRetainedUnderlayCompositeTexture);
|
|
builder->flush(context);
|
|
for (auto& drawable : builder->clearDrawables()) group->addDrawable(std::move(drawable));
|
|
compositeLayerGroup = std::move(group);
|
|
return !compositeLayerGroup->empty();
|
|
}
|
|
|
|
void RetainedUnderlayCache::upload(gfx::UploadPass& uploadPass) {
|
|
if (compositeLayerGroup) compositeLayerGroup->upload(uploadPass);
|
|
}
|
|
|
|
void RetainedUnderlayCache::beginBuild(PaintParameters& parameters) {
|
|
parameters.renderPass = parameters.encoder->createRenderPass(
|
|
"retained static underlay",
|
|
{.renderable = *offscreenTexture,
|
|
.clearColor = Color{0.0f, 0.0f, 0.0f, 0.0f},
|
|
.clearDepth = 1.0f,
|
|
.clearStencil = 0});
|
|
#if MLN_RENDER_BACKEND_OPENGL
|
|
parameters.updateStencilBufferAvailability();
|
|
#endif
|
|
}
|
|
|
|
void RetainedUnderlayCache::finishBuild(PaintParameters& parameters) {
|
|
parameters.renderPass.reset();
|
|
parameters.encoder->present(*offscreenTexture);
|
|
}
|
|
|
|
void RetainedUnderlayCache::composite(RenderOrchestrator& orchestrator, PaintParameters& parameters) {
|
|
if (!compositeLayerGroup) return;
|
|
parameters.pass = RenderPass::Translucent;
|
|
parameters.currentLayer = 0;
|
|
compositeLayerGroup->render(orchestrator, parameters);
|
|
}
|
|
|
|
void RetainedUnderlayCache::markBuildSucceeded() {
|
|
valid = true;
|
|
++buildCount;
|
|
particle::incrementRendererDebugCounter(particle::RendererDebugCounter::RetainedUnderlayBuild);
|
|
}
|
|
|
|
void RetainedUnderlayCache::markBuildFailed(const char* reason) {
|
|
++fallbackCount;
|
|
particle::incrementRendererDebugCounter(particle::RendererDebugCounter::RetainedUnderlayFallback);
|
|
invalidate(reason);
|
|
}
|
|
|
|
void RetainedUnderlayCache::invalidate(const char* reason) {
|
|
valid = false;
|
|
lastInvalidationReason = reason ? reason : "unknown";
|
|
particle::incrementRendererDebugCounter(particle::RendererDebugCounter::RetainedUnderlayInvalidation);
|
|
}
|
|
|
|
} // namespace mbgl
|