From e75858ce5e96df30ccb22253ec592d3829e2bccc Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 11 Feb 2021 10:08:04 +0100 Subject: Codechange: [SDL2] Allow several places to hook into the SDL driver This allows future subdrivers to use these to manage their own flow. --- src/video/sdl2_v.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++--------- src/video/sdl2_v.h | 10 ++++++++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 56b1644b7..72ecb97c1 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -126,9 +126,16 @@ void VideoDriver_SDL::Paint() this->UpdatePalette(); break; - case Blitter::PALETTE_ANIMATION_BLITTER: + case Blitter::PALETTE_ANIMATION_BLITTER: { + bool need_buf = _screen.dst_ptr == nullptr; + if (need_buf) _screen.dst_ptr = this->GetVideoPointer(); blitter->PaletteAnimate(this->local_palette); + if (need_buf) { + this->ReleaseVideoPointer(); + _screen.dst_ptr = nullptr; + } break; + } case Blitter::PALETTE_ANIMATION_NONE: break; @@ -248,11 +255,26 @@ static uint FindStartupDisplay(uint startup_display) return 0; } -bool VideoDriver_SDL::CreateMainWindow(uint w, uint h) +void VideoDriver_SDL::ClientSizeChanged(int w, int h, bool force) +{ + /* Allocate backing store of the new size. */ + if (this->AllocateBackingStore(w, h, force)) { + /* Mark all palette colours dirty. */ + _cur_palette.first_dirty = 0; + _cur_palette.count_dirty = 256; + this->local_palette = _cur_palette; + + BlitterFactory::GetCurrentBlitter()->PostResize(); + + GameSizeChanged(); + } +} + +bool VideoDriver_SDL::CreateMainWindow(uint w, uint h, uint flags) { if (this->sdl_window != nullptr) return true; - Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; + flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; if (_fullscreen) { flags |= SDL_WINDOW_FULLSCREEN; @@ -302,17 +324,13 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize) if (!this->CreateMainWindow(w, h)) return false; if (resize) SDL_SetWindowSize(this->sdl_window, w, h); - - if (!this->AllocateBackingStore(w, h, true)) return false; + this->ClientSizeChanged(w, h, true); /* When in full screen, we will always have the mouse cursor * within the window, even though SDL does not give us the * appropriate event to know this. */ if (_fullscreen) _cursor.in_window = true; - BlitterFactory::GetCurrentBlitter()->PostResize(); - - GameSizeChanged(); return true; } @@ -350,13 +368,18 @@ bool VideoDriver_SDL::AllocateBackingStore(int w, int h, bool force) _screen.width = _sdl_surface->w; _screen.height = _sdl_surface->h; _screen.pitch = _sdl_surface->pitch / (bpp / 8); - _screen.dst_ptr = _sdl_surface->pixels; + _screen.dst_ptr = this->GetVideoPointer(); this->MakePalette(); return true; } +void *VideoDriver_SDL::GetVideoPointer() +{ + return _sdl_surface->pixels; +} + bool VideoDriver_SDL::ClaimMousePointer() { SDL_ShowCursor(0); @@ -944,11 +967,25 @@ Dimension VideoDriver_SDL::GetScreenSize() const bool VideoDriver_SDL::LockVideoBuffer() { + if (this->buffer_locked) return false; + this->buffer_locked = true; + if (this->draw_threaded) this->draw_lock.lock(); + + _screen.dst_ptr = this->GetVideoPointer(); + assert(_screen.dst_ptr != nullptr); + return true; } void VideoDriver_SDL::UnlockVideoBuffer() { + if (_screen.dst_ptr != nullptr) { + /* Hand video buffer back to the drawing backend. */ + this->ReleaseVideoPointer(); + _screen.dst_ptr = nullptr; + } + if (this->draw_threaded) this->draw_lock.unlock(); + this->buffer_locked = false; } diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index 8793ade18..19c208cfe 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -52,6 +52,7 @@ protected: std::recursive_mutex *draw_mutex = nullptr; ///< Mutex to keep the access to the shared memory controlled. std::condition_variable_any *draw_signal = nullptr; ///< Signal to draw the next frame. volatile bool draw_continue; ///< Should we keep continue drawing? + bool buffer_locked; ///< Video buffer was locked by the main thread. Dimension GetScreenSize() const override; void InputLoop() override; @@ -61,8 +62,17 @@ protected: void PaintThread() override; void CheckPaletteAnim() override; + /** Indicate to the driver the client-side might have changed. */ + void ClientSizeChanged(int w, int h, bool force); + /** (Re-)create the backing store. */ virtual bool AllocateBackingStore(int w, int h, bool force = false); + /** Get a pointer to the video buffer. */ + virtual void *GetVideoPointer(); + /** Hand video buffer back to the painting backend. */ + virtual void ReleaseVideoPointer() {} + /** Create the main window. */ + virtual bool CreateMainWindow(uint w, uint h, uint flags = 0); private: int PollEvent(); -- cgit v1.2.3-54-g00ecf