策略抽离
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
namespace renderive {
|
||||
struct Band_Region_Render_State : Render_State, Band_Region_Prop {};
|
||||
struct Band_Region_Private : Typed_Render_Data<Band_Region, Band_Region_Render_State, Input_Data> {
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Band_Region_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -67,7 +67,7 @@ std::shared_ptr<Band_Region> Band_Region::Builder::build() {
|
||||
auto ret = renderive::make_shared<Band_Region>();
|
||||
ret->init(parent);
|
||||
Band_Region_Private* pd = ret->d();
|
||||
Band_Region_Render_State* sc = reinterpret_cast<Band_Region_Render_State*>(pd->state(State_Edit));
|
||||
Band_Region_Render_State* sc = reinterpret_cast<Band_Region_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(Range, range)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <utility>
|
||||
#include "../base/Memory.h"
|
||||
#include "../base/String_Format.h"
|
||||
#include "../architecture/Render_Lease.h"
|
||||
#include "../flow/low_latency/Render_Lease.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../render/Image.h"
|
||||
|
||||
@@ -47,7 +47,7 @@ struct Color_Bar_Private : Typed_Render_Data<Color_Bar, Color_Bar_Render_State,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot& snapshot) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot) override {
|
||||
Color_Bar_Render_State* s = render_state();
|
||||
auto scale = s->color_scale.snapshot();
|
||||
if (scale->range.length() == 0.0)
|
||||
@@ -146,7 +146,7 @@ std::shared_ptr<Color_Bar> Color_Bar::Builder::build() {
|
||||
auto ret = renderive::make_shared<Color_Bar>();
|
||||
ret->init(parent);
|
||||
Color_Bar_Private* pd = ret->d();
|
||||
Color_Bar_Render_State* sc = reinterpret_cast<Color_Bar_Render_State*>(pd->state(State_Edit));
|
||||
Color_Bar_Render_State* sc = reinterpret_cast<Color_Bar_Render_State*>(pd->edit_state());
|
||||
sc->color_scale = color_scale.clone();
|
||||
PROP_R(std::string, name)
|
||||
PROP_R(std::string, unit)
|
||||
|
||||
+64
-38
@@ -9,6 +9,7 @@
|
||||
#include <optional>
|
||||
#include <rigtorp/MPMCQueue.h>
|
||||
#include <system_error>
|
||||
#include <variant>
|
||||
#include "../base/Memory.h"
|
||||
#include "../render/Canvas.h"
|
||||
namespace renderive {
|
||||
@@ -19,36 +20,62 @@ enum class Curve_Input_Mode : std::uint8_t {
|
||||
};
|
||||
struct Curve_Input_Data : Input_Data {};
|
||||
struct Curve_Render_State : Render_State, Curve_Prop {};
|
||||
struct Curve_Sample_Source {
|
||||
Curve_Sample_Source() : values(memory_resource(Memory_Domain::Curve)) {}
|
||||
explicit Curve_Sample_Source(std::span<const double> input) : values(memory_resource(Memory_Domain::Curve)) {
|
||||
values.assign(input.begin(), input.end());
|
||||
}
|
||||
explicit Curve_Sample_Source(std::pmr::vector<double>&& input) : values(std::move(input)) {}
|
||||
std::pmr::vector<double> values;
|
||||
};
|
||||
struct Curve_Point_Source {
|
||||
Curve_Point_Source() : values(memory_resource(Memory_Domain::Curve)) {}
|
||||
explicit Curve_Point_Source(std::span<const PointF> input) : values(memory_resource(Memory_Domain::Curve)) {
|
||||
values.assign(input.begin(), input.end());
|
||||
}
|
||||
explicit Curve_Point_Source(std::pmr::vector<PointF>&& input) : values(std::move(input)) {}
|
||||
std::pmr::vector<PointF> values;
|
||||
};
|
||||
using Curve_Source = std::variant<std::monostate, Curve_Sample_Source, Curve_Point_Source>;
|
||||
static Curve_Input_Mode curve_source_mode(const Curve_Source& source) {
|
||||
if (std::holds_alternative<Curve_Sample_Source>(source))
|
||||
return Curve_Input_Mode::Samples;
|
||||
if (std::holds_alternative<Curve_Point_Source>(source))
|
||||
return Curve_Input_Mode::Points;
|
||||
return Curve_Input_Mode::None;
|
||||
}
|
||||
static std::size_t curve_sample_count(const Curve_Source& source) {
|
||||
const auto* samples = std::get_if<Curve_Sample_Source>(&source);
|
||||
return samples ? samples->values.size() : 0u;
|
||||
}
|
||||
static std::size_t curve_point_count(const Curve_Source& source) {
|
||||
const auto* points = std::get_if<Curve_Point_Source>(&source);
|
||||
return points ? points->values.size() : 0u;
|
||||
}
|
||||
struct Curve_Input_Block {
|
||||
Curve_Input_Mode mode = Curve_Input_Mode::None;
|
||||
std::pmr::vector<double> samples{memory_resource(Memory_Domain::Curve)};
|
||||
std::pmr::vector<PointF> points{memory_resource(Memory_Domain::Curve)};
|
||||
std::shared_ptr<const Curve_Source> source = std::make_shared<Curve_Source>();
|
||||
std::shared_ptr<Update_State> completion_state;
|
||||
static std::shared_ptr<Curve_Input_Block> samples_block(std::span<const double> values, std::shared_ptr<Update_State> state = {}) {
|
||||
auto block = std::make_shared<Curve_Input_Block>();
|
||||
block->mode = Curve_Input_Mode::Samples;
|
||||
block->samples.assign(values.begin(), values.end());
|
||||
block->source = std::make_shared<Curve_Source>(Curve_Sample_Source(values));
|
||||
block->completion_state = std::move(state);
|
||||
return block;
|
||||
}
|
||||
static std::shared_ptr<Curve_Input_Block> samples_block(std::pmr::vector<double>&& values, std::shared_ptr<Update_State> state = {}) {
|
||||
auto block = std::make_shared<Curve_Input_Block>();
|
||||
block->mode = Curve_Input_Mode::Samples;
|
||||
block->samples = std::move(values);
|
||||
block->source = std::make_shared<Curve_Source>(Curve_Sample_Source(std::move(values)));
|
||||
block->completion_state = std::move(state);
|
||||
return block;
|
||||
}
|
||||
static std::shared_ptr<Curve_Input_Block> points_block(std::span<const PointF> values, std::shared_ptr<Update_State> state = {}) {
|
||||
auto block = std::make_shared<Curve_Input_Block>();
|
||||
block->mode = Curve_Input_Mode::Points;
|
||||
block->points.assign(values.begin(), values.end());
|
||||
block->source = std::make_shared<Curve_Source>(Curve_Point_Source(values));
|
||||
block->completion_state = std::move(state);
|
||||
return block;
|
||||
}
|
||||
static std::shared_ptr<Curve_Input_Block> points_block(std::pmr::vector<PointF>&& values, std::shared_ptr<Update_State> state = {}) {
|
||||
auto block = std::make_shared<Curve_Input_Block>();
|
||||
block->mode = Curve_Input_Mode::Points;
|
||||
block->points = std::move(values);
|
||||
block->source = std::make_shared<Curve_Source>(Curve_Point_Source(std::move(values)));
|
||||
block->completion_state = std::move(state);
|
||||
return block;
|
||||
}
|
||||
@@ -94,15 +121,14 @@ struct Curve_Geometry_Result {
|
||||
std::pmr::vector<std::shared_ptr<Update_State>> update_states;
|
||||
};
|
||||
struct Curve_Geometry_Request {
|
||||
Curve_Geometry_Request() : samples(memory_resource(Memory_Domain::Curve)), data_points(memory_resource(Memory_Domain::Curve)), update_states(memory_resource(Memory_Domain::Update_Completion)) {}
|
||||
Curve_Geometry_Request() : update_states(memory_resource(Memory_Domain::Update_Completion)) {}
|
||||
Curve_Input_Mode mode = Curve_Input_Mode::None;
|
||||
Axis_Mapping_2D mapping;
|
||||
Range data_range{0.0, 1.0};
|
||||
bool visible_range_only{};
|
||||
Line_Interpolation_Mode interpolation_mode = Line_Interpolation_Mode::Linear_Value;
|
||||
Line_Sampling_Strategy sample_mode = Line_Sampling_Strategy::Pixel_Min_Max_Envelope;
|
||||
std::pmr::vector<double> samples;
|
||||
std::pmr::vector<PointF> data_points;
|
||||
std::shared_ptr<const Curve_Source> source;
|
||||
std::pmr::vector<std::shared_ptr<Update_State>> update_states;
|
||||
};
|
||||
static Curve_Axis_Geometry_Key curve_axis_key(const Axis_Frame_Snapshot& axis) {
|
||||
@@ -124,29 +150,30 @@ static void complete_curve_result_states(Curve_Geometry_Result& result, std::err
|
||||
}
|
||||
static void build_curve_geometry(Curve_Geometry_Result& result, const Curve_Geometry_Request& request) {
|
||||
std::pmr::vector<PointF>& points = result.points;
|
||||
if (request.mode == Curve_Input_Mode::Points) {
|
||||
points.reserve(request.data_points.size());
|
||||
for (std::size_t i = 0; i < request.data_points.size(); ++i)
|
||||
points.push_back(request.mapping.map(request.data_points[i]));
|
||||
if (!request.source)
|
||||
return;
|
||||
if (const auto* data_points = std::get_if<Curve_Point_Source>(request.source.get())) {
|
||||
points.reserve(data_points->values.size());
|
||||
for (std::size_t i = 0; i < data_points->values.size(); ++i)
|
||||
points.push_back(request.mapping.map(data_points->values[i]));
|
||||
return;
|
||||
}
|
||||
if (request.mode != Curve_Input_Mode::Samples || request.samples.size() < 2 || request.data_range.length() == 0.0)
|
||||
const auto* samples = std::get_if<Curve_Sample_Source>(request.source.get());
|
||||
if (!samples || samples->values.size() < 2 || request.data_range.length() == 0.0)
|
||||
return;
|
||||
if (request.sample_mode == Line_Sampling_Strategy::Pixel_Min_Max_Envelope) {
|
||||
points = Curve_Utils::build_pixel_envelope_points(request.mapping, request.data_range, static_cast<int>(request.samples.size()), static_cast<int>(request.samples.size()), request.visible_range_only, [&request](int i) {
|
||||
return request.samples[static_cast<std::size_t>(i)];
|
||||
points = Curve_Utils::build_pixel_envelope_points(request.mapping, request.data_range, static_cast<int>(samples->values.size()), static_cast<int>(samples->values.size()), request.visible_range_only, [samples](int i) {
|
||||
return samples->values[static_cast<std::size_t>(i)];
|
||||
}, memory_resource(Memory_Domain::Curve));
|
||||
return;
|
||||
}
|
||||
points = Curve_Utils::build_resampled_points(request.mapping, request.data_range, static_cast<int>(request.samples.size()), static_cast<int>(request.samples.size()), request.visible_range_only, request.interpolation_mode, [&request](int i) {
|
||||
return request.samples[static_cast<std::size_t>(i)];
|
||||
points = Curve_Utils::build_resampled_points(request.mapping, request.data_range, static_cast<int>(samples->values.size()), static_cast<int>(samples->values.size()), request.visible_range_only, request.interpolation_mode, [samples](int i) {
|
||||
return samples->values[static_cast<std::size_t>(i)];
|
||||
}, memory_resource(Memory_Domain::Curve));
|
||||
}
|
||||
struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_Data> {
|
||||
static constexpr std::size_t Input_Queue_Capacity = 8;
|
||||
std::pmr::vector<double> samples{memory_resource(Memory_Domain::Curve)};
|
||||
std::pmr::vector<PointF> data_points{memory_resource(Memory_Domain::Curve)};
|
||||
Curve_Input_Mode mode = Curve_Input_Mode::None;
|
||||
std::shared_ptr<const Curve_Source> source = std::make_shared<Curve_Source>();
|
||||
rigtorp::MPMCQueue<std::shared_ptr<Curve_Input_Block>> input_queue;
|
||||
std::atomic_uint64_t dropped_input_count{0};
|
||||
std::pmr::vector<std::shared_ptr<Update_State>> pending_geometry_update_states{memory_resource(Memory_Domain::Update_Completion)};
|
||||
@@ -195,16 +222,14 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
|
||||
}
|
||||
if (!selected)
|
||||
return;
|
||||
mode = selected->mode;
|
||||
samples = std::move(selected->samples);
|
||||
data_points = std::move(selected->points);
|
||||
source = std::move(selected->source);
|
||||
++input_generation;
|
||||
if (selected->completion_state) {
|
||||
selected->completion_state->complete_until(Update_Stage::Committed);
|
||||
pending_geometry_update_states.push_back(std::move(selected->completion_state));
|
||||
}
|
||||
}
|
||||
void prepare_data(const Plot_Render_Snapshot& snapshot) override {
|
||||
void prepare_data(const Render_Frame_Snapshot& snapshot) override {
|
||||
(void)snapshot;
|
||||
sync_state_pipeline();
|
||||
consume_input_queue();
|
||||
@@ -226,27 +251,26 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
|
||||
Curve_Geometry_Key key;
|
||||
key.input_generation = input_generation;
|
||||
key.state_version = s->version;
|
||||
key.mode = mode;
|
||||
key.mode = source ? curve_source_mode(*source) : Curve_Input_Mode::None;
|
||||
key.sample_mode = s->sample_mode;
|
||||
key.interpolation_mode = s->interpolation_mode;
|
||||
key.visible_range_only = s->visible_range_only;
|
||||
key.data_range = s->data_range;
|
||||
key.sample_count = samples.size();
|
||||
key.point_count = data_points.size();
|
||||
key.sample_count = source ? curve_sample_count(*source) : 0u;
|
||||
key.point_count = source ? curve_point_count(*source) : 0u;
|
||||
key.domain = curve_axis_key(mapping.domain);
|
||||
key.value = curve_axis_key(mapping.value);
|
||||
if (submitted_geometry_key && key == *submitted_geometry_key)
|
||||
return;
|
||||
submitted_geometry_key = key;
|
||||
auto request = std::make_shared<Curve_Geometry_Request>();
|
||||
request->mode = mode;
|
||||
request->mode = key.mode;
|
||||
request->mapping = mapping;
|
||||
request->data_range = s->data_range;
|
||||
request->visible_range_only = s->visible_range_only;
|
||||
request->interpolation_mode = s->interpolation_mode;
|
||||
request->sample_mode = s->sample_mode;
|
||||
request->samples = samples;
|
||||
request->data_points = data_points;
|
||||
request->source = source;
|
||||
request->update_states = std::move(pending_geometry_update_states);
|
||||
pending_geometry_update_states = std::pmr::vector<std::shared_ptr<Update_State>>(memory_resource(Memory_Domain::Update_Completion));
|
||||
geometry_result.emplace();
|
||||
@@ -254,7 +278,7 @@ struct Curve_Private : Typed_Render_Data<Curve, Curve_Render_State, Curve_Input_
|
||||
build_curve_geometry(*geometry_result, *request);
|
||||
geometry_result->update_states = std::move(request->update_states);
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot& snapshot) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot) override {
|
||||
Curve_Render_State* s = render_state();
|
||||
if (!geometry_result)
|
||||
return;
|
||||
@@ -361,7 +385,7 @@ std::shared_ptr<Curve> Curve::Builder::build() {
|
||||
auto ret = renderive::make_shared<Curve>();
|
||||
ret->init(parent);
|
||||
Curve_Private* pd = ret->d();
|
||||
Curve_Render_State* sc = reinterpret_cast<Curve_Render_State*>(pd->state(State_Edit));
|
||||
Curve_Render_State* sc = reinterpret_cast<Curve_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(Range, data_range)
|
||||
@@ -397,6 +421,8 @@ void Curve_Utils::draw_fill_to_value(Canvas* canvas, std::span<const PointF> poi
|
||||
void Curve_Utils::append_envelope_point(std::pmr::vector<PointF>& points, const Axis_Mapping_2D& mapping, const Range& data_range, int total_count, int index, double value) {
|
||||
if (index < 0)
|
||||
return;
|
||||
if (!std::isfinite(value))
|
||||
return;
|
||||
PointF point = mapping.map(source_index_to_coordinate(data_range, total_count, index), value);
|
||||
if (!points.empty() && points.back().x == point.x && points.back().y == point.y)
|
||||
return;
|
||||
|
||||
@@ -32,35 +32,36 @@ public:
|
||||
}
|
||||
template <typename Value_At>
|
||||
static std::pmr::vector<PointF> build_resampled_points(Abs_Axis* domain_axis, Abs_Axis* value_axis, const Range& sample_domain_range, int source_sample_count, int available_sample_count, bool visible_range_only, Line_Interpolation_Mode mode, Value_At value_at) {
|
||||
(void)mode;
|
||||
return build_sample_line_points(Axis_Render_Access::mapping(domain_axis, value_axis), sample_domain_range, source_sample_count, available_sample_count, visible_range_only, value_at, frame_memory_resource());
|
||||
return build_sample_line_points(Axis_Render_Access::mapping(domain_axis, value_axis), sample_domain_range, source_sample_count, available_sample_count, visible_range_only, mode, value_at, frame_memory_resource());
|
||||
}
|
||||
template <typename Value_At>
|
||||
static std::pmr::vector<PointF> build_resampled_points(const Axis_Mapping_2D& mapping, const Range& sample_domain_range, int source_sample_count, int available_sample_count, bool visible_range_only, Line_Interpolation_Mode mode, Value_At value_at, std::pmr::memory_resource* resource = frame_memory_resource()) {
|
||||
(void)mode;
|
||||
return build_sample_line_points(mapping, sample_domain_range, source_sample_count, available_sample_count, visible_range_only, value_at, resource);
|
||||
return build_sample_line_points(mapping, sample_domain_range, source_sample_count, available_sample_count, visible_range_only, mode, value_at, resource);
|
||||
}
|
||||
template <typename Value_At>
|
||||
static std::pmr::vector<PointF> build_pixel_envelope_points(const Axis_Mapping_2D& mapping, const Range& sample_domain_range, int source_sample_count, int available_sample_count, bool visible_range_only, Value_At value_at, std::pmr::memory_resource* resource = frame_memory_resource()) {
|
||||
Visible_Sample_Window window = compute_visible_sample_window(mapping.domain, sample_domain_range, source_sample_count, available_sample_count, visible_range_only);
|
||||
if (!window)
|
||||
return {};
|
||||
int first_source = std::clamp(static_cast<int>(std::floor(std::min(window.first_index, window.last_index))), 0, available_sample_count - 1);
|
||||
int last_source = std::clamp(static_cast<int>(std::ceil(std::max(window.first_index, window.last_index))), first_source, available_sample_count - 1);
|
||||
double first_pixel = mapping.domain.coord_to_pixel(source_index_to_coordinate(sample_domain_range, source_sample_count, window.first_index));
|
||||
double last_pixel = mapping.domain.coord_to_pixel(source_index_to_coordinate(sample_domain_range, source_sample_count, window.last_index));
|
||||
double pixel_min = std::min(first_pixel, last_pixel);
|
||||
double pixel_max = std::max(first_pixel, last_pixel);
|
||||
int bucket_count = std::max(1, static_cast<int>(std::ceil(pixel_max - pixel_min)) + 1);
|
||||
double first_index = std::clamp(std::min(window.first_index, window.last_index), 0.0, static_cast<double>(available_sample_count - 1));
|
||||
double last_index = std::clamp(std::max(window.first_index, window.last_index), first_index, static_cast<double>(available_sample_count - 1));
|
||||
int first_source = std::clamp(static_cast<int>(std::ceil(first_index)), 0, available_sample_count - 1);
|
||||
int last_source = std::clamp(static_cast<int>(std::floor(last_index)), first_source, available_sample_count - 1);
|
||||
double first_pixel = mapping.domain.coord_to_pixel(source_index_to_coordinate(sample_domain_range, source_sample_count, first_index));
|
||||
double last_pixel = mapping.domain.coord_to_pixel(source_index_to_coordinate(sample_domain_range, source_sample_count, last_index));
|
||||
int pixel_floor_min = static_cast<int>(std::floor(std::min(first_pixel, last_pixel)));
|
||||
int pixel_floor_max = static_cast<int>(std::floor(std::max(first_pixel, last_pixel)));
|
||||
int bucket_count = std::max(1, pixel_floor_max - pixel_floor_min + 1);
|
||||
bucket_count = std::min(bucket_count, mapping.domain.pixel_size() + 1);
|
||||
std::pmr::vector<Pixel_Envelope_Bucket> buckets(bucket_count, resource);
|
||||
double pixel_span = std::max(1.0, pixel_max - pixel_min);
|
||||
for (int i = first_source; i <= last_source; ++i) {
|
||||
double value = value_at(i);
|
||||
if (!std::isfinite(value))
|
||||
continue;
|
||||
double coord = source_index_to_coordinate(sample_domain_range, source_sample_count, i);
|
||||
double pixel = mapping.domain.coord_to_pixel(coord);
|
||||
int bucket_index = std::clamp(static_cast<int>((pixel - pixel_min) * static_cast<double>(bucket_count - 1) / pixel_span), 0, bucket_count - 1);
|
||||
int bucket_index = std::clamp(static_cast<int>(std::floor(pixel)) - pixel_floor_min, 0, bucket_count - 1);
|
||||
Pixel_Envelope_Bucket& bucket = buckets[bucket_index];
|
||||
double value = value_at(i);
|
||||
if (!bucket.has_samples) {
|
||||
bucket.has_samples = true;
|
||||
bucket.first_index = i;
|
||||
@@ -80,9 +81,25 @@ public:
|
||||
}
|
||||
}
|
||||
std::pmr::vector<PointF> points(resource);
|
||||
points.reserve(bucket_count * 4);
|
||||
bool pixel_forward = first_pixel <= last_pixel;
|
||||
for (int b = pixel_forward ? 0 : bucket_count - 1; pixel_forward ? b < bucket_count : b >= 0; pixel_forward ? ++b : --b) {
|
||||
points.reserve(bucket_count * 4 + 2);
|
||||
double last_appended_index = -std::numeric_limits<double>::infinity();
|
||||
auto append_index = [&](double index) {
|
||||
if (std::abs(index - last_appended_index) <= 1e-9)
|
||||
return;
|
||||
double value = interpolate_sample_value(index, available_sample_count, Line_Interpolation_Mode::Linear_Value, value_at);
|
||||
if (!std::isfinite(value))
|
||||
return;
|
||||
PointF point = mapping.map(source_index_to_coordinate(sample_domain_range, source_sample_count, index), value);
|
||||
if (!points.empty() && points.back().x == point.x && points.back().y == point.y)
|
||||
return;
|
||||
points.push_back(point);
|
||||
last_appended_index = index;
|
||||
};
|
||||
append_index(first_index);
|
||||
int first_bucket = std::clamp(static_cast<int>(std::floor(first_pixel)) - pixel_floor_min, 0, bucket_count - 1);
|
||||
int last_bucket = std::clamp(static_cast<int>(std::floor(last_pixel)) - pixel_floor_min, 0, bucket_count - 1);
|
||||
bool bucket_forward = first_bucket <= last_bucket;
|
||||
for (int b = bucket_forward ? 0 : bucket_count - 1; bucket_forward ? b < bucket_count : b >= 0; bucket_forward ? ++b : --b) {
|
||||
const Pixel_Envelope_Bucket& bucket = buckets[b];
|
||||
if (!bucket.has_samples)
|
||||
continue;
|
||||
@@ -90,8 +107,9 @@ public:
|
||||
std::sort(indexes.begin(), indexes.end());
|
||||
auto end = std::unique(indexes.begin(), indexes.end());
|
||||
for (auto it = indexes.begin(); it != end; ++it)
|
||||
append_envelope_point(points, mapping, sample_domain_range, source_sample_count, *it, value_at(*it));
|
||||
append_index(static_cast<double>(*it));
|
||||
}
|
||||
append_index(last_index);
|
||||
return points;
|
||||
}
|
||||
template <typename Value_At>
|
||||
|
||||
@@ -28,7 +28,7 @@ struct Fill_Area_Input_Data : Latest_Input_Data {
|
||||
struct Fill_Area_Render_State : Render_State, Fill_Area_Prop {};
|
||||
struct Fill_Area_Private : Typed_Render_Data<Fill_Area, Fill_Area_Render_State, Fill_Area_Input_Data> {
|
||||
std::pmr::vector<PointF> data_points{memory_resource(Memory_Domain::Curve)};
|
||||
void prepare_data(const Plot_Render_Snapshot&) override {
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
Fill_Area_Input_Data* input = render_input_data();
|
||||
input->read_all([this](std::pmr::vector<PointF>& points) {
|
||||
@@ -36,7 +36,7 @@ struct Fill_Area_Private : Typed_Render_Data<Fill_Area, Fill_Area_Render_State,
|
||||
});
|
||||
clear_render_input();
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Fill_Area_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -103,7 +103,7 @@ std::shared_ptr<Fill_Area> Fill_Area::Builder::build() {
|
||||
auto ret = renderive::make_shared<Fill_Area>();
|
||||
ret->init(parent);
|
||||
Fill_Area_Private* pd = ret->d();
|
||||
Fill_Area_Render_State* sc = reinterpret_cast<Fill_Area_Render_State*>(pd->state(State_Edit));
|
||||
Fill_Area_Render_State* sc = reinterpret_cast<Fill_Area_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(double, baseline)
|
||||
|
||||
@@ -53,7 +53,7 @@ struct Grid_Private : Typed_Render_Data<Grid, Grid_Render_State, Input_Data> {
|
||||
canvas.draw_line(PointF{cross0, pixel}, PointF{cross1, pixel});
|
||||
}
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Grid_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -180,7 +180,7 @@ std::shared_ptr<Grid> Grid::Builder::build() {
|
||||
auto ret = renderive::make_shared<Grid>();
|
||||
ret->init(parent);
|
||||
Grid_Private* pd = ret->d();
|
||||
Grid_Render_State* sc = reinterpret_cast<Grid_Render_State*>(pd->state(State_Edit));
|
||||
Grid_Render_State* sc = reinterpret_cast<Grid_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(bool, domain_grid)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Label_Input_Data : Latest_Input_Data {
|
||||
struct Label_Private : Typed_Render_Data<Label, Label_Render_State, Label_Input_Data> {
|
||||
std::pmr::vector<Label_Item> prepared_items{memory_resource(Memory_Domain::Other)};
|
||||
bool use_prepared_items = false;
|
||||
void prepare_data(const Plot_Render_Snapshot&) override {
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
Label_Input_Data* input = render_input_data();
|
||||
if (!input->pending)
|
||||
@@ -59,7 +59,7 @@ struct Label_Private : Typed_Render_Data<Label, Label_Render_State, Label_Input_
|
||||
canvas.draw_text(rect, Text_Align::Left | Text_Align::Vertical_Center, item.text);
|
||||
canvas.restore();
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Label_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -122,7 +122,7 @@ std::shared_ptr<Label> Label::Builder::build() {
|
||||
auto ret = renderive::make_shared<Label>();
|
||||
ret->init(parent);
|
||||
Label_Private* pd = ret->d();
|
||||
Label_Render_State* sc = reinterpret_cast<Label_Render_State*>(pd->state(State_Edit));
|
||||
Label_Render_State* sc = reinterpret_cast<Label_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(PointF, position)
|
||||
|
||||
@@ -45,7 +45,7 @@ struct Marker_Private : Typed_Render_Data<Marker, Marker_Render_State, Marker_In
|
||||
canvas.draw_line(value_start, value_end);
|
||||
}
|
||||
}
|
||||
void prepare_data(const Plot_Render_Snapshot&) override {
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
Marker_Input_Data* input = render_input_data();
|
||||
if (!input->pending)
|
||||
@@ -54,7 +54,7 @@ struct Marker_Private : Typed_Render_Data<Marker, Marker_Render_State, Marker_In
|
||||
use_prepared_items = true;
|
||||
clear_render_input();
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Marker_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -118,7 +118,7 @@ std::shared_ptr<Marker> Marker::Builder::build() {
|
||||
auto ret = renderive::make_shared<Marker>();
|
||||
ret->init(parent);
|
||||
Marker_Private* pd = ret->d();
|
||||
Marker_Render_State* sc = reinterpret_cast<Marker_Render_State*>(pd->state(State_Edit));
|
||||
Marker_Render_State* sc = reinterpret_cast<Marker_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(PointF, position)
|
||||
|
||||
@@ -44,7 +44,7 @@ struct Point_Set_Render_State : Render_State, Point_Set_Prop {};
|
||||
struct Point_Set_Private : Typed_Render_Data<Point_Set, Point_Set_Render_State, Point_Set_Input_Data> {
|
||||
std::pmr::vector<PointF> data_points{memory_resource(Memory_Domain::Point_Set)};
|
||||
std::pmr::vector<Color> data_colors{memory_resource(Memory_Domain::Point_Set)};
|
||||
void prepare_data(const Plot_Render_Snapshot&) override {
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
Point_Set_Input_Data* input = render_input_data();
|
||||
input->read_all([this](std::pmr::vector<PointF>& points, std::pmr::vector<Color>& colors) {
|
||||
@@ -66,7 +66,7 @@ struct Point_Set_Private : Typed_Render_Data<Point_Set, Point_Set_Render_State,
|
||||
canvas.draw_line(PointF{point.x, point.y - half}, PointF{point.x, point.y + half});
|
||||
}
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Point_Set_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -164,7 +164,7 @@ std::shared_ptr<Point_Set> Point_Set::Builder::build() {
|
||||
auto ret = renderive::make_shared<Point_Set>();
|
||||
ret->init(parent);
|
||||
Point_Set_Private* pd = ret->d();
|
||||
Point_Set_Render_State* sc = reinterpret_cast<Point_Set_Render_State*>(pd->state(State_Edit));
|
||||
Point_Set_Render_State* sc = reinterpret_cast<Point_Set_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(double, size)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Raster_Image_Input_Data : Latest_Input_Data {
|
||||
struct Raster_Image_Render_State : Render_State, Raster_Image_Prop {};
|
||||
struct Raster_Image_Private : Typed_Render_Data<Raster_Image, Raster_Image_Render_State, Raster_Image_Input_Data> {
|
||||
Image image;
|
||||
void prepare_data(const Plot_Render_Snapshot&) override {
|
||||
void prepare_data(const Render_Frame_Snapshot&) override {
|
||||
sync_state_pipeline();
|
||||
Raster_Image_Input_Data* input = render_input_data();
|
||||
input->read_all([this](const Image& value) {
|
||||
@@ -30,7 +30,7 @@ struct Raster_Image_Private : Typed_Render_Data<Raster_Image, Raster_Image_Rende
|
||||
});
|
||||
clear_render_input();
|
||||
}
|
||||
void draw(Canvas& canvas, const Plot_Render_Snapshot&) override {
|
||||
void draw(Canvas& canvas, const Render_Frame_Snapshot&) override {
|
||||
Raster_Image_Render_State* s = render_state();
|
||||
auto domain_axis = s->domain_axis.lock();
|
||||
auto value_axis = s->value_axis.lock();
|
||||
@@ -69,17 +69,13 @@ void Raster_Image::update_image_frame(const Image& image, Range domain_range, Ra
|
||||
if (!ok())
|
||||
return;
|
||||
Raster_Image_Private* pd = d();
|
||||
auto record = pd->state_control.try_acquire_role(State_Edit);
|
||||
if (record.result != Triple_Buffer_Result::Success)
|
||||
Render_Edit_Lease<Raster_Image_Private, Raster_Image_Render_State> edit(pd);
|
||||
if (!edit)
|
||||
return;
|
||||
auto lease = record.lease;
|
||||
Raster_Image_Render_State* state = reinterpret_cast<Raster_Image_Render_State*>(pd->state_by_index(lease.index));
|
||||
state->domain_range = domain_range;
|
||||
state->value_range = value_range;
|
||||
state->source_rect = source_rect;
|
||||
state->interpolation_mode = interpolation_mode;
|
||||
++state->version;
|
||||
pd->unmark_state(lease);
|
||||
edit->domain_range = domain_range;
|
||||
edit->value_range = value_range;
|
||||
edit->source_rect = source_rect;
|
||||
edit->interpolation_mode = interpolation_mode;
|
||||
Render_Input_Lease<Raster_Image_Private, Raster_Image_Input_Data> input(pd);
|
||||
input->push(image);
|
||||
}
|
||||
@@ -118,7 +114,7 @@ std::shared_ptr<Raster_Image> Raster_Image::Builder::build() {
|
||||
auto ret = renderive::make_shared<Raster_Image>();
|
||||
ret->init(parent);
|
||||
Raster_Image_Private* pd = ret->d();
|
||||
Raster_Image_Render_State* sc = reinterpret_cast<Raster_Image_Render_State*>(pd->state(State_Edit));
|
||||
Raster_Image_Render_State* sc = reinterpret_cast<Raster_Image_Render_State*>(pd->edit_state());
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, domain_axis)
|
||||
PROP_R(std::weak_ptr<Abs_Axis>, value_axis)
|
||||
PROP_R(Range, domain_range)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include "../architecture/Render_Lease.h"
|
||||
#include "../flow/low_latency/Render_Lease.h"
|
||||
#include "../base/Color.h"
|
||||
#include "../base/Geometry.h"
|
||||
#include "../plottable/Interpolation_p.h"
|
||||
|
||||
Reference in New Issue
Block a user