diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/windowing/osx/OpenGL | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/windowing/osx/OpenGL')
-rw-r--r-- | xbmc/windowing/osx/OpenGL/CMakeLists.txt | 14 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/OSXGLView.h | 18 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/OSXGLView.mm | 111 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/OSXGLWindow.h | 19 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/OSXGLWindow.mm | 245 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h | 35 | ||||
-rw-r--r-- | xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm | 79 |
7 files changed, 521 insertions, 0 deletions
diff --git a/xbmc/windowing/osx/OpenGL/CMakeLists.txt b/xbmc/windowing/osx/OpenGL/CMakeLists.txt new file mode 100644 index 0000000..fd250d7 --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/CMakeLists.txt @@ -0,0 +1,14 @@ +if(OPENGL_FOUND) + set(SOURCES WinSystemOSXGL.mm) + set(HEADERS WinSystemOSXGL.h) + + if(NOT SDL_FOUND) + list(APPEND SOURCES OSXGLView.mm + OSXGLWindow.mm) + list(APPEND HEADERS OSXGLView.h + OSXGLWindow.h) + endif() + + core_add_library(windowing_osx_opengl) + +endif() diff --git a/xbmc/windowing/osx/OpenGL/OSXGLView.h b/xbmc/windowing/osx/OpenGL/OSXGLView.h new file mode 100644 index 0000000..577642d --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/OSXGLView.h @@ -0,0 +1,18 @@ +#pragma once + +/* + * Copyright (C) 2021- Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#import <Cocoa/Cocoa.h> + +@interface OSXGLView : NSOpenGLView + +- (id)initWithFrame:(NSRect)frameRect; +- (NSOpenGLContext*)getGLContext; + +@end diff --git a/xbmc/windowing/osx/OpenGL/OSXGLView.mm b/xbmc/windowing/osx/OpenGL/OSXGLView.mm new file mode 100644 index 0000000..6c0a8b5 --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/OSXGLView.mm @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2021- Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#import "OSXGLView.h" + +#include "ServiceBroker.h" +#include "application/AppInboundProtocol.h" +#include "application/AppParamParser.h" +#include "application/Application.h" +#include "messaging/ApplicationMessenger.h" +#include "settings/AdvancedSettings.h" +#include "settings/SettingsComponent.h" +#include "utils/log.h" + +#include "system_gl.h" + +@implementation OSXGLView +{ + NSOpenGLContext* m_glcontext; + NSOpenGLPixelFormat* m_pixFmt; + NSTrackingArea* m_trackingArea; + BOOL pause; +} + +- (id)initWithFrame:(NSRect)frameRect +{ + NSOpenGLPixelFormatAttribute wattrs[] = { + NSOpenGLPFANoRecovery, NSOpenGLPFAAccelerated, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32, + NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)24, + NSOpenGLPFADoubleBuffer, (NSOpenGLPixelFormatAttribute)0}; + + self = [super initWithFrame:frameRect]; + if (self) + { + m_pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:wattrs]; + m_glcontext = [[NSOpenGLContext alloc] initWithFormat:m_pixFmt shareContext:nil]; + } + + [self updateTrackingAreas]; + + GLint swapInterval = 1; + [m_glcontext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + [m_glcontext makeCurrentContext]; + + return self; +} + +- (void)dealloc +{ + [NSOpenGLContext clearCurrentContext]; + [m_glcontext clearDrawable]; +} + +- (void)drawRect:(NSRect)rect +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [m_glcontext setView:self]; + + // clear screen on first render + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0, 0, 0, 0); + + [m_glcontext update]; + }); +} + +- (void)updateTrackingAreas +{ + if (m_trackingArea != nil) + { + [self removeTrackingArea:m_trackingArea]; + } + + const int opts = + (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways); + m_trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds + options:opts + owner:self + userInfo:nil]; + [self addTrackingArea:m_trackingArea]; +} + +- (void)mouseEntered:(NSEvent*)theEvent +{ + [NSCursor hide]; +} + +- (void)mouseMoved:(NSEvent*)theEvent +{ +} + +- (void)mouseExited:(NSEvent*)theEvent +{ + [NSCursor unhide]; +} + +- (NSOpenGLContext*)getGLContext +{ + return m_glcontext; +} +@end diff --git a/xbmc/windowing/osx/OpenGL/OSXGLWindow.h b/xbmc/windowing/osx/OpenGL/OSXGLWindow.h new file mode 100644 index 0000000..a722804 --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/OSXGLWindow.h @@ -0,0 +1,19 @@ +#pragma once + +/* + * Copyright (C) 2021- Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#import <Cocoa/Cocoa.h> + +@interface OSXGLWindow : NSWindow <NSWindowDelegate> + +@property(atomic) bool resizeState; + +- (id)initWithContentRect:(NSRect)box styleMask:(uint)style; + +@end diff --git a/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm new file mode 100644 index 0000000..8ee26fc --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2021- Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#import "OSXGLWindow.h" + +#include "ServiceBroker.h" +#include "application/AppInboundProtocol.h" +#include "application/AppParamParser.h" +#include "application/Application.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIWindowManager.h" +#include "messaging/ApplicationMessenger.h" +#include "settings/DisplaySettings.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#import "windowing/osx/OpenGL/OSXGLView.h" +#include "windowing/osx/WinEventsOSX.h" +#import "windowing/osx/WinSystemOSX.h" + +#include "platform/darwin/osx/CocoaInterface.h" + +//------------------------------------------------------------------------------------------ +@implementation OSXGLWindow + +@synthesize resizeState = m_resizeState; + +- (id)initWithContentRect:(NSRect)box styleMask:(uint)style +{ + self = [super initWithContentRect:box styleMask:style backing:NSBackingStoreBuffered defer:YES]; + [self setDelegate:self]; + [self setAcceptsMouseMovedEvents:YES]; + // autosave the window position/size + // Tell the controller to not cascade its windows. + [self.windowController setShouldCascadeWindows:NO]; + [self setFrameAutosaveName:@"OSXGLWindowPositionHeightWidth"]; + + g_application.m_AppFocused = true; + + return self; +} + +- (void)dealloc +{ + [self setDelegate:nil]; +} + +- (BOOL)windowShouldClose:(id)sender +{ + if (!g_application.m_bStop) + CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT); + + return NO; +} + +- (void)windowDidExpose:(NSNotification*)aNotification +{ + g_application.m_AppFocused = true; +} + +- (void)windowDidMove:(NSNotification*)aNotification +{ + NSOpenGLContext* context = NSOpenGLContext.currentContext; + if (context) + { + if (context.view) + { + NSPoint window_origin = [[[context view] window] frame].origin; + XBMC_Event newEvent = {}; + newEvent.type = XBMC_VIDEOMOVE; + newEvent.move.x = window_origin.x; + newEvent.move.y = window_origin.y; + std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort(); + if (appPort) + appPort->OnEvent(newEvent); + } + } +} + +- (void)windowWillStartLiveResize:(NSNotification*)notification +{ + m_resizeState = true; +} + +- (void)windowDidEndLiveResize:(NSNotification*)notification +{ + m_resizeState = false; + [self windowDidResize:notification]; +} + +- (void)windowDidResize:(NSNotification*)aNotification +{ + if (!m_resizeState) + { + NSRect rect = [self contentRectForFrameRect:self.frame]; + int width = static_cast<int>(rect.size.width); + int height = static_cast<int>(rect.size.height); + + XBMC_Event newEvent = {}; + + if (!CServiceBroker::GetWinSystem()->IsFullScreen()) + { + RESOLUTION res_index = RES_DESKTOP; + if ((width == CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iWidth) && + (height == CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iHeight)) + return; + + newEvent.type = XBMC_VIDEORESIZE; + } + else + { + // macos may trigger a resize/rescale event just after Kodi has entered fullscreen + // (from windowDidEndLiveResize). Kodi needs to rescale the UI - use a different event + // type since XBMC_VIDEORESIZE is supposed to only be used in windowed mode + newEvent.type = XBMC_FULLSCREEN_UPDATE; + newEvent.move.x = -1; + newEvent.move.y = -1; + } + + newEvent.resize.w = width; + newEvent.resize.h = height; + + // check for valid sizes cause in some cases + // we are hit during fullscreen transition from macos + // and might be technically "zero" sized + if (newEvent.resize.w != 0 && newEvent.resize.h != 0) + { + std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort(); + if (appPort) + appPort->OnEvent(newEvent); + } + } +} + +- (void)windowDidChangeScreen:(NSNotification*)notification +{ + // user has moved the window to a + // different screen + // if (CServiceBroker::GetWinSystem()->IsFullScreen()) + // CServiceBroker::GetWinSystem()->SetMovedToOtherScreen(true); +} + +- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize +{ + return frameSize; +} + +- (void)windowWillEnterFullScreen:(NSNotification*)pNotification +{ + CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem()); + if (!winSystem) + return; + + // if osx is the issuer of the toggle + // call Kodi's toggle function + if (!winSystem->GetFullscreenWillToggle()) + { + // indicate that we are toggling + // flag will be reset in SetFullscreen once its + // called from Kodi's gui thread + winSystem->SetFullscreenWillToggle(true); + + CServiceBroker::GetAppMessenger()->PostMsg(TMSG_TOGGLEFULLSCREEN); + } + else + { + // in this case we are just called because + // of Kodi did a toggle - just reset the flag + // we don't need to do anything else + winSystem->SetFullscreenWillToggle(false); + } +} + +- (void)windowDidExitFullScreen:(NSNotification*)pNotification +{ + auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem()); + if (!winSystem) + return; + + // if osx is the issuer of the toggle + // call Kodi's toggle function + if (!winSystem->GetFullscreenWillToggle()) + { + // indicate that we are toggling + // flag will be reset in SetFullscreen once its + // called from Kodi's gui thread + winSystem->SetFullscreenWillToggle(true); + CServiceBroker::GetAppMessenger()->PostMsg(TMSG_TOGGLEFULLSCREEN); + } + else + { + // in this case we are just called because + // of Kodi did a toggle - just reset the flag + // we don't need to do anything else + winSystem->SetFullscreenWillToggle(false); + } +} + +- (NSApplicationPresentationOptions)window:(NSWindow*)window + willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions +{ + // customize our appearance when entering full screen: + // we don't want the dock to appear but we want the menubar to hide/show automatically + // + return (NSApplicationPresentationFullScreen | // support full screen for this window (required) + NSApplicationPresentationHideDock | // completely hide the dock + NSApplicationPresentationAutoHideMenuBar); // yes we want the menu bar to show/hide +} + +- (void)windowDidMiniaturize:(NSNotification*)aNotification +{ + g_application.m_AppFocused = false; +} + +- (void)windowDidDeminiaturize:(NSNotification*)aNotification +{ + g_application.m_AppFocused = true; +} + +- (void)windowDidBecomeKey:(NSNotification*)aNotification +{ + g_application.m_AppFocused = true; + + auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem()); + if (winSystem) + { + winSystem->enableInputEvents(); + } +} + +- (void)windowDidResignKey:(NSNotification*)aNotification +{ + g_application.m_AppFocused = false; + + auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem()); + if (winSystem) + { + winSystem->disableInputEvents(); + } +} +@end diff --git a/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h new file mode 100644 index 0000000..c38e5e3 --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#if defined(HAS_SDL) +#include "windowing/osx/SDL/WinSystemOSXSDL.h" +#else +#include "windowing/osx/WinSystemOSX.h" +#endif +#include "rendering/gl/RenderSystemGL.h" + +class CWinSystemOSXGL : public CWinSystemOSX, public CRenderSystemGL +{ +public: + CWinSystemOSXGL() = default; + ~CWinSystemOSXGL() override = default; + + static void Register(); + static std::unique_ptr<CWinSystemBase> CreateWinSystem(); + + // Implementation of CWinSystemBase via CWinSystemOSX + CRenderSystemBase *GetRenderSystem() override { return this; } + bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override; + bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override; + +protected: + void PresentRenderImpl(bool rendered) override; + void SetVSyncImpl(bool enable) override; +}; diff --git a/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm new file mode 100644 index 0000000..30e44f2 --- /dev/null +++ b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "WinSystemOSXGL.h" + +#include "guilib/Texture.h" +#include "rendering/gl/RenderSystemGL.h" +#include "windowing/WindowSystemFactory.h" + +#include <unistd.h> + +void CWinSystemOSXGL::Register() +{ + KODI::WINDOWING::CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem); +} + +std::unique_ptr<CWinSystemBase> CWinSystemOSXGL::CreateWinSystem() +{ + return std::make_unique<CWinSystemOSXGL>(); +} + +void CWinSystemOSXGL::PresentRenderImpl(bool rendered) +{ + if (rendered) + FlushBuffer(); + + // FlushBuffer does not block if window is obscured + // in this case we need to throttle the render loop + if (IsObscured()) + usleep(10000); + + if (m_delayDispReset && m_dispResetTimer.IsTimePast()) + { + m_delayDispReset = false; + AnnounceOnResetDevice(); + } +} + +void CWinSystemOSXGL::SetVSyncImpl(bool enable) +{ + EnableVSync(false); + + if (enable) + { + EnableVSync(true); + } +} + +bool CWinSystemOSXGL::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) +{ + CWinSystemOSX::ResizeWindow(newWidth, newHeight, newLeft, newTop); + CRenderSystemGL::ResetRenderSystem(newWidth, newHeight); + + if (m_bVSync) + { + EnableVSync(m_bVSync); + } + + return true; +} + +bool CWinSystemOSXGL::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) +{ + CWinSystemOSX::SetFullScreen(fullScreen, res, blankOtherDisplays); + CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight); + + if (m_bVSync) + { + EnableVSync(m_bVSync); + } + + return true; +} + |