From 5dfae0604bba1916578e847df3aa4f8e524cc1b7 Mon Sep 17 00:00:00 2001 From: Dirk Hoffmann Date: Sun, 22 Dec 2024 14:40:50 +0100 Subject: [PATCH] Added a mutex protecting texture accesses (#845) --- Emulator/Components/Denise/PixelEngine.cpp | 5 +++++ Emulator/Components/Emulator.h | 6 +++++- Emulator/VAmiga.cpp | 12 ++++++++++++ Emulator/VAmiga.h | 14 ++++++++++++++ Emulator/config.cpp | 2 +- GUI/Metal/Layers/Canvas.swift | 8 ++++++++ Proxy/EmulatorProxy.h | 2 ++ Proxy/EmulatorProxy.mm | 10 ++++++++++ 8 files changed, 57 insertions(+), 2 deletions(-) diff --git a/Emulator/Components/Denise/PixelEngine.cpp b/Emulator/Components/Denise/PixelEngine.cpp index 3aa716bbb..2b7b20179 100644 --- a/Emulator/Components/Denise/PixelEngine.cpp +++ b/Emulator/Components/Denise/PixelEngine.cpp @@ -13,6 +13,7 @@ #include "Colors.h" #include "Denise.h" #include "DmaDebugger.h" +#include "Emulator.h" #include @@ -309,6 +310,8 @@ PixelEngine::stablePtr(isize row, isize col) void PixelEngine::swapBuffers() { + emulator.textureLock.lock(); + videoPort.buffersWillSwap(); isize oldActiveBuffer = activeBuffer; @@ -319,6 +322,8 @@ PixelEngine::swapBuffers() emuTexture[newActiveBuffer].prevlof = emuTexture[oldActiveBuffer].lof; activeBuffer = newActiveBuffer; + + emulator.textureLock.unlock(); } void diff --git a/Emulator/Components/Emulator.h b/Emulator/Components/Emulator.h index 3b6af5d54..70e64841e 100644 --- a/Emulator/Components/Emulator.h +++ b/Emulator/Components/Emulator.h @@ -40,6 +40,9 @@ class Emulator : public Thread, public Synchronizable, public InspectablelockTexture(); +} + +void +VideoPortAPI::unlockTexture() +{ + emu->unlockTexture(); +} + const u32 * VideoPortAPI::getTexture() const { diff --git a/Emulator/VAmiga.h b/Emulator/VAmiga.h index fe8bd8045..de4abf9ee 100644 --- a/Emulator/VAmiga.h +++ b/Emulator/VAmiga.h @@ -999,6 +999,20 @@ struct VideoPortAPI : public API { /// @name Retrieving video data /// @{ + /** @brief Locks the emulator texture + * + * This function aquires a mutex that prevents the emulator to modify the + * stable texture. Call this function prior to getTexture(). + */ + void lockTexture(); + + /** @brief Unlocks the emulator texture + * + * This function releases the mutex acquired in lockTexture(). Call this + * function when the pointer returned by getTexture() is no longer needed. + */ + void unlockTexture(); + /** @brief Returns a pointer to the most recent stable texture * * The texture dimensions are given by constants vamiga::Texture::width diff --git a/Emulator/config.cpp b/Emulator/config.cpp index 68cb10e00..49a934a83 100644 --- a/Emulator/config.cpp +++ b/Emulator/config.cpp @@ -108,7 +108,7 @@ debugflag POSREG_DEBUG = 0; debugflag JOYREG_DEBUG = 0; debugflag POTREG_DEBUG = 0; debugflag VID_DEBUG = 0; -debugflag PRT_DEBUG = 1; +debugflag PRT_DEBUG = 0; debugflag SER_DEBUG = 0; debugflag POT_DEBUG = 0; debugflag HOLD_MOUSE_L = 0; diff --git a/GUI/Metal/Layers/Canvas.swift b/GUI/Metal/Layers/Canvas.swift index b708358f7..3392fcc9a 100644 --- a/GUI/Metal/Layers/Canvas.swift +++ b/GUI/Metal/Layers/Canvas.swift @@ -237,6 +237,11 @@ class Canvas: Layer { // Get the emulator texture var buffer: UnsafePointer! var nr = 0 + + // Prevent the stable texture from changing + amiga.videoPort.lockTexture() + + // Grab the stable texture amiga.videoPort.texture(&buffer, nr: &nr, lof: &currLOF, prevlof: &prevLOF) // Check for duplicated or dropped frames @@ -255,6 +260,9 @@ class Canvas: Layer { } else { sfTexture.replace(w: Int(TPP) * HPIXELS, h: VPIXELS, buffer: buffer) } + + // Release the texture lock + amiga.videoPort.unlockTexture() } // diff --git a/Proxy/EmulatorProxy.h b/Proxy/EmulatorProxy.h index 201e8b0a6..19b3adbe4 100644 --- a/Proxy/EmulatorProxy.h +++ b/Proxy/EmulatorProxy.h @@ -594,6 +594,8 @@ @interface VideoPortProxy : CoreComponentProxy { } +- (void)lockTexture; +- (void)unlockTexture; - (void)texture:(const u32 **)ptr nr:(NSInteger *)nr lof:(bool *)lof prevlof:(bool *)prevlof; @end diff --git a/Proxy/EmulatorProxy.mm b/Proxy/EmulatorProxy.mm index 968cbaf9e..246542d2e 100644 --- a/Proxy/EmulatorProxy.mm +++ b/Proxy/EmulatorProxy.mm @@ -1081,6 +1081,16 @@ - (VideoPortAPI *)port return (VideoPortAPI *)obj; } +- (void)lockTexture +{ + [self port]->lockTexture(); +} + +- (void)unlockTexture +{ + [self port]->unlockTexture(); +} + - (void)texture:(const u32 **)ptr nr:(NSInteger *)nr lof:(bool *)lof prevlof:(bool *)prevlof { isize inr;