From b75ad3def2a808ce1a8b450242a6a838e8c1cdcf Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 3 Feb 2019 15:07:22 -0500 Subject: [PATCH] Updates the multimachine for the ScanTarget world. --- .../Implementation/MultiCRTMachine.cpp | 18 +++++++++++++----- .../Implementation/MultiCRTMachine.hpp | 1 + Outputs/OpenGL/ScanTarget.cpp | 5 +++++ Outputs/OpenGL/ScanTarget.hpp | 1 + Outputs/ScanTarget.hpp | 4 ++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp index 73e086532..53c2ae3b1 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.cpp @@ -48,16 +48,16 @@ void MultiCRTMachine::perform_parallel(const std::function &function) { std::lock_guard machines_lock(machines_mutex_); for(const auto &machine: machines_) { - CRTMachine::Machine *crt_machine = machine->crt_machine(); + CRTMachine::Machine *const crt_machine = machine->crt_machine(); if(crt_machine) function(crt_machine); } } void MultiCRTMachine::set_scan_target(Outputs::Display::ScanTarget *scan_target) { - perform_serial([=](::CRTMachine::Machine *machine) { - // TODO. -// machine->setup_output(aspect_ratio); - }); + scan_target_ = scan_target; + + CRTMachine::Machine *const crt_machine = machines_.front()->crt_machine(); + if(crt_machine) crt_machine->set_scan_target(scan_target); } Outputs::Speaker::Speaker *MultiCRTMachine::get_speaker() { @@ -73,6 +73,14 @@ void MultiCRTMachine::run_for(Time::Seconds duration) { } void MultiCRTMachine::did_change_machine_order() { + if(scan_target_) scan_target_->will_change_owner(); + + perform_serial([=](::CRTMachine::Machine *machine) { + machine->set_scan_target(nullptr); + }); + CRTMachine::Machine *const crt_machine = machines_.front()->crt_machine(); + if(crt_machine) crt_machine->set_scan_target(scan_target_); + if(speaker_) { speaker_->set_new_front_machine(machines_.front().get()); } diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp index 6cd886669..bf6b3d083 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiCRTMachine.hpp @@ -64,6 +64,7 @@ class MultiCRTMachine: public CRTMachine::Machine { std::vector queues_; MultiSpeaker *speaker_ = nullptr; Delegate *delegate_ = nullptr; + Outputs::Display::ScanTarget *scan_target_ = nullptr; /*! Performs a parallel for operation across all machines, performing the supplied diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index ff4451a12..cff0bf703 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -209,6 +209,11 @@ void ScanTarget::end_data(size_t actual_length) { data_type_size_); } +void ScanTarget::will_change_owner() { + allocation_has_failed_ = true; + vended_scan_ = nullptr; +} + void ScanTarget::submit() { if(allocation_has_failed_) { // Reset all pointers to where they were; this also means diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index acd36d3d4..d3b6337bc 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -60,6 +60,7 @@ class ScanTarget: public Outputs::Display::ScanTarget { void end_data(size_t actual_length) override; void submit() override; void announce(Event event, bool is_visible, const Outputs::Display::ScanTarget::Scan::EndPoint &location, uint8_t colour_burst_amplitude) override; + void will_change_owner() override; bool output_is_visible_ = false; diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index b7f24a9fa..83de2ef1c 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -264,6 +264,10 @@ struct ScanTarget { /// It is required that every call to begin_data be paired with a call to end_data. virtual void end_data(size_t actual_length) {} + /// Tells the scan target that its owner is about to change; this is a hint that existing + /// data and scan allocations should be invalidated. + virtual void will_change_owner() {} + /// Marks the end of an atomic set of data. Drawing is best effort, so the scan target should either: /// /// (i) output everything received since the previous submit; or