1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "WinSystemGbmGLESContext.h"
10
11 #include "OptionalsReg.h"
12 #include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h"
13 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.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"
31
32 #include <gbm.h>
33
34 using namespace KODI::WINDOWING::GBM;
35
CWinSystemGbmGLESContext()36 CWinSystemGbmGLESContext::CWinSystemGbmGLESContext()
37 : CWinSystemGbmEGLContext(EGL_PLATFORM_GBM_MESA, "EGL_MESA_platform_gbm")
38 {}
39
Register()40 void CWinSystemGbmGLESContext::Register()
41 {
42 CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "gbm");
43 }
44
CreateWinSystem()45 std::unique_ptr<CWinSystemBase> CWinSystemGbmGLESContext::CreateWinSystem()
46 {
47 return std::make_unique<CWinSystemGbmGLESContext>();
48 }
49
InitWindowSystem()50 bool CWinSystemGbmGLESContext::InitWindowSystem()
51 {
52 VIDEOPLAYER::CRendererFactory::ClearRenderer();
53 CDVDFactoryCodec::ClearHWAccels();
54 CLinuxRendererGLES::Register();
55 RETRO::CRPProcessInfoGbm::Register();
56 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryDMA);
57 RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
58
59 if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API))
60 {
61 return false;
62 }
63
64 bool general, deepColor;
65 m_vaapiProxy.reset(GBM::VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor()));
66 GBM::VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay());
67 GBM::VAAPIRegisterRender(m_vaapiProxy.get(), general, deepColor);
68
69 if (general)
70 {
71 GBM::VAAPIRegister(m_vaapiProxy.get(), deepColor);
72 }
73
74 CRendererDRMPRIMEGLES::Register();
75 CRendererDRMPRIME::Register();
76 CDVDVideoCodecDRMPRIME::Register();
77 VIDEOPLAYER::CProcessInfoGBM::Register();
78
79 CScreenshotSurfaceGLES::Register();
80
81 CBufferObjectFactory::ClearBufferObjects();
82 CDumbBufferObject::Register();
83 #if defined(HAS_GBM_BO_MAP)
84 CGBMBufferObject::Register();
85 #endif
86 #if defined(HAVE_LINUX_MEMFD) && defined(HAVE_LINUX_UDMABUF)
87 CUDMABufferObject::Register();
88 #endif
89 #if defined(HAVE_LINUX_DMA_HEAP)
90 CDMAHeapBufferObject::Register();
91 #endif
92
93 return true;
94 }
95
SetFullScreen(bool fullScreen,RESOLUTION_INFO & res,bool blankOtherDisplays)96 bool CWinSystemGbmGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
97 {
98 if (res.iWidth != m_nWidth ||
99 res.iHeight != m_nHeight)
100 {
101 CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::%s - resolution changed, creating a new window", __FUNCTION__);
102 CreateNewWindow("", fullScreen, res);
103 }
104
105 if (!m_eglContext.TrySwapBuffers())
106 {
107 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
108 throw std::runtime_error("eglSwapBuffers failed");
109 }
110
111 CWinSystemGbm::SetFullScreen(fullScreen, res, blankOtherDisplays);
112 CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
113
114 return true;
115 }
116
PresentRender(bool rendered,bool videoLayer)117 void CWinSystemGbmGLESContext::PresentRender(bool rendered, bool videoLayer)
118 {
119 if (!m_bRenderCreated)
120 return;
121
122 if (rendered || videoLayer)
123 {
124 if (rendered)
125 {
126 if (!m_eglContext.TrySwapBuffers())
127 {
128 CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
129 throw std::runtime_error("eglSwapBuffers failed");
130 }
131 }
132 CWinSystemGbm::FlipPage(rendered, videoLayer);
133
134 if (m_dispReset && m_dispResetTimer.IsTimePast())
135 {
136 CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::%s - Sending display reset to all clients",
137 __FUNCTION__);
138 m_dispReset = false;
139 CSingleLock lock(m_resourceSection);
140
141 for (auto resource : m_resources)
142 resource->OnResetDisplay();
143 }
144 }
145 else
146 {
147 KODI::TIME::Sleep(10);
148 }
149 }
150
CreateContext()151 bool CWinSystemGbmGLESContext::CreateContext()
152 {
153 CEGLAttributesVec contextAttribs;
154 contextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
155
156 if (!m_eglContext.CreateContext(contextAttribs))
157 {
158 CLog::Log(LOGERROR, "EGL context creation failed");
159 return false;
160 }
161 return true;
162 }
163