Files
Renderive/tests/Renderable_Lifecycle_Stress.cpp
2026-07-31 06:21:10 +08:00

96 lines
4.0 KiB
C++

#include <QApplication>
#include <QElapsedTimer>
#include <QEventLoop>
#include <QThread>
#include <gtest/gtest.h>
#include <cmath>
#include <memory>
#include <thread>
#include "../Renderive/Axis/Axis.h"
#include "../Renderive/Axis/Frequency_Axis.h"
#include "../Renderive/plot/Latency_Eager_Plot.h"
#include "../Renderive/plottable/Spectrum.h"
namespace {
std::vector<double> make_spectrum_data(int size, int frame) {
std::vector<double> data(size);
for (int i = 0; i < size; ++i)
data[i] = -80.0 + 20.0 * std::sin((double)(i + frame) * 0.03);
return data;
}
void process_events(int ms) {
QElapsedTimer timer;
timer.start();
while (timer.elapsed() < ms) {
QApplication::processEvents(QEventLoop::AllEvents, 10);
QThread::msleep(1);
}
}
void stress_remove_local_cache_renderable() {
renderive::Latency_Eager_Plot plot;
plot.init();
plot.resize(640, 360);
auto data = plot.create_renderable_node(plot.get_root_renderable(), "Data_Renderable");
auto axis = plot.create_renderable_node(plot.get_root_renderable(), "Axis_Renderable");
auto x_axis = renderive::Frequency_Axis::Builder(axis, Qt::Horizontal).set_pixel_size(620).set_coord_range({0.0, 100.0}).build();
auto y_axis = renderive::Axis::Builder(axis, Qt::Vertical).set_pixel_size(300).set_coord_range({-120.0, 0.0}).build();
auto spectrum = renderive::Spectrum::Builder(data, x_axis, y_axis).set_frequency_point_size(4096).set_frequency_range({0.0, 100.0}).set_sample_mode(renderive::Line_Sampling_Mode::Preserve_Extrema).build();
spectrum->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
plot.start_render(120);
for (int i = 0; i < 64; ++i) {
spectrum->give_data(make_spectrum_data(4096, i));
spectrum->mark_render_dirty();
}
plot.remove_renderable(spectrum);
spectrum.reset();
process_events(250);
}
void stress_plot_destroy_with_pending_tasks() {
for (int round = 0; round < 32; ++round) {
auto plot = std::make_unique<renderive::Latency_Eager_Plot>();
plot->init();
plot->resize(480, 240);
auto data = plot->create_renderable_node(plot->get_root_renderable(), "Data_Renderable");
auto axis = plot->create_renderable_node(plot->get_root_renderable(), "Axis_Renderable");
auto x_axis = renderive::Frequency_Axis::Builder(axis, Qt::Horizontal).set_pixel_size(460).set_coord_range({100.0, 0.0}).build();
auto y_axis = renderive::Axis::Builder(axis, Qt::Vertical).set_pixel_size(220).set_coord_range({0.0, -120.0}).build();
auto spectrum = renderive::Spectrum::Builder(data, x_axis, y_axis).set_frequency_point_size(2048).set_frequency_range({100.0, 0.0}).set_sample_mode(renderive::Line_Sampling_Mode::Preserve_Extrema).build();
spectrum->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
plot->start_render(120);
for (int frame = 0; frame < 16; ++frame) {
spectrum->give_data(make_spectrum_data(2048, frame));
spectrum->mark_render_dirty();
}
plot.reset();
spectrum.reset();
x_axis.reset();
y_axis.reset();
process_events(20);
}
}
void stress_release_renderable_after_plot_destroy() {
std::shared_ptr<renderive::Renderable> survivor;
{
renderive::Latency_Eager_Plot plot;
plot.init();
survivor = plot.create_renderable_node(plot.get_root_renderable(), "Survivor");
}
std::thread release_thread([owner = std::move(survivor)]() mutable {
owner.reset();
});
release_thread.join();
}
}
TEST(Renderable_Lifecycle_Stress, HandlesRemovalDestroyAndLateRelease) {
stress_remove_local_cache_renderable();
stress_plot_destroy_with_pending_tasks();
stress_release_renderable_after_plot_destroy();
process_events(250);
}
int main(int argc, char** argv) {
qputenv("QT_QPA_PLATFORM", "offscreen");
QApplication app(argc, argv);
testing::InitGoogleTest(&argc, argv);
renderive::start_render_scheduler();
return RUN_ALL_TESTS();
}