feat: admit settled Symbol render results to retained cache
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
@@ -10,8 +10,10 @@
|
||||
#include <mln/renderer/render_source.hpp>
|
||||
#include <mln/renderer/render_source_observer.hpp>
|
||||
#include <mln/renderer/tile_render_data.hpp>
|
||||
#include <mln/renderer/symbol_render_result.hpp>
|
||||
#include <mln/style/sources/geojson_source_impl.hpp>
|
||||
#include <mln/style/layers/symbol_layer.hpp>
|
||||
#include <mln/style/layers/background_layer.hpp>
|
||||
#include <mln/tile/tile.hpp>
|
||||
#include <mln/tile/tile_observer.hpp>
|
||||
|
||||
@@ -435,3 +437,137 @@ TEST(Step117Safety, RealAsyncCallbacksAndContextStyleCleanupAdvanceContentEpoch)
|
||||
scheduler.runRenderJobs();
|
||||
// Actual callback dispatch, but no network delivery, GPU, or Android assertion.
|
||||
}
|
||||
|
||||
namespace {
|
||||
void step119Certify(SymbolResultCertificate& certificate, SymbolResultBinding binding) {
|
||||
SymbolRenderResult result;
|
||||
result.append(255.0f);
|
||||
EXPECT_FALSE(certificate.observeFull(result, binding, true));
|
||||
certificate.completeFull(binding, true, false);
|
||||
EXPECT_TRUE(certificate.observeFull(result, binding, true));
|
||||
certificate.completeFull(binding, true, true);
|
||||
EXPECT_TRUE(certificate.observeFull(result, binding, true));
|
||||
certificate.completeFull(binding, true, false, true);
|
||||
EXPECT_TRUE(certificate.canFast(binding));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(Step119SymbolResults, RealTileGlyphImageStyleContextCallbacksRejectBuiltCertificate) {
|
||||
TaggedScheduler scheduler{Scheduler::GetBackground(), {}};
|
||||
RenderOrchestrator orchestrator(false, scheduler, std::nullopt);
|
||||
std::atomic<int> deferred{0}, jobs{0}, detached{0};
|
||||
auto source = std::make_unique<TeardownSource>(scheduler, deferred, jobs, detached);
|
||||
const auto rejects = [&](auto event) {
|
||||
SymbolResultBinding binding;
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
SymbolResultCertificate certificate;
|
||||
step119Certify(certificate, binding);
|
||||
event();
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
EXPECT_FALSE(certificate.canFast(binding));
|
||||
};
|
||||
rejects([&] {
|
||||
static_cast<RenderSourceObserver&>(orchestrator).onTileChanged(*source, OverscaledTileID{2, 1, {2, 1, 1}});
|
||||
});
|
||||
rejects([&] { static_cast<GlyphManagerObserver&>(orchestrator).onGlyphsLoaded({}, {0, 255}); });
|
||||
rejects([&] { static_cast<ImageManagerObserver&>(orchestrator).onStyleImageMissing("step119-icon", [] {}); });
|
||||
rejects([&] { orchestrator.markContextLost(); });
|
||||
rejects([&] { orchestrator.clearData(); });
|
||||
source->setObserver(nullptr);
|
||||
source.reset();
|
||||
scheduler.waitForEmpty();
|
||||
scheduler.runRenderJobs();
|
||||
}
|
||||
|
||||
TEST(Step119SymbolResults, AppliedCrossSegmentRegistryRebuildChangesExactEvidence) {
|
||||
TaggedScheduler scheduler{Scheduler::GetBackground(), {}};
|
||||
RenderOrchestrator orchestrator(false, scheduler, std::nullopt);
|
||||
auto runtime = std::make_shared<RetainedUnderlayRuntimeState>();
|
||||
style::BackgroundLayer lower("step119-lower"), continuous("step119-middle"), upper("step119-upper");
|
||||
const Immutable<std::vector<Immutable<style::Layer::Impl>>> layers =
|
||||
makeMutable<std::vector<Immutable<style::Layer::Impl>>>(
|
||||
std::initializer_list<Immutable<style::Layer::Impl>>{lower.baseImpl, continuous.baseImpl, upper.baseImpl});
|
||||
const Immutable<std::vector<Immutable<style::Source::Impl>>> sources =
|
||||
makeMutable<std::vector<Immutable<style::Source::Impl>>>();
|
||||
auto tree = orchestrator.createRenderTree(step117TreeParameters(layers, sources, runtime, TimePoint{}), nullptr);
|
||||
ASSERT_TRUE(tree);
|
||||
orchestrator.processChanges();
|
||||
auto group = std::make_shared<TestLayerGroup>(0);
|
||||
ASSERT_TRUE(orchestrator.addLayerGroup(group));
|
||||
ASSERT_TRUE(orchestrator.addLayerGroup(std::make_shared<TestLayerGroup>(2)));
|
||||
const auto before = orchestrator.retainedSymbolRenderResult(2, 3, 1, 0);
|
||||
ASSERT_TRUE(before.complete);
|
||||
SymbolResultCertificate certificate;
|
||||
SymbolResultBinding binding;
|
||||
step119Certify(certificate, binding);
|
||||
UniqueChangeRequestVec changes;
|
||||
changes.emplace_back(std::make_unique<RemoveLayerGroupRequest>(group));
|
||||
RenderOrchestratorTeardownTestAccess::enqueue(orchestrator, changes);
|
||||
const auto pending = orchestrator.retainedSymbolRenderResult(2, 3, 1, 0);
|
||||
EXPECT_FALSE(pending.complete);
|
||||
EXPECT_FALSE(certificate.observeFull(pending, binding, true));
|
||||
orchestrator.processChanges();
|
||||
EXPECT_EQ(orchestrator.numLayerGroups(), 1u);
|
||||
const auto after = orchestrator.retainedSymbolRenderResult(2, 3, 1, 0);
|
||||
EXPECT_TRUE(after.complete);
|
||||
EXPECT_NE(before.bytes, after.bytes); // actual global count + original ordinal changed
|
||||
EXPECT_FALSE(certificate.canFast(binding));
|
||||
}
|
||||
|
||||
TEST(Step119SymbolResults, RangeDrawFailureInvalidatesContentAndCompletedEvidence) {
|
||||
TaggedScheduler scheduler{Scheduler::GetBackground(), {}};
|
||||
RenderOrchestrator orchestrator(false, scheduler, std::nullopt);
|
||||
ErrorObserver observer;
|
||||
orchestrator.setObserver(&observer);
|
||||
ASSERT_TRUE(orchestrator.addLayerGroup(std::make_shared<TestLayerGroup>(0)));
|
||||
SymbolResultBinding binding;
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
SymbolResultCertificate certificate;
|
||||
step119Certify(certificate, binding);
|
||||
const auto errors = orchestrator.getRenderErrorRevision();
|
||||
bool failed = false;
|
||||
orchestrator.visitLayerGroupsInRange(0, 1, [](LayerGroupBase&, size_t) {
|
||||
throw std::runtime_error("step119-upload-or-draw");
|
||||
}, &failed);
|
||||
EXPECT_TRUE(failed);
|
||||
EXPECT_EQ(observer.errors, 1);
|
||||
EXPECT_GT(orchestrator.getRenderErrorRevision(), errors);
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
EXPECT_FALSE(certificate.canReuse(binding));
|
||||
EXPECT_FALSE(certificate.canFast(binding));
|
||||
}
|
||||
|
||||
TEST(Step119SymbolResults, RealSourceReplacementAndMissingSourceRetainFailClosed) {
|
||||
TaggedScheduler scheduler{Scheduler::GetBackground(), {}};
|
||||
RenderOrchestrator orchestrator(false, scheduler, std::nullopt);
|
||||
auto runtime = std::make_shared<RetainedUnderlayRuntimeState>();
|
||||
ASSERT_TRUE(runtime->setRenderSegmentPlan({1, {{RenderSegmentStrategy::Retained, std::nullopt}}}));
|
||||
style::SymbolLayer symbol("step119-symbol", "step119-source");
|
||||
const Immutable<std::vector<Immutable<style::Layer::Impl>>> layers =
|
||||
makeMutable<std::vector<Immutable<style::Layer::Impl>>>(
|
||||
std::initializer_list<Immutable<style::Layer::Impl>>{symbol.baseImpl});
|
||||
const auto sourceList = []() -> Immutable<std::vector<Immutable<style::Source::Impl>>> {
|
||||
return makeMutable<std::vector<Immutable<style::Source::Impl>>>(
|
||||
std::initializer_list<Immutable<style::Source::Impl>>{
|
||||
makeMutable<style::GeoJSONSource::Impl>("step119-source", style::GeoJSONOptions::defaultOptions())});
|
||||
};
|
||||
auto tree = orchestrator.createRenderTree(step117TreeParameters(layers, sourceList(), runtime, TimePoint{}), nullptr);
|
||||
ASSERT_TRUE(tree);
|
||||
SymbolResultBinding binding;
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
SymbolResultCertificate certificate;
|
||||
step119Certify(certificate, binding);
|
||||
tree.reset();
|
||||
tree = orchestrator.createRenderTree(step117TreeParameters(layers, sourceList(), runtime, TimePoint{} + Seconds(1)), nullptr);
|
||||
ASSERT_TRUE(tree);
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
EXPECT_FALSE(certificate.canFast(binding));
|
||||
tree.reset();
|
||||
const Immutable<std::vector<Immutable<style::Source::Impl>>> absent =
|
||||
makeMutable<std::vector<Immutable<style::Source::Impl>>>();
|
||||
tree = orchestrator.createRenderTree(step117TreeParameters(layers, absent, runtime, TimePoint{} + Seconds(2)), nullptr);
|
||||
ASSERT_TRUE(tree);
|
||||
EXPECT_STREQ(orchestrator.retainedSegmentSourceState(0, 1).reason, "missing-source");
|
||||
binding.content = orchestrator.getRetainedUnderlayContentRevision();
|
||||
EXPECT_FALSE(certificate.canFast(binding));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user