[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / windowing / X11 / WinSystemX11GLESContext.cpp
blobe2367d3e646e140ca27bb8acc343c75dce381ff1
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 "WinSystemX11GLESContext.h"
11 #include "GLContextEGL.h"
12 #include "OptionalsReg.h"
13 #include "X11DPMSSupport.h"
14 #include "application/ApplicationComponents.h"
15 #include "application/ApplicationSkinHandling.h"
16 #include "cores/RetroPlayer/process/X11/RPProcessInfoX11.h"
17 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
18 #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
19 #include "cores/VideoPlayer/Process/X11/ProcessInfoX11.h"
20 #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
21 #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
22 #include "guilib/DispResource.h"
23 #include "utils/log.h"
24 #include "windowing/GraphicContext.h"
25 #include "windowing/WindowSystemFactory.h"
27 #include <mutex>
29 using namespace KODI;
30 using namespace KODI::WINDOWING::X11;
32 void CWinSystemX11GLESContext::Register()
34 KODI::WINDOWING::CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "x11");
37 std::unique_ptr<CWinSystemBase> CWinSystemX11GLESContext::CreateWinSystem()
39 return std::make_unique<CWinSystemX11GLESContext>();
42 CWinSystemX11GLESContext::~CWinSystemX11GLESContext()
44 delete m_pGLContext;
47 void CWinSystemX11GLESContext::PresentRenderImpl(bool rendered)
49 if (rendered && m_pGLContext)
50 m_pGLContext->SwapBuffers();
52 if (m_delayDispReset && m_dispResetTimer.IsTimePast())
54 m_delayDispReset = false;
55 std::unique_lock<CCriticalSection> lock(m_resourceSection);
56 // tell any shared resources
57 for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
58 (*i)->OnResetDisplay();
62 void CWinSystemX11GLESContext::SetVSyncImpl(bool enable)
64 m_pGLContext->SetVSync(enable);
67 bool CWinSystemX11GLESContext::IsExtSupported(const char* extension) const
69 if (strncmp(extension, m_pGLContext->ExtPrefix().c_str(), 4) != 0)
70 return CRenderSystemGLES::IsExtSupported(extension);
72 return m_pGLContext->IsExtSupported(extension);
75 EGLDisplay CWinSystemX11GLESContext::GetEGLDisplay() const
77 return m_pGLContext->m_eglDisplay;
80 EGLSurface CWinSystemX11GLESContext::GetEGLSurface() const
82 return m_pGLContext->m_eglSurface;
85 EGLContext CWinSystemX11GLESContext::GetEGLContext() const
87 return m_pGLContext->m_eglContext;
90 EGLConfig CWinSystemX11GLESContext::GetEGLConfig() const
92 return m_pGLContext->m_eglConfig;
95 bool CWinSystemX11GLESContext::SetWindow(int width, int height, bool fullscreen, const std::string& output, int* winstate)
97 int newwin = 0;
99 CWinSystemX11::SetWindow(width, height, fullscreen, output, &newwin);
100 if (newwin)
102 RefreshGLContext(m_currentOutput.compare(output) != 0);
103 XSync(m_dpy, false);
104 CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0);
105 CServiceBroker::GetWinSystem()->GetGfxContext().Flip(true, false);
106 ResetVSync();
108 m_windowDirty = false;
109 m_bIsInternalXrr = false;
111 if (!m_delayDispReset)
113 std::unique_lock<CCriticalSection> lock(m_resourceSection);
114 // tell any shared resources
115 for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
116 (*i)->OnResetDisplay();
119 return true;
122 bool CWinSystemX11GLESContext::CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res)
124 CLog::Log(LOGINFO, "CWinSystemX11GLESContext::CreateNewWindow");
125 if (!CWinSystemX11::CreateNewWindow(name, fullScreen, res) || !m_pGLContext)
126 return false;
128 m_pGLContext->QueryExtensions();
129 return true;
132 bool CWinSystemX11GLESContext::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
134 m_newGlContext = false;
135 CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop);
136 CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
138 if (m_newGlContext)
140 auto& components = CServiceBroker::GetAppComponents();
141 const auto appSkin = components.GetComponent<CApplicationSkinHandling>();
142 appSkin->ReloadSkin();
145 return true;
148 void CWinSystemX11GLESContext::FinishWindowResize(int newWidth, int newHeight)
150 m_newGlContext = false;
151 CWinSystemX11::FinishWindowResize(newWidth, newHeight);
152 CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
154 if (m_newGlContext)
156 auto& components = CServiceBroker::GetAppComponents();
157 const auto appSkin = components.GetComponent<CApplicationSkinHandling>();
158 appSkin->ReloadSkin();
162 bool CWinSystemX11GLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
164 m_newGlContext = false;
165 CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays);
166 CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
168 if (m_newGlContext)
170 auto& components = CServiceBroker::GetAppComponents();
171 const auto appSkin = components.GetComponent<CApplicationSkinHandling>();
172 appSkin->ReloadSkin();
175 return true;
178 bool CWinSystemX11GLESContext::DestroyWindowSystem()
180 if (m_pGLContext)
181 m_pGLContext->Destroy();
182 return CWinSystemX11::DestroyWindowSystem();
185 bool CWinSystemX11GLESContext::DestroyWindow()
187 if (m_pGLContext)
188 m_pGLContext->Detach();
189 return CWinSystemX11::DestroyWindow();
192 XVisualInfo* CWinSystemX11GLESContext::GetVisual()
194 EGLDisplay eglDisplay;
196 PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
197 reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
198 if (eglGetPlatformDisplayEXT)
200 EGLint attribs[] =
202 EGL_PLATFORM_X11_SCREEN_EXT, m_screen,
203 EGL_NONE
205 eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,static_cast<EGLNativeDisplayType>(m_dpy), attribs);
207 else
208 eglDisplay = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_dpy));
210 if (eglDisplay == EGL_NO_DISPLAY)
212 CLog::Log(LOGERROR, "failed to get egl display");
213 return nullptr;
215 if (!eglInitialize(eglDisplay, nullptr, nullptr))
217 CLog::Log(LOGERROR, "failed to initialize egl display");
218 return nullptr;
221 GLint att[] =
223 EGL_RED_SIZE, 8,
224 EGL_GREEN_SIZE, 8,
225 EGL_BLUE_SIZE, 8,
226 EGL_ALPHA_SIZE, 8,
227 EGL_BUFFER_SIZE, 32,
228 EGL_DEPTH_SIZE, 24,
229 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
230 EGL_NONE
232 EGLint numConfigs;
233 EGLConfig eglConfig = 0;
234 if (!eglChooseConfig(eglDisplay, att, &eglConfig, 1, &numConfigs) || numConfigs == 0)
236 CLog::Log(LOGERROR, "Failed to choose a config {}", eglGetError());
237 return nullptr;
240 XVisualInfo x11_visual_info_template;
241 memset(&x11_visual_info_template, 0, sizeof(XVisualInfo));
243 if (!eglGetConfigAttrib(eglDisplay, eglConfig,
244 EGL_NATIVE_VISUAL_ID, reinterpret_cast<EGLint*>(&x11_visual_info_template.visualid)))
246 CLog::Log(LOGERROR, "Failed to query native visual id");
247 return nullptr;
249 int num_visuals;
250 XVisualInfo* visual =
251 XGetVisualInfo(m_dpy, VisualIDMask, &x11_visual_info_template, &num_visuals);
252 return visual;
255 bool CWinSystemX11GLESContext::RefreshGLContext(bool force)
257 bool success = false;
258 if (m_pGLContext)
260 success = m_pGLContext->Refresh(force, m_screen, m_glWindow, m_newGlContext);
261 if (!success)
263 success = m_pGLContext->CreatePB();
264 m_newGlContext = true;
266 return success;
269 m_dpms = std::make_shared<CX11DPMSSupport>();
270 VIDEOPLAYER::CProcessInfoX11::Register();
271 RETRO::CRPProcessInfoX11::Register();
272 RETRO::CRPProcessInfoX11::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
273 CDVDFactoryCodec::ClearHWAccels();
274 VIDEOPLAYER::CRendererFactory::ClearRenderer();
275 CLinuxRendererGLES::Register();
277 std::string gli = (getenv("KODI_GL_INTERFACE") != nullptr) ? getenv("KODI_GL_INTERFACE") : "";
279 m_pGLContext = new CGLContextEGL(m_dpy, EGL_OPENGL_ES_API);
280 success = m_pGLContext->Refresh(force, m_screen, m_glWindow, m_newGlContext);
281 if (!success && gli == "EGL_PB")
283 success = m_pGLContext->CreatePB();
284 m_newGlContext = true;
287 if (!success)
289 delete m_pGLContext;
290 m_pGLContext = nullptr;
292 return success;