summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xbmc/windowing/android/WinSystemAndroidGLESContext.cpp270
1 files changed, 270 insertions, 0 deletions
diff --git a/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp b/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp
new file mode 100644
index 0000000..ac562ae
--- /dev/null
+++ b/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp
@@ -0,0 +1,270 @@
+/*
+ * 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 "WinSystemAndroidGLESContext.h"
+
+#include "ServiceBroker.h"
+#include "VideoSyncAndroid.h"
+#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "windowing/WindowSystemFactory.h"
+
+#include "platform/android/activity/XBMCApp.h"
+
+#include <EGL/eglext.h>
+#include <unistd.h>
+
+#include "PlatformDefs.h"
+
+void CWinSystemAndroidGLESContext::Register()
+{
+ KODI::WINDOWING::CWindowSystemFactory::RegisterWindowSystem(CreateWinSystem);
+}
+
+std::unique_ptr<CWinSystemBase> CWinSystemAndroidGLESContext::CreateWinSystem()
+{
+ return std::make_unique<CWinSystemAndroidGLESContext>();
+}
+
+bool CWinSystemAndroidGLESContext::InitWindowSystem()
+{
+ if (!CWinSystemAndroid::InitWindowSystem())
+ {
+ return false;
+ }
+
+ if (!m_pGLContext.CreateDisplay(m_nativeDisplay))
+ {
+ return false;
+ }
+
+ if (!m_pGLContext.InitializeDisplay(EGL_OPENGL_ES_API))
+ {
+ return false;
+ }
+
+ if (!m_pGLContext.ChooseConfig(EGL_OPENGL_ES2_BIT))
+ {
+ return false;
+ }
+
+ m_hasHDRConfig = m_pGLContext.ChooseConfig(EGL_OPENGL_ES2_BIT, 0, true);
+
+ m_hasEGL_BT2020_PQ_Colorspace_Extension =
+ CEGLUtils::HasExtension(m_pGLContext.GetEGLDisplay(), "EGL_EXT_gl_colorspace_bt2020_pq");
+ m_hasEGL_ST2086_Extension =
+ CEGLUtils::HasExtension(m_pGLContext.GetEGLDisplay(), "EGL_EXT_surface_SMPTE2086_metadata");
+
+ bool hasEGLHDRExtensions = m_hasEGL_BT2020_PQ_Colorspace_Extension && m_hasEGL_ST2086_Extension;
+
+ CLog::Log(LOGDEBUG,
+ "CWinSystemAndroidGLESContext::InitWindowSystem: HDRConfig: {}, HDRExtensions: {}",
+ static_cast<int>(m_hasHDRConfig), static_cast<int>(hasEGLHDRExtensions));
+
+ CEGLAttributesVec contextAttribs;
+ contextAttribs.Add({{EGL_CONTEXT_CLIENT_VERSION, 2}});
+
+ if (!m_pGLContext.CreateContext(contextAttribs))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool CWinSystemAndroidGLESContext::CreateNewWindow(const std::string& name,
+ bool fullScreen,
+ RESOLUTION_INFO& res)
+{
+ m_pGLContext.DestroySurface();
+
+ if (!CWinSystemAndroid::CreateNewWindow(name, fullScreen, res))
+ {
+ return false;
+ }
+
+ if (!CreateSurface())
+ {
+ return false;
+ }
+
+ if (!m_pGLContext.BindContext())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool CWinSystemAndroidGLESContext::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
+{
+ CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight);
+ return true;
+}
+
+bool CWinSystemAndroidGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
+{
+ CreateNewWindow("", fullScreen, res);
+ CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight);
+ return true;
+}
+
+void CWinSystemAndroidGLESContext::SetVSyncImpl(bool enable)
+{
+ // We use Choreographer for timing
+ m_pGLContext.SetVSync(false);
+}
+
+void CWinSystemAndroidGLESContext::PresentRenderImpl(bool rendered)
+{
+ if (!m_nativeWindow)
+ {
+ usleep(10000);
+ return;
+ }
+
+ // Mode change finalization was triggered by timer
+ if (IsHdmiModeTriggered())
+ SetHdmiState(true);
+
+ // Ignore EGL_BAD_SURFACE: It seems to happen during/after mode changes, but
+ // we can't actually do anything about it
+ if (rendered && !m_pGLContext.TrySwapBuffers())
+ CEGLUtils::Log(LOGERROR, "eglSwapBuffers failed");
+
+ CXBMCApp::Get().WaitVSync(1000);
+}
+
+float CWinSystemAndroidGLESContext::GetFrameLatencyAdjustment()
+{
+ return CXBMCApp::Get().GetFrameLatencyMs();
+}
+
+EGLDisplay CWinSystemAndroidGLESContext::GetEGLDisplay() const
+{
+ return m_pGLContext.GetEGLDisplay();
+}
+
+EGLSurface CWinSystemAndroidGLESContext::GetEGLSurface() const
+{
+ return m_pGLContext.GetEGLSurface();
+}
+
+EGLContext CWinSystemAndroidGLESContext::GetEGLContext() const
+{
+ return m_pGLContext.GetEGLContext();
+}
+
+EGLConfig CWinSystemAndroidGLESContext::GetEGLConfig() const
+{
+ return m_pGLContext.GetEGLConfig();
+}
+
+std::unique_ptr<CVideoSync> CWinSystemAndroidGLESContext::GetVideoSync(void *clock)
+{
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncAndroid(clock));
+ return pVSync;
+}
+
+bool CWinSystemAndroidGLESContext::CreateSurface()
+{
+ if (!m_pGLContext.CreateSurface(static_cast<EGLNativeWindowType>(m_nativeWindow->m_window),
+ m_HDRColorSpace))
+ {
+ if (m_HDRColorSpace != EGL_NONE)
+ {
+ m_HDRColorSpace = EGL_NONE;
+ m_displayMetadata = nullptr;
+ m_lightMetadata = nullptr;
+ if (!m_pGLContext.CreateSurface(static_cast<EGLNativeWindowType>(m_nativeWindow->m_window)))
+ return false;
+ }
+ else
+ return false;
+ }
+
+#if EGL_EXT_surface_SMPTE2086_metadata
+ if (m_displayMetadata)
+ {
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[0][0]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[0][1]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[1][0]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[1][1]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[2][0]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, static_cast<int>(av_q2d(m_displayMetadata->display_primaries[2][1]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_WHITE_POINT_X_EXT, static_cast<int>(av_q2d(m_displayMetadata->white_point[0]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_WHITE_POINT_Y_EXT, static_cast<int>(av_q2d(m_displayMetadata->white_point[1]) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_MAX_LUMINANCE_EXT, static_cast<int>(av_q2d(m_displayMetadata->max_luminance) * EGL_METADATA_SCALING_EXT + 0.5));
+ m_pGLContext.SurfaceAttrib(EGL_SMPTE2086_MIN_LUMINANCE_EXT, static_cast<int>(av_q2d(m_displayMetadata->min_luminance) * EGL_METADATA_SCALING_EXT + 0.5));
+ }
+ if (m_lightMetadata)
+ {
+ m_pGLContext.SurfaceAttrib(EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, static_cast<int>(m_lightMetadata->MaxCLL * EGL_METADATA_SCALING_EXT));
+ m_pGLContext.SurfaceAttrib(EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, static_cast<int>(m_lightMetadata->MaxFALL * EGL_METADATA_SCALING_EXT));
+ }
+#endif
+ return true;
+}
+
+bool CWinSystemAndroidGLESContext::IsHDRDisplay()
+{
+ return m_hasHDRConfig && (m_hasEGL_BT2020_PQ_Colorspace_Extension || m_hasEGL_ST2086_Extension) &&
+ CWinSystemAndroid::IsHDRDisplay();
+}
+
+bool CWinSystemAndroidGLESContext::SetHDR(const VideoPicture* videoPicture)
+{
+ if (!CWinSystemAndroid::IsHDRDisplay() || !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_WINSYSTEM_IS_HDR_DISPLAY))
+ return false;
+
+ EGLint HDRColorSpace = 0;
+
+#if EGL_EXT_gl_colorspace_bt2020_linear
+ if (m_hasHDRConfig && m_hasEGL_BT2020_PQ_Colorspace_Extension && m_hasEGL_ST2086_Extension)
+ {
+ HDRColorSpace = EGL_NONE;
+ if (videoPicture && videoPicture->hasDisplayMetadata)
+ {
+ switch (videoPicture->color_space)
+ {
+ case AVCOL_SPC_BT2020_NCL:
+ case AVCOL_SPC_BT2020_CL:
+ case AVCOL_SPC_BT709:
+ HDRColorSpace = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
+ break;
+ default:
+ m_displayMetadata = nullptr;
+ m_lightMetadata = nullptr;
+ }
+ }
+ else
+ {
+ m_displayMetadata = nullptr;
+ m_lightMetadata = nullptr;
+ }
+
+ if (HDRColorSpace != m_HDRColorSpace)
+ {
+ CLog::Log(LOGDEBUG, "CWinSystemAndroidGLESContext::SetHDR: ColorSpace: {}", HDRColorSpace);
+
+ m_HDRColorSpace = HDRColorSpace;
+ m_displayMetadata = m_HDRColorSpace == EGL_NONE ? nullptr : std::unique_ptr<AVMasteringDisplayMetadata>(new AVMasteringDisplayMetadata(videoPicture->displayMetadata));
+ // TODO: discuss with NVIDIA why this prevent turning HDR display off
+ //m_lightMetadata = !videoPicture || m_HDRColorSpace == EGL_NONE ? nullptr : std::unique_ptr<AVContentLightMetadata>(new AVContentLightMetadata(videoPicture->lightMetadata));
+ m_pGLContext.DestroySurface();
+ CreateSurface();
+ m_pGLContext.BindContext();
+ }
+ }
+#endif
+
+ return m_HDRColorSpace == HDRColorSpace;
+}