diff options
author | Max Horn | 2003-04-30 19:11:33 +0000 |
---|---|---|
committer | Max Horn | 2003-04-30 19:11:33 +0000 |
commit | feab6f904f81e5f6a1fbaf8b1b3b8686242ed00b (patch) | |
tree | db386448d255e93d18ce5751bb94b65c6ed44726 /backends/sdl | |
parent | 70936947815df45899879fa0467c6489cc0d72c9 (diff) | |
download | scummvm-rg350-feab6f904f81e5f6a1fbaf8b1b3b8686242ed00b.tar.gz scummvm-rg350-feab6f904f81e5f6a1fbaf8b1b3b8686242ed00b.tar.bz2 scummvm-rg350-feab6f904f81e5f6a1fbaf8b1b3b8686242ed00b.zip |
moved screen mutex from smush into SDL backend (other backends have to make sure they are thread safe by themselves)
svn-id: r7230
Diffstat (limited to 'backends/sdl')
-rw-r--r-- | backends/sdl/sdl-common.cpp | 15 | ||||
-rw-r--r-- | backends/sdl/sdl-common.h | 14 | ||||
-rw-r--r-- | backends/sdl/sdl.cpp | 6 |
3 files changed, 30 insertions, 5 deletions
diff --git a/backends/sdl/sdl-common.cpp b/backends/sdl/sdl-common.cpp index 9b20879ef9..9c9128abb6 100644 --- a/backends/sdl/sdl-common.cpp +++ b/backends/sdl/sdl-common.cpp @@ -104,6 +104,8 @@ OSystem_SDL_Common::OSystem_SDL_Common() // reset mouse state memset(&km, 0, sizeof(km)); + + _mutex = SDL_CreateMutex(); } OSystem_SDL_Common::~OSystem_SDL_Common() { @@ -111,6 +113,7 @@ OSystem_SDL_Common::~OSystem_SDL_Common() { free(_dirty_checksums); free(_currentPalette); free(_mouseBackup); + SDL_DestroyMutex(_mutex); } void OSystem_SDL_Common::init_size(uint w, uint h) { @@ -140,6 +143,8 @@ void OSystem_SDL_Common::copy_rect(const byte *buf, int pitch, int x, int y, int if (_screen == NULL) return; + StackLock lock(_mutex); // Lock the mutex until this function ends + if (((uint32)buf & 3) == 0 && pitch == _screenWidth && x==0 && y==0 && w==_screenWidth && h==_screenHeight && _mode_flags&DF_WANT_RECT_OPTIM) { /* Special, optimized case for full screen updates. @@ -208,8 +213,10 @@ void OSystem_SDL_Common::move_screen(int dx, int dy, int height) { if (_mouseDrawn) undraw_mouse(); - // FIXME - calling copy rect repeatedly is horribly inefficient, as it (un)locks the surface repeatedly + // FIXME - calling copy_rect repeatedly is horribly inefficient, as it (un)locks the surface repeatedly // and it performs unneeded clipping checks etc. + // Furthermore, this code is not correct, techincally: the pixels members of an SDLSource may be 0 + // while it is not locked (e.g. for HW surfaces which are stored in the graphic card's VRAM). // vertical movement if (dy > 0) { @@ -218,7 +225,7 @@ void OSystem_SDL_Common::move_screen(int dx, int dy, int height) { copy_rect((byte *)_screen->pixels + _screenWidth * (y - dy), _screenWidth, 0, y, _screenWidth, 1); } else if (dy < 0) { // move up - copy from top to bottom - for (y = 0; y < height + dx; y++) + for (y = dy; y < height; y++) copy_rect((byte *)_screen->pixels + _screenWidth * (y - dy), _screenWidth, 0, y, _screenWidth, 1); } @@ -229,7 +236,7 @@ void OSystem_SDL_Common::move_screen(int dx, int dy, int height) { copy_rect((byte *)_screen->pixels + x - dx, _screenWidth, x, 0, 1, height); } else if (dx < 0) { // move left - copy from left to right - for (x = 0; x < _screenWidth; x++) + for (x = dx; x < _screenWidth; x++) copy_rect((byte *)_screen->pixels + x - dx, _screenWidth, x, 0, 1, height); } } @@ -1150,6 +1157,8 @@ void OSystem_SDL_Common::clear_overlay() { if (!_overlayVisible) return; + StackLock lock(_mutex); // Lock the mutex until this function ends + // hide the mouse undraw_mouse(); diff --git a/backends/sdl/sdl-common.h b/backends/sdl/sdl-common.h index 920e396e79..ca90335a4a 100644 --- a/backends/sdl/sdl-common.h +++ b/backends/sdl/sdl-common.h @@ -200,6 +200,10 @@ protected: // Palette data SDL_Color *_currentPalette; uint _paletteDirtyStart, _paletteDirtyEnd; + + // Mutex that prevents multiple threads interferring with each other + // when accessing the screen. + SDL_mutex *_mutex; void add_dirty_rgn_auto(const byte *buf); @@ -222,5 +226,15 @@ protected: static OSystem_SDL_Common *create(); }; +// Auxillary class to (un)lock a mutex on the stack +class StackLock { + SDL_mutex *_mutex; +public: + StackLock(SDL_mutex *mutex) : _mutex(mutex) { lock(); } + ~StackLock() { unlock(); } + void lock() { SDL_mutexP(_mutex); } + void unlock() { SDL_mutexV(_mutex); } +}; + #endif diff --git a/backends/sdl/sdl.cpp b/backends/sdl/sdl.cpp index 6c6dd255e1..3c977e20b9 100644 --- a/backends/sdl/sdl.cpp +++ b/backends/sdl/sdl.cpp @@ -230,6 +230,8 @@ void OSystem_SDL::hotswap_gfx_mode() { void OSystem_SDL::update_screen() { assert(_hwscreen != NULL); + StackLock lock(_mutex); // Lock the mutex until this function ends + // If the shake position changed, fill the dirty area with blackness if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor}; @@ -277,12 +279,12 @@ void OSystem_SDL::update_screen() { if (!_overlayVisible) { for(r = _dirty_rect_list; r != last_rect; ++r) { dst = *r; + dst.x++; // Shift rect by one since 2xSai needs to acces the data around + dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. if (_scaler_proc == Normal1x) { if (SDL_BlitSurface(_screen, r, _hwscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } else { - dst.x++; // Shift rect by one since 2xSai needs to acces the data around - dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. if (SDL_BlitSurface(_screen, r, _tmpscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } |