diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index 4db4d30e9..4bd136496 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -62,6 +62,8 @@ void CRT::set_new_timing(int cycles_per_line, int height_of_display, Outputs::Di scan_target_modals_.output_scale.y = uint16_t(real_clock_scan_period / vertical_flywheel_output_divider_); scan_target_modals_.expected_vertical_lines = height_of_display; scan_target_modals_.composite_colour_space = colour_space; + scan_target_modals_.colour_cycle_numerator = colour_cycle_numerator; + scan_target_modals_.colour_cycle_denominator = colour_cycle_denominator; scan_target_->set_modals(scan_target_modals_); } diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 97a37e5f0..49d0bb93b 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -131,6 +131,15 @@ void ScanTarget::set_modals(Modals modals) { write_pointers_.write_area = 0; } + // Pick a processing width; this will be at least four times the + // colour subcarrier, and an integer multiple of the pixel clock and + // at most 2048. + const int colour_cycle_width = (modals.colour_cycle_numerator * 4 + modals.colour_cycle_denominator - 1) / modals.colour_cycle_denominator; + const int dot_clock = modals.cycles_per_line / modals.clocks_per_pixel_greatest_common_divisor; + const int overflow = colour_cycle_width % dot_clock; + processing_width_ = colour_cycle_width + (overflow ? dot_clock - overflow : 0); + processing_width_ = std::min(processing_width_, 2048); + // TODO: this, but not to the test shader. test_shader_->set_uniform("scale", GLfloat(modals.output_scale.x), GLfloat(modals.output_scale.y)); test_shader_->set_uniform("rowHeight", GLfloat(1.0f / modals.expected_vertical_lines)); diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index 578c0e71f..e4c6382a9 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -129,9 +129,11 @@ class ScanTarget: public Outputs::Display::ScanTarget { */ void enable_vertex_attributes(ShaderType type, Shader &target); - std::unique_ptr test_shader_; GLsync fence_ = nullptr; std::atomic_flag is_drawing_; + + int processing_width_ = 0; + std::unique_ptr test_shader_; }; } diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index 29fcf28a2..4f880adc5 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -129,6 +129,9 @@ struct ScanTarget { /// the @c cycles_per_line are offered for sizing of intermediary buffers. int clocks_per_pixel_greatest_common_divisor; + /// Provides the number of colour cycles in a line, as a quotient. + int colour_cycle_numerator, colour_cycle_denominator; + /// Provides a pre-estimate of the likely number of left-to-right scans per frame. /// This isn't a guarantee, but it should provide a decent-enough estimate. int expected_vertical_lines;