补充提交
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
#include <QApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QEventLoop>
|
||||
#include <QThread>
|
||||
#include <QTime>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
#include "../Renderive/Axis/Axis.h"
|
||||
#include "../Renderive/Axis/Frequency_Axis.h"
|
||||
#include "../Renderive/Axis/Time_Axis.h"
|
||||
#include "../Renderive/Axis/Time_Axis_p.h"
|
||||
#include "../Renderive/architecture/Plot.h"
|
||||
#include "../Renderive/architecture/Plot_p.h"
|
||||
#include "../Renderive/base/Memory.h"
|
||||
#include "../Renderive/plottable/Audio_Frequency.h"
|
||||
#include "../Renderive/plottable/Audio_Frequency_p.h"
|
||||
#include "../Renderive/plottable/Planisphere.h"
|
||||
#include "../Renderive/plottable/Planisphere_p.h"
|
||||
#include "../Renderive/plottable/Waterfall.h"
|
||||
#include "../Renderive/plottable/Waterfall_p.h"
|
||||
namespace {
|
||||
void process_events(int milliseconds) {
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while (timer.elapsed() < milliseconds) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 10);
|
||||
QThread::msleep(1);
|
||||
}
|
||||
}
|
||||
std::vector<double> make_frequency_data(int size, int frame) {
|
||||
std::vector<double> data(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
data[i] = -90.0 + 30.0 * std::sin(static_cast<double>(i + frame) * 0.017);
|
||||
return data;
|
||||
}
|
||||
bool wait_ready(const std::shared_ptr<renderive::Waterfall>& waterfall, const std::shared_ptr<renderive::Time_Axis>& time_axis, const std::shared_ptr<renderive::Audio_Frequency>& audio, const std::shared_ptr<renderive::Planisphere>& planisphere) {
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while (timer.elapsed() < 3000) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 10);
|
||||
if (waterfall->ok() && time_axis->ok() && audio->ok() && planisphere->ok())
|
||||
return true;
|
||||
QThread::msleep(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool wait_idle(renderive::Plot& plot) {
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
while (timer.elapsed() < 3000) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 10);
|
||||
if (!plot.is_rendering() && !plot.d->active_render_tasks.load(std::memory_order_acquire))
|
||||
return true;
|
||||
QThread::msleep(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int stress_data_paths() {
|
||||
renderive::Plot plot;
|
||||
plot.init();
|
||||
plot.resize(720, 420);
|
||||
auto data_node = plot.create_renderable_node(plot.get_root_renderable(), "Data_Renderable");
|
||||
auto axis_node = plot.create_renderable_node(plot.get_root_renderable(), "Axis_Renderable");
|
||||
auto frequency_axis = renderive::Frequency_Axis::Builder(axis_node, Qt::Horizontal).set_pixel_size(700).set_coord_range({0.0, 100.0}).build();
|
||||
auto time_axis = renderive::Time_Axis::Builder(axis_node, Qt::Vertical).set_pixel_size(400).set_time_point_size(32).build();
|
||||
auto value_axis = renderive::Axis::Builder(axis_node, Qt::Vertical).set_pixel_size(400).set_coord_range({-120.0, 0.0}).build();
|
||||
auto i_axis = renderive::Axis::Builder(axis_node, Qt::Horizontal).set_pixel_size(700).set_coord_range({-2.0, 2.0}).build();
|
||||
auto q_axis = renderive::Axis::Builder(axis_node, Qt::Vertical).set_pixel_size(400).set_coord_range({-2.0, 2.0}).build();
|
||||
auto waterfall = renderive::Waterfall::Builder(data_node, frequency_axis, time_axis).set_frequency_range({0.0, 100.0}).set_power_range({-120.0, 0.0}).set_frequency_point_size(64).build();
|
||||
auto audio = renderive::Audio_Frequency::Builder(data_node, time_axis, value_axis).set_time_point_size(32).set_key_range({-120.0, 0.0}).build();
|
||||
auto planisphere = renderive::Planisphere::Builder(data_node, i_axis, q_axis).set_i_range({-2.0, 2.0}).set_q_range({-2.0, 2.0}).set_continue_millisecond(500).build();
|
||||
plot.show();
|
||||
plot.start_render(240);
|
||||
if (!wait_ready(waterfall, time_axis, audio, planisphere))
|
||||
return 1;
|
||||
const int frequency_sizes[] = {64, 512, 8192, 8193, 128};
|
||||
const int time_sizes[] = {32, 96, 48, 64, 24};
|
||||
const renderive::Waterfall_Update_Mode update_modes[] = {
|
||||
renderive::Waterfall_Update_Mode::Batch,
|
||||
renderive::Waterfall_Update_Mode::Single_Line,
|
||||
renderive::Waterfall_Update_Mode::Timed_Latest,
|
||||
renderive::Waterfall_Update_Mode::Single_Line,
|
||||
renderive::Waterfall_Update_Mode::Batch
|
||||
};
|
||||
for (int stage = 0; stage < 5; ++stage) {
|
||||
waterfall->set_frequency_point_size(frequency_sizes[stage]);
|
||||
waterfall->set_update_mode(update_modes[stage]);
|
||||
waterfall->set_update_interval_ms(2);
|
||||
time_axis->set_time_point_size(time_sizes[stage]);
|
||||
audio->set_time_point_size(time_sizes[stage]);
|
||||
process_events(100);
|
||||
std::unordered_map<int, double> expected_frequency;
|
||||
QTime expected_time;
|
||||
double expected_power{};
|
||||
QPointF expected_position;
|
||||
for (int frame = 0; frame < time_sizes[stage] * 2; ++frame) {
|
||||
std::vector<double> frequency_data = make_frequency_data(frequency_sizes[stage], frame);
|
||||
expected_time = QTime::fromMSecsSinceStartOfDay((stage * 10000 + frame * 4) % 86400000);
|
||||
int tick = time_axis->give_data(expected_time);
|
||||
waterfall->give_data(tick, frequency_data);
|
||||
expected_frequency[tick] = frequency_data.front();
|
||||
expected_power = frequency_data[frame % frequency_data.size()];
|
||||
audio->give_data(tick, expected_power);
|
||||
double phase = static_cast<double>(frame) * 0.13;
|
||||
expected_position = {1.5 * std::cos(phase), 1.5 * std::sin(phase)};
|
||||
planisphere->give_data(expected_position);
|
||||
if ((frame & 3) == 3)
|
||||
process_events(8);
|
||||
}
|
||||
process_events(60);
|
||||
plot.pause_render();
|
||||
if (!wait_idle(plot))
|
||||
return 2;
|
||||
auto* waterfall_data = waterfall->d();
|
||||
if (waterfall_data->ring_buffer.col_count != frequency_sizes[stage] || waterfall_data->ring_buffer.row_count != time_sizes[stage])
|
||||
return 3;
|
||||
if (waterfall_data->image.width() != frequency_sizes[stage] || waterfall_data->image.height() != time_sizes[stage])
|
||||
return 4;
|
||||
int row_count = waterfall_data->ring_buffer.snapshot();
|
||||
int previous_tick{};
|
||||
for (int row = 0; row < row_count; ++row) {
|
||||
int tick = waterfall_data->ring_buffer.tick(row);
|
||||
auto expected = expected_frequency.find(tick);
|
||||
if (expected == expected_frequency.end())
|
||||
return 5;
|
||||
if (std::abs(waterfall_data->ring_buffer.frequency_data(row, 0, 0)[0] - expected->second) > 0.000001)
|
||||
return 6;
|
||||
if (row && tick >= previous_tick)
|
||||
return 7;
|
||||
previous_tick = tick;
|
||||
}
|
||||
auto* time_data = time_axis->d();
|
||||
if (time_data->time_ticker.time_point_size != time_sizes[stage] || time_data->time_snapshot.size() != static_cast<std::size_t>(time_sizes[stage]))
|
||||
return 8;
|
||||
if (!time_data->time_data_count || time_data->time_snapshot[time_data->time_data_count - 1] != expected_time)
|
||||
return 9;
|
||||
int lower = qMin(time_data->time_ticker.lower, time_data->time_ticker.upper());
|
||||
int upper = qMax(time_data->time_ticker.lower, time_data->time_ticker.upper());
|
||||
for (const renderive::Time_Tick& tick : time_data->data) {
|
||||
if (tick.tick < lower || tick.tick > upper)
|
||||
return 10;
|
||||
}
|
||||
auto* audio_data = audio->d();
|
||||
if (audio_data->point_count != time_sizes[stage] || audio_data->power_snapshot.size() != static_cast<std::size_t>(time_sizes[stage]))
|
||||
return 11;
|
||||
if (!audio_data->data_count || std::abs(audio_data->power_snapshot[audio_data->data_count - 1] - expected_power) > 0.000001)
|
||||
return 12;
|
||||
auto* planisphere_data = planisphere->d();
|
||||
if (planisphere_data->data_list.empty())
|
||||
return 13;
|
||||
QPointF actual_position = planisphere_data->data_list.back().pos;
|
||||
if (std::abs(actual_position.x() - expected_position.x()) > 0.000001 || std::abs(actual_position.y() - expected_position.y()) > 0.000001)
|
||||
return 14;
|
||||
plot.start_render(240);
|
||||
}
|
||||
for (int frame = 0; frame < 180; ++frame) {
|
||||
planisphere->set_continue_millisecond(500 + (frame & 1));
|
||||
process_events(8);
|
||||
}
|
||||
plot.pause_render();
|
||||
if (!wait_idle(plot))
|
||||
return 15;
|
||||
if (!planisphere->d()->data_list.empty())
|
||||
return 16;
|
||||
renderive::Memory_Stats stats = renderive::memory_stats();
|
||||
return stats.upstream_allocation_count && stats.upstream_peak_bytes ? 0 : 17;
|
||||
}
|
||||
}
|
||||
int main(int argc, char** argv) {
|
||||
QApplication app(argc, argv);
|
||||
renderive::start_render_scheduler();
|
||||
return stress_data_paths();
|
||||
}
|
||||
Reference in New Issue
Block a user