Skip to content

Commit

Permalink
Added a mutex protecting texture accesses (#845)
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkwhoffmann committed Dec 22, 2024
1 parent 3879884 commit 5dfae06
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Emulator/Components/Denise/PixelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Colors.h"
#include "Denise.h"
#include "DmaDebugger.h"
#include "Emulator.h"

#include <fstream>

Expand Down Expand Up @@ -309,6 +310,8 @@ PixelEngine::stablePtr(isize row, isize col)
void
PixelEngine::swapBuffers()
{
emulator.textureLock.lock();

videoPort.buffersWillSwap();

isize oldActiveBuffer = activeBuffer;
Expand All @@ -319,6 +322,8 @@ PixelEngine::swapBuffers()
emuTexture[newActiveBuffer].prevlof = emuTexture[oldActiveBuffer].lof;

activeBuffer = newActiveBuffer;

emulator.textureLock.unlock();
}

void
Expand Down
6 changes: 5 additions & 1 deletion Emulator/Components/Emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class Emulator : public Thread, public Synchronizable, public Inspectable<Emulat
// Incoming external events
CmdQueue cmdQueue;

// Texture lock
util::Mutex textureLock;


//
// Methods
Expand Down Expand Up @@ -157,7 +160,8 @@ class Emulator : public Thread, public Synchronizable, public Inspectable<Emulat
//

const FrameBuffer &getTexture() const;

void lockTexture() { textureLock.lock(); }
void unlockTexture() { textureLock.unlock(); }

//
// Command queue
Expand Down
12 changes: 12 additions & 0 deletions Emulator/VAmiga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,18 @@ SerialPortAPI::readOutgoingPrintableByte() const
// Ports (VideoPort)
//

void
VideoPortAPI::lockTexture()
{
emu->lockTexture();
}

void
VideoPortAPI::unlockTexture()
{
emu->unlockTexture();
}

const u32 *
VideoPortAPI::getTexture() const
{
Expand Down
14 changes: 14 additions & 0 deletions Emulator/VAmiga.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Emulator/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions GUI/Metal/Layers/Canvas.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ class Canvas: Layer {
// Get the emulator texture
var buffer: UnsafePointer<u32>!
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
Expand All @@ -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()
}

//
Expand Down
2 changes: 2 additions & 0 deletions Proxy/EmulatorProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions Proxy/EmulatorProxy.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 5dfae06

Please sign in to comment.