diff options
Diffstat (limited to '')
-rw-r--r-- | xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp new file mode 100644 index 0000000..0d071c3 --- /dev/null +++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp @@ -0,0 +1,167 @@ +/* + * 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 "WinSystemGbmGLESContext.h" + +#include "OptionalsReg.h" +#include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h" +#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.h" +#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h" +#include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h" +#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +#include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h" +#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.h" +#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h" +#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" +#include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" +#include "rendering/gles/ScreenshotSurfaceGLES.h" +#include "utils/BufferObjectFactory.h" +#include "utils/DMAHeapBufferObject.h" +#include "utils/DumbBufferObject.h" +#include "utils/GBMBufferObject.h" +#include "utils/UDMABufferObject.h" +#include "utils/XTimeUtils.h" +#include "utils/log.h" +#include "windowing/WindowSystemFactory.h" + +#include <mutex> + +#include <gbm.h> + +using namespace KODI::WINDOWING::GBM; + +using namespace std::chrono_literals; + +CWinSystemGbmGLESContext::CWinSystemGbmGLESContext() +: CWinSystemGbmEGLContext(EGL_PLATFORM_GBM_MESA, "EGL_MESA_platform_gbm") +{} + +void CWinSystemGbmGLESContext::Register() +{ + CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem, "gbm"); +} + +std::unique_ptr<CWinSystemBase> CWinSystemGbmGLESContext::CreateWinSystem() +{ + return std::make_unique<CWinSystemGbmGLESContext>(); +} + +bool CWinSystemGbmGLESContext::InitWindowSystem() +{ + VIDEOPLAYER::CRendererFactory::ClearRenderer(); + CDVDFactoryCodec::ClearHWAccels(); + CLinuxRendererGLES::Register(); + RETRO::CRPProcessInfoGbm::Register(); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryDMA); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES); + + if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API)) + { + return false; + } + + bool general, deepColor; + m_vaapiProxy.reset(GBM::VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor())); + GBM::VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay()); + GBM::VAAPIRegisterRenderGLES(m_vaapiProxy.get(), general, deepColor); + + if (general) + { + GBM::VAAPIRegister(m_vaapiProxy.get(), deepColor); + } + + CRendererDRMPRIMEGLES::Register(); + CRendererDRMPRIME::Register(); + CDVDVideoCodecDRMPRIME::Register(); + VIDEOPLAYER::CProcessInfoGBM::Register(); + + CScreenshotSurfaceGLES::Register(); + + CBufferObjectFactory::ClearBufferObjects(); + CDumbBufferObject::Register(); +#if defined(HAS_GBM_BO_MAP) + CGBMBufferObject::Register(); +#endif +#if defined(HAVE_LINUX_MEMFD) && defined(HAVE_LINUX_UDMABUF) + CUDMABufferObject::Register(); +#endif +#if defined(HAVE_LINUX_DMA_HEAP) + CDMAHeapBufferObject::Register(); +#endif + + return true; +} + +bool CWinSystemGbmGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) +{ + if (res.iWidth != m_nWidth || + res.iHeight != m_nHeight) + { + CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::{} - resolution changed, creating a new window", + __FUNCTION__); + CreateNewWindow("", fullScreen, res); + } + + if (!m_eglContext.TrySwapBuffers()) + { + CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed"); + throw std::runtime_error("eglSwapBuffers failed"); + } + + CWinSystemGbm::SetFullScreen(fullScreen, res, blankOtherDisplays); + CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight); + + return true; +} + +void CWinSystemGbmGLESContext::PresentRender(bool rendered, bool videoLayer) +{ + if (!m_bRenderCreated) + return; + + if (rendered || videoLayer) + { + if (rendered) + { + if (!m_eglContext.TrySwapBuffers()) + { + CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed"); + throw std::runtime_error("eglSwapBuffers failed"); + } + } + CWinSystemGbm::FlipPage(rendered, videoLayer); + + if (m_dispReset && m_dispResetTimer.IsTimePast()) + { + CLog::Log(LOGDEBUG, "CWinSystemGbmGLESContext::{} - Sending display reset to all clients", + __FUNCTION__); + m_dispReset = false; + std::unique_lock<CCriticalSection> lock(m_resourceSection); + + for (auto resource : m_resources) + resource->OnResetDisplay(); + } + } + else + { + KODI::TIME::Sleep(10ms); + } +} + +bool CWinSystemGbmGLESContext::CreateContext() +{ + CEGLAttributesVec contextAttribs; + contextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}}); + + if (!m_eglContext.CreateContext(contextAttribs)) + { + CLog::Log(LOGERROR, "EGL context creation failed"); + return false; + } + return true; +} |