summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/osx/OpenGL
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /xbmc/windowing/osx/OpenGL
parentInitial commit. (diff)
downloadkodi-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.txt14
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.h18
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.mm111
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLWindow.h19
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLWindow.mm245
-rw-r--r--xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h35
-rw-r--r--xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm79
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;
+}
+