From 902017a962718ae197b8822c4a2a3e7e9c531418 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 20 Mar 2016 18:42:37 -0400 Subject: [PATCH] Fixes: drop any processing backlog, try not to allow an Electron document to close mid-draw, perform a frame grab even if the emulated machine is over-processing, really really don't create a CRT until it's safe. --- Machines/Electron/Electron.cpp | 3 ++- .../Mac/Clock Signal/Documents/ElectronDocument.swift | 8 +++++++- .../Mac/Clock Signal/Documents/MachineDocument.swift | 7 ++++++- OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m | 4 ++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 0dd95b24e..a3f16da98 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -45,7 +45,7 @@ Machine::Machine() : _audioOutputPositionError(0), _current_pixel_line(-1), _use_fast_tape_hack(false), - _crt(std::unique_ptr(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1))) + _crt(nullptr) { memset(_key_states, 0, sizeof(_key_states)); memset(_palette, 0xf, sizeof(_palette)); @@ -57,6 +57,7 @@ Machine::Machine() : void Machine::setup_output() { + _crt = std::unique_ptr(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1)); _crt->set_rgb_sampling_function( "vec4 rgb_sample(vec2 coordinate)" "{" diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift index a815e50d7..588223b72 100644 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift @@ -58,11 +58,14 @@ class ElectronDocument: MachineDocument { } lazy var actionLock = NSLock() + lazy var drawLock = NSLock() override func close() { actionLock.lock() + drawLock.lock() openGLView.invalidate() openGLView.openGLContext!.makeCurrentContext() actionLock.unlock() + drawLock.unlock() super.close() } @@ -76,7 +79,10 @@ class ElectronDocument: MachineDocument { } override func openGLView(view: CSOpenGLView, drawViewOnlyIfDirty onlyIfDirty: Bool) { - electron.drawViewForPixelSize(view.backingSize, onlyIfDirty: onlyIfDirty) + if drawLock.tryLock() { + electron.drawViewForPixelSize(view.backingSize, onlyIfDirty: onlyIfDirty) + drawLock.unlock() + } } // MARK: CSOpenGLViewResponderDelegate diff --git a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift index 3bb2ebac5..062a69158 100644 --- a/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/MachineDocument.swift @@ -41,7 +41,12 @@ class MachineDocument: NSDocument, CSOpenGLViewDelegate, CSOpenGLViewResponderDe let cycleCount = cycleCountLow + cycleCountHigh if let lastCycleCount = lastCycleCount { let elapsedTime = cycleCount - lastCycleCount - runForNumberOfCycles(Int32(elapsedTime)) + // if the emulation has fallen too far behind then silently swallow the request; + // some actions — e.g. the host computer waking after sleep — may give us a + // prohibitive backlog + if elapsedTime < intendedCyclesPerSecond / 25 { + runForNumberOfCycles(Int32(elapsedTime)) + } } lastCycleCount = cycleCount } diff --git a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m index 7bd943fe2..3b04dd760 100644 --- a/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m +++ b/OSBindings/Mac/Clock Signal/Views/CSOpenGLView.m @@ -62,6 +62,10 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt OSAtomicTestAndClear(activityMask, &_updateIsOngoing); }); } + else + { + [self drawViewOnlyIfDirty:YES]; + } } - (void)invalidate