From c5d8d9127b501294ebba04ca6d584eab68264bf7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 21 Jun 2020 18:25:38 -0400 Subject: [PATCH] Rejigs ScanTarget relationship from pull to push, so it can be set whenever it is safe. --- OSBindings/Qt/mainwindow.cpp | 2 +- OSBindings/Qt/scantargetwidget.cpp | 32 +++++++++++++++++++++--------- OSBindings/Qt/scantargetwidget.h | 7 ++++++- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/OSBindings/Qt/mainwindow.cpp b/OSBindings/Qt/mainwindow.cpp index 03eec545c..781a2a007 100644 --- a/OSBindings/Qt/mainwindow.cpp +++ b/OSBindings/Qt/mainwindow.cpp @@ -217,7 +217,7 @@ void MainWindow::launchMachine() { // TODO: in the future, hypothetically, deal with non-scan producers. const auto scan_producer = machine->scan_producer(); if(scan_producer) { - scan_producer->set_scan_target(ui->openGLWidget->getScanTarget()); + ui->openGLWidget->setScanProducer(scan_producer); } // Install audio output if required. diff --git a/OSBindings/Qt/scantargetwidget.cpp b/OSBindings/Qt/scantargetwidget.cpp index 4d2804008..a9aab5e32 100644 --- a/OSBindings/Qt/scantargetwidget.cpp +++ b/OSBindings/Qt/scantargetwidget.cpp @@ -20,7 +20,26 @@ void ScanTargetWidget::initializeGL() { void ScanTargetWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT); - if(isConnected) { + + // Gmynastics ahoy: if a producer has been specified or previously connected then: + // + // (i) if it's a new producer, generate a new scan target and pass it on; + // (ii) in any case, check whether the underlyiung framebuffer has changed; and + // (iii) draw. + // + // The slightly convoluted scan target forwarding arrangement works around an issue + // with QOpenGLWidget under macOS, which I did not fully diagnose, in which creating + // a scan target in ::initializeGL did not work (and no other arrangement really works + // with regard to starting up). + if(isConnected || producer) { + if(producer) { + isConnected = true; + framebuffer = defaultFramebufferObject(); + scanTarget = std::make_unique(framebuffer); + producer->set_scan_target(scanTarget.get()); + producer = nullptr; + } + // Qt reserves the right to change the framebuffer object due to window resizes or if setParent is called; // therefore check whether it has changed. const auto newFramebuffer = defaultFramebufferObject(); @@ -52,12 +71,7 @@ void ScanTargetWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); } -Outputs::Display::OpenGL::ScanTarget *ScanTargetWidget::getScanTarget() { - makeCurrent(); - if(!scanTarget) { - isConnected = true; - framebuffer = defaultFramebufferObject(); - scanTarget = std::make_unique(framebuffer); - } - return scanTarget.get(); +void ScanTargetWidget::setScanProducer(MachineTypes::ScanProducer *producer) { + this->producer = producer; + repaint(); } diff --git a/OSBindings/Qt/scantargetwidget.h b/OSBindings/Qt/scantargetwidget.h index e3204707e..520df2153 100644 --- a/OSBindings/Qt/scantargetwidget.h +++ b/OSBindings/Qt/scantargetwidget.h @@ -4,6 +4,8 @@ #include #include "../../Outputs/OpenGL/ScanTarget.hpp" +#include "../../Machines/ScanProducer.hpp" + #include "../../ClockReceiver/VSyncPredictor.hpp" class ScanTargetWidget : public QOpenGLWidget @@ -12,7 +14,9 @@ class ScanTargetWidget : public QOpenGLWidget ScanTargetWidget(QWidget *parent = nullptr); ~ScanTargetWidget(); - Outputs::Display::OpenGL::ScanTarget *getScanTarget(); + // Sets the current scan producer; this scan producer will be + // handed a suitable scan target as soon as one exists. + void setScanProducer(MachineTypes::ScanProducer *); protected: void initializeGL() override; @@ -26,6 +30,7 @@ class ScanTargetWidget : public QOpenGLWidget Time::VSyncPredictor vsyncPredictor; bool isConnected = false; GLuint framebuffer = 0; + MachineTypes::ScanProducer *producer = nullptr; private slots: void vsync();