diff options
author | Stefan Sichler <stsichler@web.de> | 2019-08-16 20:24:37 +0200 |
---|---|---|
committer | Stefan Sichler <stsichler@web.de> | 2019-11-04 23:19:01 +0100 |
commit | 1c91a4024388a78eef878674099eebaa3b7ed528 (patch) | |
tree | 6cbcbda64459d0446d1293e2d67b140b9934f297 | |
parent | 5aaa190407255c9222ea33cbfb7d3ff09e527497 (diff) |
[windowing] resurrection of X11/GLES support
-rw-r--r-- | cmake/platform/linux/x11.cmake | 16 | ||||
-rw-r--r-- | docs/README.Linux.md | 4 | ||||
-rw-r--r-- | tools/depends/target/Toolchain.cmake.in | 2 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt | 1 | ||||
-rw-r--r-- | xbmc/windowing/X11/CMakeLists.txt | 17 | ||||
-rw-r--r-- | xbmc/windowing/X11/GLContextEGL.cpp | 39 | ||||
-rw-r--r-- | xbmc/windowing/X11/GLContextEGL.h | 7 | ||||
-rw-r--r-- | xbmc/windowing/X11/WinSystemX11GLContext.cpp | 2 | ||||
-rw-r--r-- | xbmc/windowing/X11/WinSystemX11GLESContext.cpp | 312 | ||||
-rw-r--r-- | xbmc/windowing/X11/WinSystemX11GLESContext.h | 54 |
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; +}; |