Merge pull request #26273 from 78andyp/blurayfixes2
[xbmc.git] / xbmc / windowing / gbm / WinSystemGbmGLContext.cpp
blob00b47e47d55047b69d03cdc05f28507a5ae28810
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "WinSystemGbmGLContext.h"
11 #include "OptionalsReg.h"
12 #include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h"
13 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMAOpenGL.h"
14 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h"
15 #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
16 #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h"
17 #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
18 #include "rendering/gl/ScreenshotSurfaceGL.h"
19 #include "utils/BufferObjectFactory.h"
20 #include "utils/DMAHeapBufferObject.h"
21 #include "utils/DumbBufferObject.h"
22 #include "utils/GBMBufferObject.h"
23 #include "utils/UDMABufferObject.h"
24 #include "utils/XTimeUtils.h"
25 #include "utils/log.h"
26 #include "windowing/WindowSystemFactory.h"
28 #include <mutex>
30 #include <EGL/eglext.h>
32 using namespace KODI::WINDOWING::GBM;
34 using namespace std::chrono_literals;
36 CWinSystemGbmGLContext::CWinSystemGbmGLContext()
37 : CWinSystemGbmEGLContext(EGL_PLATFORM_GBM_MESA, "EGL_MESA_platform_gbm")
40 void CWinSystemGbmGLContext::Register()
42 CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "gbm");
45 std::unique_ptr<CWinSystemBase> CWinSystemGbmGLContext::CreateWinSystem()
47 return std::make_unique<CWinSystemGbmGLContext>();
50 bool CWinSystemGbmGLContext::InitWindowSystem()
52 VIDEOPLAYER::CRendererFactory::ClearRenderer();
53 CDVDFactoryCodec::ClearHWAccels();
54 CLinuxRendererGL::Register();
55 RETRO::CRPProcessInfoGbm::Register();
56 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryDMAOpenGL);
57 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGL);
59 if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_BIT, EGL_OPENGL_API))
61 return false;
64 bool general, deepColor;
65 m_vaapiProxy.reset(VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor()));
66 VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay());
67 VAAPIRegisterRenderGL(m_vaapiProxy.get(), general, deepColor);
69 if (general)
71 VAAPIRegister(m_vaapiProxy.get(), deepColor);
74 CScreenshotSurfaceGL::Register();
76 CBufferObjectFactory::ClearBufferObjects();
77 CDumbBufferObject::Register();
78 #if defined(HAS_GBM_BO_MAP)
79 CGBMBufferObject::Register();
80 #endif
81 #if defined(HAVE_LINUX_MEMFD) && defined(HAVE_LINUX_UDMABUF)
82 CUDMABufferObject::Register();
83 #endif
84 #if defined(HAVE_LINUX_DMA_HEAP)
85 CDMAHeapBufferObject::Register();
86 #endif
88 return true;
91 bool CWinSystemGbmGLContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
93 if (res.iWidth != m_nWidth ||
94 res.iHeight != m_nHeight)
96 CLog::Log(LOGDEBUG, "CWinSystemGbmGLContext::{} - resolution changed, creating a new window",
97 __FUNCTION__);
98 CreateNewWindow("", fullScreen, res);
101 if (!m_eglContext.TrySwapBuffers())
103 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
104 throw std::runtime_error("eglSwapBuffers failed");
107 CWinSystemGbm::SetFullScreen(fullScreen, res, blankOtherDisplays);
108 CRenderSystemGL::ResetRenderSystem(res.iWidth, res.iHeight);
110 return true;
113 void CWinSystemGbmGLContext::PresentRender(bool rendered, bool videoLayer)
115 if (!m_bRenderCreated)
116 return;
118 if (rendered || videoLayer)
120 if (rendered)
122 #if defined(EGL_ANDROID_native_fence_sync) && defined(EGL_KHR_fence_sync)
123 if (m_eglFence)
125 int fd = m_DRM->TakeOutFenceFd();
126 if (fd != -1)
128 m_eglFence->CreateKMSFence(fd);
129 m_eglFence->WaitSyncGPU();
132 m_eglFence->CreateGPUFence();
134 #endif
136 if (!m_eglContext.TrySwapBuffers())
138 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
139 throw std::runtime_error("eglSwapBuffers failed");
142 #if defined(EGL_ANDROID_native_fence_sync) && defined(EGL_KHR_fence_sync)
143 if (m_eglFence)
145 int fd = m_eglFence->FlushFence();
146 m_DRM->SetInFenceFd(fd);
148 m_eglFence->WaitSyncCPU();
150 #endif
152 CWinSystemGbm::FlipPage(rendered, videoLayer, static_cast<bool>(m_eglFence));
154 if (m_dispReset && m_dispResetTimer.IsTimePast())
156 CLog::Log(LOGDEBUG, "CWinSystemGbmGLContext::{} - Sending display reset to all clients",
157 __FUNCTION__);
158 m_dispReset = false;
159 std::unique_lock<CCriticalSection> lock(m_resourceSection);
161 for (auto resource : m_resources)
162 resource->OnResetDisplay();
165 else
167 KODI::TIME::Sleep(10ms);
171 bool CWinSystemGbmGLContext::CreateContext()
173 const EGLint glMajor = 3;
174 const EGLint glMinor = 2;
176 CEGLAttributesVec contextAttribs;
177 contextAttribs.Add({{EGL_CONTEXT_MAJOR_VERSION_KHR, glMajor},
178 {EGL_CONTEXT_MINOR_VERSION_KHR, glMinor},
179 {EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR}});
181 if (!m_eglContext.CreateContext(contextAttribs))
183 CEGLAttributesVec fallbackContextAttribs;
184 fallbackContextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
186 if (!m_eglContext.CreateContext(fallbackContextAttribs))
188 CLog::Log(LOGERROR, "EGL context creation failed");
189 return false;
191 else
193 CLog::Log(LOGWARNING, "Your OpenGL drivers do not support OpenGL {}.{} core profile. Kodi will run in compatibility mode, but performance may suffer.", glMajor, glMinor);
197 return true;