Merge pull request #26273 from 78andyp/blurayfixes2
[xbmc.git] / xbmc / windowing / gbm / WinSystemGbmGLESContext.cpp
blobf272860b70fe7e2f289ae4145887529d18ca41ad
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 "WinSystemGbmGLESContext.h"
11 #include "OptionalsReg.h"
12 #include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h"
13 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMAOpenGLES.h"
14 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
15 #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
16 #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h"
17 #include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h"
18 #include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.h"
19 #include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h"
20 #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
21 #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
22 #include "rendering/gles/ScreenshotSurfaceGLES.h"
23 #include "utils/BufferObjectFactory.h"
24 #include "utils/DMAHeapBufferObject.h"
25 #include "utils/DumbBufferObject.h"
26 #include "utils/GBMBufferObject.h"
27 #include "utils/UDMABufferObject.h"
28 #include "utils/XTimeUtils.h"
29 #include "utils/log.h"
30 #include "windowing/WindowSystemFactory.h"
32 #include <mutex>
34 #include <gbm.h>
36 using namespace KODI::WINDOWING::GBM;
38 using namespace std::chrono_literals;
40 CWinSystemGbmGLESContext::CWinSystemGbmGLESContext()
41 : CWinSystemGbmEGLContext(EGL_PLATFORM_GBM_MESA, "EGL_MESA_platform_gbm")
44 void CWinSystemGbmGLESContext::Register()
46 CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "gbm");
49 std::unique_ptr<CWinSystemBase> CWinSystemGbmGLESContext::CreateWinSystem()
51 return std::make_unique<CWinSystemGbmGLESContext>();
54 bool CWinSystemGbmGLESContext::InitWindowSystem()
56 VIDEOPLAYER::CRendererFactory::ClearRenderer();
57 CDVDFactoryCodec::ClearHWAccels();
58 CLinuxRendererGLES::Register();
59 RETRO::CRPProcessInfoGbm::Register();
60 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryDMAOpenGLES);
61 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
63 if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API))
65 return false;
68 bool general, deepColor;
69 m_vaapiProxy.reset(GBM::VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor()));
70 GBM::VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay());
71 GBM::VAAPIRegisterRenderGLES(m_vaapiProxy.get(), general, deepColor);
73 if (general)
75 GBM::VAAPIRegister(m_vaapiProxy.get(), deepColor);
78 CRendererDRMPRIMEGLES::Register();
79 CRendererDRMPRIME::Register();
80 CDVDVideoCodecDRMPRIME::Register();
81 VIDEOPLAYER::CProcessInfoGBM::Register();
83 CScreenshotSurfaceGLES::Register();
85 CBufferObjectFactory::ClearBufferObjects();
86 CDumbBufferObject::Register();
87 #if defined(HAS_GBM_BO_MAP)
88 CGBMBufferObject::Register();
89 #endif
90 #if defined(HAVE_LINUX_MEMFD) && defined(HAVE_LINUX_UDMABUF)
91 CUDMABufferObject::Register();
92 #endif
93 #if defined(HAVE_LINUX_DMA_HEAP)
94 CDMAHeapBufferObject::Register();
95 #endif
97 return true;
100 bool CWinSystemGbmGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
102 if (res.iWidth != m_nWidth ||
103 res.iHeight != m_nHeight)
105 CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::{} - resolution changed, creating a new window",
106 __FUNCTION__);
107 CreateNewWindow("", fullScreen, res);
110 if (!m_eglContext.TrySwapBuffers())
112 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
113 throw std::runtime_error("eglSwapBuffers failed");
116 CWinSystemGbm::SetFullScreen(fullScreen, res, blankOtherDisplays);
117 CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
119 return true;
122 void CWinSystemGbmGLESContext::PresentRender(bool rendered, bool videoLayer)
124 if (!m_bRenderCreated)
125 return;
127 if (rendered || videoLayer)
129 if (rendered)
131 #if defined(EGL_ANDROID_native_fence_sync) && defined(EGL_KHR_fence_sync)
132 if (m_eglFence)
134 int fd = m_DRM->TakeOutFenceFd();
135 if (fd != -1)
137 m_eglFence->CreateKMSFence(fd);
138 m_eglFence->WaitSyncGPU();
141 m_eglFence->CreateGPUFence();
143 #endif
145 if (!m_eglContext.TrySwapBuffers())
147 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
148 throw std::runtime_error("eglSwapBuffers failed");
151 #if defined(EGL_ANDROID_native_fence_sync) && defined(EGL_KHR_fence_sync)
152 if (m_eglFence)
154 int fd = m_eglFence->FlushFence();
155 m_DRM->SetInFenceFd(fd);
157 m_eglFence->WaitSyncCPU();
159 #endif
162 CWinSystemGbm::FlipPage(rendered, videoLayer, static_cast<bool>(m_eglFence));
164 if (m_dispReset && m_dispResetTimer.IsTimePast())
166 CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::{} - Sending display reset to all clients",
167 __FUNCTION__);
168 m_dispReset = false;
169 std::unique_lock<CCriticalSection> lock(m_resourceSection);
171 for (auto resource : m_resources)
172 resource->OnResetDisplay();
175 else
177 KODI::TIME::Sleep(10ms);
181 bool CWinSystemGbmGLESContext::CreateContext()
183 CEGLAttributesVec contextAttribs;
184 contextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
186 if (!m_eglContext.CreateContext(contextAttribs))
188 CLog::Log(LOGERROR, "EGL context creation failed");
189 return false;
191 return true;