/* * 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 #include 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 CWinSystemGbmGLESContext::CreateWinSystem() { return std::make_unique(); } 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 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; }