From 7f55f0a264aa6070865ac311942c3bbf7f1e1319 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Thu, 11 Feb 2021 00:10:27 +0100 Subject: [PATCH] Codechange: [OSX] Add support for (un)locking the video buffer. --- src/video/cocoa/cocoa_v.h | 15 +++++++++++++-- src/video/cocoa/cocoa_v.mm | 33 +++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 4d683d6224..c1a6452453 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -51,13 +51,17 @@ public: void GameLoop(); - virtual void AllocateBackingStore() = 0; + virtual void AllocateBackingStore(bool force = false) = 0; protected: Rect dirty_rect; ///< Region of the screen that needs redrawing. + bool buffer_locked; ///< Video buffer was locked by the main thread. + Dimension GetScreenSize() const override; float GetDPIScale() override; void InputLoop() override; + bool LockVideoBuffer() override; + void UnlockVideoBuffer() override; void GameSizeChanged(); @@ -69,6 +73,11 @@ protected: virtual NSView* AllocateDrawView() = 0; + /** Get a pointer to the video buffer. */ + virtual void *GetVideoPointer() = 0; + /** Hand video buffer back to the drawing backend. */ + virtual void ReleaseVideoPointer() {} + private: bool PollEvent(); @@ -101,13 +110,15 @@ public: /** Return driver name */ const char *GetName() const override { return "cocoa"; } - void AllocateBackingStore() override; + void AllocateBackingStore(bool force = false) override; protected: void Paint() override; void CheckPaletteAnim() override; NSView* AllocateDrawView() override; + + void *GetVideoPointer() override { return this->buffer_depth == 8 ? this->pixel_buffer : this->window_buffer; } }; class FVideoDriver_CocoaQuartz : public DriverFactoryBase { diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 36ad0cafbb..bd8340ec1e 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -85,6 +85,7 @@ static const Dimension _default_resolutions[] = { VideoDriver_Cocoa::VideoDriver_Cocoa() { this->setup = false; + this->buffer_locked = false; this->window = nil; this->cocoaview = nil; @@ -238,6 +239,30 @@ float VideoDriver_Cocoa::GetDPIScale() return this->cocoaview != nil ? [ this->cocoaview getContentsScale ] : 1.0f; } +/** Lock video buffer for drawing if it isn't already mapped. */ +bool VideoDriver_Cocoa::LockVideoBuffer() +{ + if (this->buffer_locked) return false; + this->buffer_locked = true; + + _screen.dst_ptr = this->GetVideoPointer(); + assert(_screen.dst_ptr != nullptr); + + return true; +} + +/** Unlock video buffer. */ +void VideoDriver_Cocoa::UnlockVideoBuffer() +{ + if (_screen.dst_ptr != nullptr) { + /* Hand video buffer back to the drawing backend. */ + this->ReleaseVideoPointer(); + _screen.dst_ptr = nullptr; + } + + this->buffer_locked = false; +} + /** * Are we in fullscreen mode? * @return whether fullscreen mode is currently used @@ -366,8 +391,6 @@ bool VideoDriver_Cocoa::MakeWindow(int width, int height) this->setup = false; - this->AllocateBackingStore(); - return true; } @@ -535,6 +558,8 @@ const char *VideoDriver_CocoaQuartz::Start(const StringList ¶m) return "Could not create window"; } + this->AllocateBackingStore(true); + if (fullscreen) this->ToggleFullscreen(fullscreen); this->GameSizeChanged(); @@ -560,7 +585,7 @@ NSView *VideoDriver_CocoaQuartz::AllocateDrawView() } /** Resize the window. */ -void VideoDriver_CocoaQuartz::AllocateBackingStore() +void VideoDriver_CocoaQuartz::AllocateBackingStore(bool force) { if (this->window == nil || this->cocoaview == nil || this->setup) return; @@ -608,7 +633,7 @@ void VideoDriver_CocoaQuartz::AllocateBackingStore() _screen.width = this->window_width; _screen.height = this->window_height; _screen.pitch = this->buffer_depth == 8 ? this->window_width : this->window_pitch; - _screen.dst_ptr = this->buffer_depth == 8 ? this->pixel_buffer : this->window_buffer; + _screen.dst_ptr = this->GetVideoPointer(); /* Redraw screen */ this->MakeDirty(0, 0, _screen.width, _screen.height);