summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/gbm/WinSystemGbmGLContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/windowing/gbm/WinSystemGbmGLContext.cpp')
-rw-r--r--xbmc/windowing/gbm/WinSystemGbmGLContext.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/xbmc/windowing/gbm/WinSystemGbmGLContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLContext.cpp
new file mode 100644
index 0000000..e4ff49c
--- /dev/null
+++ b/xbmc/windowing/gbm/WinSystemGbmGLContext.cpp
@@ -0,0 +1,174 @@
+/*
+ * 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 "WinSystemGbmGLContext.h"
+
+#include "OptionalsReg.h"
+#include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h"
+#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.h"
+#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h"
+#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
+#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h"
+#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
+#include "rendering/gl/ScreenshotSurfaceGL.h"
+#include "utils/BufferObjectFactory.h"
+#include "utils/DMAHeapBufferObject.h"
+#include "utils/DumbBufferObject.h"
+#include "utils/GBMBufferObject.h"
+#include "utils/UDMABufferObject.h"
+#include "utils/XTimeUtils.h"
+#include "utils/log.h"
+#include "windowing/WindowSystemFactory.h"
+
+#include <mutex>
+
+#include <EGL/eglext.h>
+
+using namespace KODI::WINDOWING::GBM;
+
+using namespace std::chrono_literals;
+
+CWinSystemGbmGLContext::CWinSystemGbmGLContext()
+: CWinSystemGbmEGLContext(EGL_PLATFORM_GBM_MESA, "EGL_MESA_platform_gbm")
+{}
+
+void CWinSystemGbmGLContext::Register()
+{
+ CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "gbm");
+}
+
+std::unique_ptr<CWinSystemBase> CWinSystemGbmGLContext::CreateWinSystem()
+{
+ return std::make_unique<CWinSystemGbmGLContext>();
+}
+
+bool CWinSystemGbmGLContext::InitWindowSystem()
+{
+ VIDEOPLAYER::CRendererFactory::ClearRenderer();
+ CDVDFactoryCodec::ClearHWAccels();
+ CLinuxRendererGL::Register();
+ RETRO::CRPProcessInfoGbm::Register();
+ RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryDMA);
+ RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGL);
+
+ if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_BIT, EGL_OPENGL_API))
+ {
+ return false;
+ }
+
+ bool general, deepColor;
+ m_vaapiProxy.reset(VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor()));
+ VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay());
+ VAAPIRegisterRenderGL(m_vaapiProxy.get(), general, deepColor);
+
+ if (general)
+ {
+ VAAPIRegister(m_vaapiProxy.get(), deepColor);
+ }
+
+ CScreenshotSurfaceGL::Register();
+
+ CBufferObjectFactory::ClearBufferObjects();
+ CDumbBufferObject::Register();
+#if defined(HAS_GBM_BO_MAP)
+ CGBMBufferObject::Register();
+#endif
+#if defined(HAVE_LINUX_MEMFD) && defined(HAVE_LINUX_UDMABUF)
+ CUDMABufferObject::Register();
+#endif
+#if defined(HAVE_LINUX_DMA_HEAP)
+ CDMAHeapBufferObject::Register();
+#endif
+
+ return true;
+}
+
+bool CWinSystemGbmGLContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
+{
+ if (res.iWidth != m_nWidth ||
+ res.iHeight != m_nHeight)
+ {
+ CLog::Log(LOGDEBUG, "CWinSystemGbmGLContext::{} - resolution changed, creating a new window",
+ __FUNCTION__);
+ CreateNewWindow("", fullScreen, res);
+ }
+
+ if (!m_eglContext.TrySwapBuffers())
+ {
+ CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
+ throw std::runtime_error("eglSwapBuffers failed");
+ }
+
+ CWinSystemGbm::SetFullScreen(fullScreen, res, blankOtherDisplays);
+ CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight);
+
+ return true;
+}
+
+void CWinSystemGbmGLContext::PresentRender(bool rendered, bool videoLayer)
+{
+ if (!m_bRenderCreated)
+ return;
+
+ if (rendered || videoLayer)
+ {
+ if (rendered)
+ {
+ if (!m_eglContext.TrySwapBuffers())
+ {
+ CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
+ throw std::runtime_error("eglSwapBuffers failed");
+ }
+ }
+ CWinSystemGbm::FlipPage(rendered, videoLayer);
+
+ if (m_dispReset && m_dispResetTimer.IsTimePast())
+ {
+ CLog::Log(LOGDEBUG, "CWinSystemGbmGLContext::{} - Sending display reset to all clients",
+ __FUNCTION__);
+ m_dispReset = false;
+ std::unique_lock<CCriticalSection> lock(m_resourceSection);
+
+ for (auto resource : m_resources)
+ resource->OnResetDisplay();
+ }
+ }
+ else
+ {
+ KODI::TIME::Sleep(10ms);
+ }
+}
+
+bool CWinSystemGbmGLContext::CreateContext()
+{
+ const EGLint glMajor = 3;
+ const EGLint glMinor = 2;
+
+ CEGLAttributesVec contextAttribs;
+ contextAttribs.Add({{EGL_CONTEXT_MAJOR_VERSION_KHR, glMajor},
+ {EGL_CONTEXT_MINOR_VERSION_KHR, glMinor},
+ {EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR}});
+
+ if (!m_eglContext.CreateContext(contextAttribs))
+ {
+ CEGLAttributesVec fallbackContextAttribs;
+ fallbackContextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
+
+ if (!m_eglContext.CreateContext(fallbackContextAttribs))
+ {
+ CLog::Log(LOGERROR, "EGL context creation failed");
+ return false;
+ }
+ else
+ {
+ CLog::Log(LOGWARNING, "Your OpenGL drivers do not support OpenGL {}.{} core profile. Kodi will run in compatibility mode, but performance may suffer.", glMajor, glMinor);
+ }
+ }
+
+ return true;
+}