aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sichler <stsichler@web.de>2019-08-16 20:24:37 +0200
committerStefan Sichler <stsichler@web.de>2019-11-04 23:19:01 +0100
commit1c91a4024388a78eef878674099eebaa3b7ed528 (patch)
tree6cbcbda64459d0446d1293e2d67b140b9934f297
parent5aaa190407255c9222ea33cbfb7d3ff09e527497 (diff)
[windowing] resurrection of X11/GLES support
-rw-r--r--cmake/platform/linux/x11.cmake16
-rw-r--r--docs/README.Linux.md4
-rw-r--r--tools/depends/target/Toolchain.cmake.in2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt1
-rw-r--r--xbmc/windowing/X11/CMakeLists.txt17
-rw-r--r--xbmc/windowing/X11/GLContextEGL.cpp39
-rw-r--r--xbmc/windowing/X11/GLContextEGL.h7
-rw-r--r--xbmc/windowing/X11/WinSystemX11GLContext.cpp2
-rw-r--r--xbmc/windowing/X11/WinSystemX11GLESContext.cpp312
-rw-r--r--xbmc/windowing/X11/WinSystemX11GLESContext.h54
11 files changed, 427 insertions, 28 deletions
diff --git a/cmake/platform/linux/x11.cmake b/cmake/platform/linux/x11.cmake
index 72d9640766..c661721b73 100644
--- a/cmake/platform/linux/x11.cmake
+++ b/cmake/platform/linux/x11.cmake
@@ -1,4 +1,16 @@
-set(PLATFORM_REQUIRED_DEPS OpenGl EGL X XRandR LibDRM)
+set(PLATFORM_REQUIRED_DEPS EGL X XRandR LibDRM)
set(PLATFORM_OPTIONAL_DEPS VAAPI VDPAU GLX)
-set(APP_RENDER_SYSTEM gl)
+
+set(X11_RENDER_SYSTEM "" CACHE STRING "Render system to use with X11: \"gl\" or \"gles\"")
+
+if(X11_RENDER_SYSTEM STREQUAL "gl")
+ list(APPEND PLATFORM_REQUIRED_DEPS OpenGl)
+ set(APP_RENDER_SYSTEM gl)
+elseif(X11_RENDER_SYSTEM STREQUAL "gles")
+ list(APPEND PLATFORM_REQUIRED_DEPS OpenGLES)
+ set(APP_RENDER_SYSTEM gles)
+else()
+ message(SEND_ERROR "You need to decide whether you want to use GL- or GLES-based rendering in combination with the X11 windowing system. Please set X11_RENDER_SYSTEM to either \"gl\" or \"gles\". For normal desktop systems, you will usually want to use \"gl\".")
+endif()
+
list(APPEND PLATFORM_DEFINES -DPLATFORM_SETTINGS_FILE=x11.xml) \ No newline at end of file
diff --git a/docs/README.Linux.md b/docs/README.Linux.md
index 10e4b3d60d..689a13b26e 100644
--- a/docs/README.Linux.md
+++ b/docs/README.Linux.md
@@ -134,9 +134,11 @@ cd $HOME/kodi-build
Configure build for X11:
```
-cmake ../kodi -DCMAKE_INSTALL_PREFIX=/usr/local
+cmake ../kodi -DCMAKE_INSTALL_PREFIX=/usr/local -DX11_RENDER_SYSTEM=gl
```
+**NOTE:** You can use `gles` instead of `gl` if you want to build with `GLES`.
+
Or configure build for Wayland:
```
cmake ../kodi -DCMAKE_INSTALL_PREFIX=/usr/local -DCORE_PLATFORM_NAME=wayland -DWAYLAND_RENDER_SYSTEM=gl
diff --git a/tools/depends/target/Toolchain.cmake.in b/tools/depends/target/Toolchain.cmake.in
index ec171a22bc..c43915ab8c 100644
--- a/tools/depends/target/Toolchain.cmake.in
+++ b/tools/depends/target/Toolchain.cmake.in
@@ -18,9 +18,11 @@ if(OS STREQUAL linux)
set(CORE_PLATFORM_NAME @target_platform@)
endif()
if(NOT "@app_rendersystem@" STREQUAL "")
+ set(X11_RENDER_SYSTEM @app_rendersystem@ CACHE STRING "Render system to use with X11: \"gl\" or \"gles\"")
set(WAYLAND_RENDER_SYSTEM @app_rendersystem@ CACHE STRING "Render system to use with Wayland: \"gl\" or \"gles\"")
set(GBM_RENDER_SYSTEM @app_rendersystem@ CACHE STRING "Render system to use with GBM: \"gl\" or \"gles\"")
else()
+ set(X11_RENDER_SYSTEM gl CACHE STRING "Render system to use with X11: \"gl\" or \"gles\"")
set(WAYLAND_RENDER_SYSTEM gl CACHE STRING "Render system to use with Wayland: \"gl\" or \"gles\"")
set(GBM_RENDER_SYSTEM gles CACHE STRING "Render system to use with GBM: \"gl\" or \"gles\"")
endif()
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
index a5c565552b..c6150b2878 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
@@ -43,6 +43,7 @@ endif()
if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR
CORE_PLATFORM_NAME_LC STREQUAL ios OR
CORE_PLATFORM_NAME_LC STREQUAL gbm OR
+ CORE_PLATFORM_NAME_LC STREQUAL x11 OR
CORE_PLATFORM_NAME_LC STREQUAL wayland))
list(APPEND SOURCES LinuxRendererGLES.cpp
FrameBufferObject.cpp)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
index b8b1331a7a..bf48f39829 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
@@ -25,6 +25,7 @@ endif()
if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR
CORE_PLATFORM_NAME_LC STREQUAL ios OR
CORE_PLATFORM_NAME_LC STREQUAL gbm OR
+ CORE_PLATFORM_NAME_LC STREQUAL x11 OR
CORE_PLATFORM_NAME_LC STREQUAL wayland))
list(APPEND SOURCES ConversionMatrix.cpp
VideoFilterShaderGLES.cpp
diff --git a/xbmc/windowing/X11/CMakeLists.txt b/xbmc/windowing/X11/CMakeLists.txt
index deaa7fbc83..3951c9b77d 100644
--- a/xbmc/windowing/X11/CMakeLists.txt
+++ b/xbmc/windowing/X11/CMakeLists.txt
@@ -4,9 +4,7 @@ set(SOURCES GLContextEGL.cpp
OSScreenSaverX11.cpp
WinEventsX11.cpp
WinSystemX11.cpp
- WinSystemX11GLContext.cpp
XRandR.cpp
- VideoSyncOML.cpp
X11DPMSSupport.cpp)
set(HEADERS GLContext.h
@@ -15,10 +13,8 @@ set(HEADERS GLContext.h
OSScreenSaverX11.h
WinEventsX11.h
WinSystemX11.h
- WinSystemX11GLContext.h
XRandR.h
- VideoSyncOML.h
- X11DPMSSupport.h)
+ X11DPMSSupport.cpp)
if(GLX_FOUND)
list(APPEND SOURCES GLContextGLX.cpp
@@ -27,4 +23,15 @@ if(GLX_FOUND)
VideoSyncGLX.h)
endif()
+if(OPENGL_FOUND)
+ list(APPEND SOURCES WinSystemX11GLContext.cpp)
+ list(APPEND HEADERS WinSystemX11GLContext.h)
+ list(APPEND SOURCES VideoSyncOML.cpp)
+ list(APPEND HEADERS VideoSyncOML.h)
+endif()
+if(OPENGLES_FOUND)
+ list(APPEND SOURCES WinSystemX11GLESContext.cpp)
+ list(APPEND HEADERS WinSystemX11GLESContext.h)
+endif()
+
core_add_library(windowing_X11)
diff --git a/xbmc/windowing/X11/GLContextEGL.cpp b/xbmc/windowing/X11/GLContextEGL.cpp
index 227ba4b16d..61d410a056 100644
--- a/xbmc/windowing/X11/GLContextEGL.cpp
+++ b/xbmc/windowing/X11/GLContextEGL.cpp
@@ -25,15 +25,17 @@
#define EGL_NO_CONFIG (EGLConfig)0
-CGLContextEGL::CGLContextEGL(Display *dpy) : CGLContext(dpy)
+CGLContextEGL::CGLContextEGL(Display *dpy, EGLint renderingApi) : CGLContext(dpy)
{
m_extPrefix = "EGL_";
+ m_renderingApi = renderingApi;
+
m_eglDisplay = EGL_NO_DISPLAY;
m_eglSurface = EGL_NO_SURFACE;
m_eglContext = EGL_NO_CONTEXT;
m_eglConfig = EGL_NO_CONFIG;
- eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
+ m_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
CSettingsComponent *settings = CServiceBroker::GetSettingsComponent();
if (settings)
@@ -73,14 +75,14 @@ bool CGLContextEGL::Refresh(bool force, int screen, Window glWindow, bool &newCo
Destroy();
newContext = true;
- if (eglGetPlatformDisplayEXT)
+ if (m_eglGetPlatformDisplayEXT)
{
EGLint attribs[] =
{
EGL_PLATFORM_X11_SCREEN_EXT, screen,
EGL_NONE
};
- m_eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,(EGLNativeDisplayType)m_dpy,
+ m_eglDisplay = m_eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,(EGLNativeDisplayType)m_dpy,
attribs);
}
else
@@ -97,10 +99,9 @@ bool CGLContextEGL::Refresh(bool force, int screen, Window glWindow, bool &newCo
Destroy();
return false;
}
-
- if (!eglBindAPI(EGL_OPENGL_API))
+ if (!eglBindAPI(m_renderingApi))
{
- CLog::Log(LOGERROR, "failed to initialize egl");
+ CLog::Log(LOGERROR, "failed to bind rendering API");
Destroy();
return false;
}
@@ -174,8 +175,8 @@ bool CGLContextEGL::Refresh(bool force, int screen, Window glWindow, bool &newCo
return false;
}
- CLog::Log(LOGWARNING, "Failed to get an OpenGL context supporting core profile 3.2, \
- using legacy mode with reduced feature set");
+ CLog::Log(LOGWARNING, "Failed to get an OpenGL context supporting core profile 3.2, "
+ "using legacy mode with reduced feature set");
}
if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
@@ -185,7 +186,7 @@ bool CGLContextEGL::Refresh(bool force, int screen, Window glWindow, bool &newCo
return false;
}
- eglGetSyncValuesCHROMIUM = (PFNEGLGETSYNCVALUESCHROMIUMPROC)eglGetProcAddress("eglGetSyncValuesCHROMIUM");
+ m_eglGetSyncValuesCHROMIUM = (PFNEGLGETSYNCVALUESCHROMIUMPROC)eglGetProcAddress("eglGetSyncValuesCHROMIUM");
m_usePB = false;
return true;
@@ -213,9 +214,9 @@ bool CGLContextEGL::CreatePB()
Destroy();
- if (eglGetPlatformDisplayEXT)
+ if (m_eglGetPlatformDisplayEXT)
{
- m_eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,(EGLNativeDisplayType)m_dpy,
+ m_eglDisplay = m_eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,(EGLNativeDisplayType)m_dpy,
NULL);
}
else
@@ -232,9 +233,9 @@ bool CGLContextEGL::CreatePB()
Destroy();
return false;
}
- if (!eglBindAPI(EGL_OPENGL_API))
+ if (!eglBindAPI(m_renderingApi))
{
- CLog::Log(LOGERROR, "failed to initialize egl");
+ CLog::Log(LOGERROR, "failed to bind rendering API");
Destroy();
return false;
}
@@ -419,14 +420,20 @@ void CGLContextEGL::SwapBuffers()
uint64_t cont = m_sync.cont;
uint64_t interval = m_sync.interval;
- eglGetSyncValuesCHROMIUM(m_eglDisplay, m_eglSurface, &ust1, &msc1, &sbc1);
+ if (m_eglGetSyncValuesCHROMIUM)
+ {
+ m_eglGetSyncValuesCHROMIUM(m_eglDisplay, m_eglSurface, &ust1, &msc1, &sbc1);
+ }
eglSwapBuffers(m_eglDisplay, m_eglSurface);
+ if (!m_eglGetSyncValuesCHROMIUM)
+ return;
+
clock_gettime(CLOCK_MONOTONIC, &nowTs);
now = static_cast<uint64_t>(nowTs.tv_sec) * 1000000000ULL + nowTs.tv_nsec;
- eglGetSyncValuesCHROMIUM(m_eglDisplay, m_eglSurface, &ust2, &msc2, &sbc2);
+ m_eglGetSyncValuesCHROMIUM(m_eglDisplay, m_eglSurface, &ust2, &msc2, &sbc2);
if ((msc1 - m_sync.msc1) > 2)
{
diff --git a/xbmc/windowing/X11/GLContextEGL.h b/xbmc/windowing/X11/GLContextEGL.h
index 3dc50dce68..f4aecac9ee 100644
--- a/xbmc/windowing/X11/GLContextEGL.h
+++ b/xbmc/windowing/X11/GLContextEGL.h
@@ -19,7 +19,7 @@
class CGLContextEGL : public CGLContext
{
public:
- explicit CGLContextEGL(Display *dpy);
+ explicit CGLContextEGL(Display *dpy, EGLint renderingApi);
~CGLContextEGL() override;
bool Refresh(bool force, int screen, Window glWindow, bool &newContext) override;
bool CreatePB() override;
@@ -30,6 +30,7 @@ public:
void QueryExtensions() override;
uint64_t GetVblankTiming(uint64_t &msc, uint64_t &interval) override;
+ EGLint m_renderingApi;
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
EGLContext m_eglContext;
@@ -37,8 +38,8 @@ public:
protected:
bool SuitableCheck(EGLDisplay eglDisplay, EGLConfig config);
EGLConfig GetEGLConfig(EGLDisplay eglDisplay, XVisualInfo *vInfo);
- PFNEGLGETSYNCVALUESCHROMIUMPROC eglGetSyncValuesCHROMIUM = nullptr;
- PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = nullptr;
+ PFNEGLGETSYNCVALUESCHROMIUMPROC m_eglGetSyncValuesCHROMIUM = nullptr;
+ PFNEGLGETPLATFORMDISPLAYEXTPROC m_eglGetPlatformDisplayEXT = nullptr;
struct Sync
{
diff --git a/xbmc/windowing/X11/WinSystemX11GLContext.cpp b/xbmc/windowing/X11/WinSystemX11GLContext.cpp
index 8ff2abdd1d..db6198bdf3 100644
--- a/xbmc/windowing/X11/WinSystemX11GLContext.cpp
+++ b/xbmc/windowing/X11/WinSystemX11GLContext.cpp
@@ -284,7 +284,7 @@ bool CWinSystemX11GLContext::RefreshGLContext(bool force)
if (gli != "GLX")
{
- m_pGLContext = new CGLContextEGL(m_dpy);
+ m_pGLContext = new CGLContextEGL(m_dpy, EGL_OPENGL_API);
success = m_pGLContext->Refresh(force, m_screen, m_glWindow, m_newGlContext);
if (success)
{
diff --git a/xbmc/windowing/X11/WinSystemX11GLESContext.cpp b/xbmc/windowing/X11/WinSystemX11GLESContext.cpp
new file mode 100644
index 0000000000..152b97fffc
--- /dev/null
+++ b/xbmc/windowing/X11/WinSystemX11GLESContext.cpp
@@ -0,0 +1,312 @@
+/*
+ * 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 "WinSystemX11GLESContext.h"
+
+#include "Application.h"
+#include "GLContextEGL.h"
+#include "OptionalsReg.h"
+#include "X11DPMSSupport.h"
+#include "cores/RetroPlayer/process/X11/RPProcessInfoX11.h"
+#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
+#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h"
+#include "cores/VideoPlayer/Process/X11/ProcessInfoX11.h"
+#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
+#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h"
+#include "guilib/DispResource.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "windowing/GraphicContext.h"
+
+#include "platform/linux/OptionalsReg.h"
+
+using namespace KODI;
+
+std::unique_ptr<CWinSystemBase> CWinSystemBase::CreateWinSystem()
+{
+ std::unique_ptr<CWinSystemBase> winSystem(new CWinSystemX11GLESContext());
+ return winSystem;
+}
+
+CWinSystemX11GLESContext::CWinSystemX11GLESContext()
+{
+ std::string envSink;
+ if (getenv("KODI_AE_SINK"))
+ envSink = getenv("KODI_AE_SINK");
+ if (StringUtils::EqualsNoCase(envSink, "ALSA"))
+ {
+ OPTIONALS::ALSARegister();
+ }
+ else if (StringUtils::EqualsNoCase(envSink, "PULSE"))
+ {
+ OPTIONALS::PulseAudioRegister();
+ }
+ else if (StringUtils::EqualsNoCase(envSink, "OSS"))
+ {
+ OPTIONALS::OSSRegister();
+ }
+ else if (StringUtils::EqualsNoCase(envSink, "SNDIO"))
+ {
+ OPTIONALS::SndioRegister();
+ }
+ else
+ {
+ if (!OPTIONALS::PulseAudioRegister())
+ {
+ if (!OPTIONALS::ALSARegister())
+ {
+ if (!OPTIONALS::SndioRegister())
+ {
+ OPTIONALS::OSSRegister();
+ }
+ }
+ }
+ }
+
+ m_lirc.reset(OPTIONALS::LircRegister());
+}
+
+CWinSystemX11GLESContext::~CWinSystemX11GLESContext()
+{
+ delete m_pGLContext;
+}
+
+void CWinSystemX11GLESContext::PresentRenderImpl(bool rendered)
+{
+ if (rendered && m_pGLContext)
+ m_pGLContext->SwapBuffers();
+
+ if (m_delayDispReset && m_dispResetTimer.IsTimePast())
+ {
+ m_delayDispReset = false;
+ CSingleLock lock(m_resourceSection);
+ // tell any shared resources
+ for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+ (*i)->OnResetDisplay();
+ }
+}
+
+void CWinSystemX11GLESContext::SetVSyncImpl(bool enable)
+{
+ m_pGLContext->SetVSync(enable);
+}
+
+bool CWinSystemX11GLESContext::IsExtSupported(const char* extension) const
+{
+ if (strncmp(extension, m_pGLContext->ExtPrefix().c_str(), 4) != 0)
+ return CRenderSystemGLES::IsExtSupported(extension);
+
+ return m_pGLContext->IsExtSupported(extension);
+}
+
+EGLDisplay CWinSystemX11GLESContext::GetEGLDisplay() const
+{
+ return m_pGLContext->m_eglDisplay;
+}
+
+EGLSurface CWinSystemX11GLESContext::GetEGLSurface() const
+{
+ return m_pGLContext->m_eglSurface;
+}
+
+EGLContext CWinSystemX11GLESContext::GetEGLContext() const
+{
+ return m_pGLContext->m_eglContext;
+}
+
+EGLConfig CWinSystemX11GLESContext::GetEGLConfig() const
+{
+ return m_pGLContext->m_eglConfig;
+}
+
+bool CWinSystemX11GLESContext::SetWindow(int width, int height, bool fullscreen, const std::string& output, int* winstate)
+{
+ int newwin = 0;
+
+ CWinSystemX11::SetWindow(width, height, fullscreen, output, &newwin);
+ if (newwin)
+ {
+ RefreshGLContext(m_currentOutput.compare(output) != 0);
+ XSync(m_dpy, false);
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0);
+ CServiceBroker::GetWinSystem()->GetGfxContext().Flip(true, false);
+ ResetVSync();
+
+ m_windowDirty = false;
+ m_bIsInternalXrr = false;
+
+ if (!m_delayDispReset)
+ {
+ CSingleLock lock(m_resourceSection);
+ // tell any shared resources
+ for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
+ (*i)->OnResetDisplay();
+ }
+ }
+ return true;
+}
+
+bool CWinSystemX11GLESContext::CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res)
+{
+ CLog::Log(LOGNOTICE, "CWinSystemX11GLESContext::CreateNewWindow");
+ if (!CWinSystemX11::CreateNewWindow(name, fullScreen, res) || !m_pGLContext)
+ return false;
+
+ m_pGLContext->QueryExtensions();
+ return true;
+}
+
+bool CWinSystemX11GLESContext::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
+{
+ m_newGlContext = false;
+ CWinSystemX11::ResizeWindow(newWidth, newHeight, newLeft, newTop);
+ CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
+
+ if (m_newGlContext)
+ g_application.ReloadSkin();
+
+ return true;
+}
+
+void CWinSystemX11GLESContext::FinishWindowResize(int newWidth, int newHeight)
+{
+ m_newGlContext = false;
+ CWinSystemX11::FinishWindowResize(newWidth, newHeight);
+ CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
+
+ if (m_newGlContext)
+ g_application.ReloadSkin();
+}
+
+bool CWinSystemX11GLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
+{
+ m_newGlContext = false;
+ CWinSystemX11::SetFullScreen(fullScreen, res, blankOtherDisplays);
+ CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
+
+ if (m_newGlContext)
+ g_application.ReloadSkin();
+
+ return true;
+}
+
+bool CWinSystemX11GLESContext::DestroyWindowSystem()
+{
+ if (m_pGLContext)
+ m_pGLContext->Destroy();
+ return CWinSystemX11::DestroyWindowSystem();
+}
+
+bool CWinSystemX11GLESContext::DestroyWindow()
+{
+ if (m_pGLContext)
+ m_pGLContext->Detach();
+ return CWinSystemX11::DestroyWindow();
+}
+
+XVisualInfo* CWinSystemX11GLESContext::GetVisual()
+{
+ EGLDisplay eglDisplay;
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
+ reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+ if (eglGetPlatformDisplayEXT)
+ {
+ EGLint attribs[] =
+ {
+ EGL_PLATFORM_X11_SCREEN_EXT, m_screen,
+ EGL_NONE
+ };
+ eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,static_cast<EGLNativeDisplayType>(m_dpy), attribs);
+ }
+ else
+ eglDisplay = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_dpy));
+
+ if (eglDisplay == EGL_NO_DISPLAY)
+ {
+ CLog::Log(LOGERROR, "failed to get egl display\n");
+ return nullptr;
+ }
+ if (!eglInitialize(eglDisplay, nullptr, nullptr))
+ {
+ CLog::Log(LOGERROR, "failed to initialize egl display\n");
+ return nullptr;
+ }
+
+ GLint att[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_BUFFER_SIZE, 32,
+ EGL_DEPTH_SIZE, 24,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+ EGLint numConfigs;
+ EGLConfig eglConfig = 0;
+ if (!eglChooseConfig(eglDisplay, att, &eglConfig, 1, &numConfigs) || numConfigs == 0)
+ {
+ CLog::Log(LOGERROR, "Failed to choose a config %d\n", eglGetError());
+ return nullptr;
+ }
+
+ XVisualInfo x11_visual_info_template;
+ if (!eglGetConfigAttrib(eglDisplay, eglConfig,
+ EGL_NATIVE_VISUAL_ID, reinterpret_cast<EGLint*>(&x11_visual_info_template.visualid)))
+ {
+ CLog::Log(LOGERROR, "Failed to query native visual id\n");
+ return nullptr;
+ }
+ int num_visuals;
+ XVisualInfo* visual =
+ XGetVisualInfo(m_dpy, VisualIDMask, &x11_visual_info_template, &num_visuals);
+ return visual;
+}
+
+bool CWinSystemX11GLESContext::RefreshGLContext(bool force)
+{
+ bool success = false;
+ if (m_pGLContext)
+ {
+ success = m_pGLContext->Refresh(force, m_screen, m_glWindow, m_newGlContext);
+ if (!success)
+ {
+ success = m_pGLContext->CreatePB();
+ m_newGlContext = true;
+ }
+ return success;
+ }
+
+ m_dpms = std::make_shared<CX11DPMSSupport>();
+ VIDEOPLAYER::CProcessInfoX11::Register();
+ RETRO::CRPProcessInfoX11::Register();
+ RETRO::CRPProcessInfoX11::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
+ CDVDFactoryCodec::ClearHWAccels();
+ VIDEOPLAYER::CRendererFactory::ClearRenderer();
+ CLinuxRendererGLES::Register();
+
+ std::string gli = (getenv("KODI_GL_INTERFACE") != nullptr) ? getenv("KODI_GL_INTERFACE") : "";
+
+ m_pGLContext = new CGLContextEGL(m_dpy, EGL_OPENGL_ES_API);
+ success = m_pGLContext->Refresh(force, m_screen, m_glWindow, m_newGlContext);
+ if (!success && gli == "EGL_PB")
+ {
+ success = m_pGLContext->CreatePB();
+ m_newGlContext = true;
+ }
+
+ if (!success)
+ {
+ delete m_pGLContext;
+ m_pGLContext = nullptr;
+ }
+ return success;
+}
diff --git a/xbmc/windowing/X11/WinSystemX11GLESContext.h b/xbmc/windowing/X11/WinSystemX11GLESContext.h
new file mode 100644
index 0000000000..129e737df6
--- /dev/null
+++ b/xbmc/windowing/X11/WinSystemX11GLESContext.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "EGL/egl.h"
+#include "WinSystemX11.h"
+#include "rendering/gles/RenderSystemGLES.h"
+
+#include "platform/linux/OptionalsReg.h"
+
+#include <memory>
+
+class CGLContextEGL;
+
+class CWinSystemX11GLESContext : public CWinSystemX11, public CRenderSystemGLES
+{
+public:
+ CWinSystemX11GLESContext();
+ virtual ~CWinSystemX11GLESContext();
+
+ // Implementation of CWinSystem via CWinSystemX11
+ CRenderSystemBase* GetRenderSystem() override { return this; }
+ bool CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res) override;
+ bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override;
+ void FinishWindowResize(int newWidth, int newHeight) override;
+ bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override;
+ bool DestroyWindowSystem() override;
+ bool DestroyWindow() override;
+
+ bool IsExtSupported(const char* extension) const override;
+
+ EGLDisplay GetEGLDisplay() const;
+ EGLSurface GetEGLSurface() const;
+ EGLContext GetEGLContext() const;
+ EGLConfig GetEGLConfig() const;
+
+protected:
+ bool SetWindow(int width, int height, bool fullscreen, const std::string& output, int* winstate = nullptr) override;
+ void PresentRenderImpl(bool rendered) override;
+ void SetVSyncImpl(bool enable) override;
+ bool RefreshGLContext(bool force);
+ XVisualInfo* GetVisual() override;
+
+ CGLContextEGL* m_pGLContext = nullptr;
+ bool m_newGlContext;
+
+ std::unique_ptr<OPTIONALS::CLircContainer, OPTIONALS::delete_CLircContainer> m_lirc;
+};