diff --git a/xbmc/windowing/amlogic/CMakeLists.txt b/xbmc/windowing/amlogic/CMakeLists.txt new file mode 100644 index 0000000000000..2ad0319615213 --- /dev/null +++ b/xbmc/windowing/amlogic/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SOURCES GLContextEGL.cpp + WinSystemAmlogic.cpp + VideoSyncAML.cpp) + +set(HEADERS GLContextEGL.h + WinSystemAmlogic.h + VideoSyncAML.h) + +if(OPENGLES_FOUND) + list(APPEND SOURCES WinSystemAmlogicGLESContext.cpp) + list(APPEND HEADERS WinSystemAmlogicGLESContext.h) +endif() + +core_add_library(windowing_Amlogic) diff --git a/xbmc/windowing/amlogic/GLContextEGL.cpp b/xbmc/windowing/amlogic/GLContextEGL.cpp new file mode 100644 index 0000000000000..74e145aa61add --- /dev/null +++ b/xbmc/windowing/amlogic/GLContextEGL.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "GLContextEGL.h" + +#include "guilib/IDirtyRegionSolver.h" +#include "settings/AdvancedSettings.h" +#include "utils/log.h" + +CGLContextEGL::CGLContextEGL() : + m_eglDisplay(EGL_NO_DISPLAY), + m_eglSurface(EGL_NO_SURFACE), + m_eglContext(EGL_NO_CONTEXT), + m_eglConfig(0) +{ +} + +CGLContextEGL::~CGLContextEGL() +{ + Destroy(); +} + +bool CGLContextEGL::CreateDisplay(EGLDisplay display, + EGLint renderable_type, + EGLint rendering_api) +{ + EGLint neglconfigs = 0; + int major, minor; + + EGLint surface_type = EGL_WINDOW_BIT; + // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates + if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION || + g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION) + surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + + EGLint attribs[] = + { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 16, + EGL_STENCIL_SIZE, 0, + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, 0, + EGL_SURFACE_TYPE, surface_type, + EGL_RENDERABLE_TYPE, renderable_type, + EGL_NONE + }; + + if (m_eglDisplay == EGL_NO_DISPLAY) + { + m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)display); + } + + if (m_eglDisplay == EGL_NO_DISPLAY) + { + CLog::Log(LOGERROR, "failed to get EGL display"); + return false; + } + + if (!eglInitialize(m_eglDisplay, &major, &minor)) + { + CLog::Log(LOGERROR, "failed to initialize EGL display"); + return false; + } + + eglBindAPI(rendering_api); + + if (!eglChooseConfig(m_eglDisplay, attribs, + &m_eglConfig, 1, &neglconfigs)) + { + CLog::Log(LOGERROR, "Failed to query number of EGL configs"); + return false; + } + + if (neglconfigs <= 0) + { + CLog::Log(LOGERROR, "No suitable EGL configs found"); + return false; + } + + return true; +} + +bool CGLContextEGL::CreateContext() +{ + int client_version = 2; + + const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, client_version, EGL_NONE + }; + + if (m_eglContext == EGL_NO_CONTEXT) + { + m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, + EGL_NO_CONTEXT, context_attribs); + } + + if (m_eglContext == EGL_NO_CONTEXT) + { + CLog::Log(LOGERROR, "failed to create EGL context"); + return false; + } + + return true; +} + +bool CGLContextEGL::BindContext() +{ + if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, + m_eglSurface, m_eglContext)) + { + CLog::Log(LOGERROR, "Failed to make context current %p %p %p", + m_eglDisplay, m_eglSurface, m_eglContext); + return false; + } + + return true; +} + +bool CGLContextEGL::SurfaceAttrib() +{ + // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates + if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION || + g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION) + { + if ((m_eglDisplay == EGL_NO_DISPLAY) || (m_eglSurface == EGL_NO_SURFACE)) + { + return false; + } + + if (!eglSurfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) + { + CLog::Log(LOGDEBUG, "%s: Could not set EGL_SWAP_BEHAVIOR",__FUNCTION__); + } + } + + return true; +} + +bool CGLContextEGL::CreateSurface(EGLNativeWindowType surface) +{ + m_eglSurface = eglCreateWindowSurface(m_eglDisplay, + m_eglConfig, + surface, + nullptr); + + if (m_eglSurface == EGL_NO_SURFACE) + { + CLog::Log(LOGERROR, "failed to create EGL window surface %d", eglGetError()); + return false; + } + + return true; +} + +void CGLContextEGL::Destroy() +{ + if (m_eglContext != EGL_NO_CONTEXT) + { + eglDestroyContext(m_eglDisplay, m_eglContext); + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + m_eglContext = EGL_NO_CONTEXT; + } + + if (m_eglSurface != EGL_NO_SURFACE) + { + eglDestroySurface(m_eglDisplay, m_eglSurface); + m_eglSurface = EGL_NO_SURFACE; + } + + if (m_eglDisplay != EGL_NO_DISPLAY) + { + eglTerminate(m_eglDisplay); + m_eglDisplay = EGL_NO_DISPLAY; + } +} + +void CGLContextEGL::Detach() +{ + if (m_eglContext != EGL_NO_CONTEXT) + { + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + + if (m_eglSurface != EGL_NO_SURFACE) + { + eglDestroySurface(m_eglDisplay, m_eglSurface); + m_eglSurface = EGL_NO_SURFACE; + } +} + +bool CGLContextEGL::SetVSync(bool enable) +{ + if (!eglSwapInterval(m_eglDisplay, enable)) + { + return false; + } + + return true; +} + +void CGLContextEGL::SwapBuffers() +{ + if (m_eglDisplay == EGL_NO_DISPLAY || m_eglSurface == EGL_NO_SURFACE) + { + return; + } + + eglSwapBuffers(m_eglDisplay, m_eglSurface); +} diff --git a/xbmc/windowing/amlogic/GLContextEGL.h b/xbmc/windowing/amlogic/GLContextEGL.h new file mode 100644 index 0000000000000..afea42950e873 --- /dev/null +++ b/xbmc/windowing/amlogic/GLContextEGL.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#pragma once + +#include "EGL/egl.h" + +class CGLContextEGL +{ +public: + CGLContextEGL(); + virtual ~CGLContextEGL(); + + bool CreateDisplay(EGLDisplay display, + EGLint renderable_type, + EGLint rendering_api); + + bool CreateSurface(EGLNativeWindowType surface); + bool CreateContext(); + bool BindContext(); + bool SurfaceAttrib(); + void Destroy(); + void Detach(); + bool SetVSync(bool enable); + void SwapBuffers(); + + EGLDisplay m_eglDisplay; + EGLSurface m_eglSurface; + EGLContext m_eglContext; + EGLConfig m_eglConfig; +}; diff --git a/xbmc/windowing/egl/VideoSyncAML.cpp b/xbmc/windowing/amlogic/VideoSyncAML.cpp similarity index 98% rename from xbmc/windowing/egl/VideoSyncAML.cpp rename to xbmc/windowing/amlogic/VideoSyncAML.cpp index ebf3fb95467c4..50427cf287640 100644 --- a/xbmc/windowing/egl/VideoSyncAML.cpp +++ b/xbmc/windowing/amlogic/VideoSyncAML.cpp @@ -20,8 +20,6 @@ #include "system.h" -#if defined(HAS_LIBAMCODEC) - #include "VideoSyncAML.h" #include "guilib/GraphicContext.h" #include "windowing/WindowingFactory.h" @@ -106,5 +104,3 @@ void CVideoSyncAML::OnResetDisplay() { m_abort = true; } - -#endif diff --git a/xbmc/windowing/egl/VideoSyncAML.h b/xbmc/windowing/amlogic/VideoSyncAML.h similarity index 96% rename from xbmc/windowing/egl/VideoSyncAML.h rename to xbmc/windowing/amlogic/VideoSyncAML.h index 8186459f9ffc8..2ba9a8bf787be 100644 --- a/xbmc/windowing/egl/VideoSyncAML.h +++ b/xbmc/windowing/amlogic/VideoSyncAML.h @@ -19,8 +19,6 @@ * */ -#if defined(HAS_LIBAMCODEC) - #include "windowing/VideoSync.h" #include "guilib/DispResource.h" @@ -37,5 +35,3 @@ class CVideoSyncAML : public CVideoSync, IDispResource private: volatile bool m_abort; }; - -#endif diff --git a/xbmc/windowing/amlogic/WinSystemAmlogic.cpp b/xbmc/windowing/amlogic/WinSystemAmlogic.cpp new file mode 100644 index 0000000000000..f10a32e04ea8c --- /dev/null +++ b/xbmc/windowing/amlogic/WinSystemAmlogic.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "WinSystemAmlogic.h" + +#include +#include + +#include "ServiceBroker.h" +#include "guilib/GraphicContext.h" +#include "guilib/Resolution.h" +#include "settings/Settings.h" +#include "settings/DisplaySettings.h" +#include "guilib/DispResource.h" +#include "utils/AMLUtils.h" +#include "utils/log.h" +#include "utils/SysfsUtils.h" +#include "threads/SingleLock.h" + +#include + +#include + +CWinSystemAmlogic::CWinSystemAmlogic() +{ + m_eWindowSystem = WINDOW_SYSTEM_AML; + + const char *env_framebuffer = getenv("FRAMEBUFFER"); + + // default to framebuffer 0 + m_framebuffer_name = "fb0"; + if (env_framebuffer) + { + std::string framebuffer(env_framebuffer); + std::string::size_type start = framebuffer.find("fb"); + m_framebuffer_name = framebuffer.substr(start); + } + + m_nativeDisplay = EGL_NO_DISPLAY; + m_nativeWindow = nullptr; + + m_displayWidth = 0; + m_displayHeight = 0; + + m_stereo_mode = RENDER_STEREO_MODE_OFF; + m_delayDispReset = false; + + aml_permissions(); + aml_disable_freeScale(); +} + +CWinSystemAmlogic::~CWinSystemAmlogic() +{ + if(m_nativeWindow) + { + m_nativeWindow = nullptr; + } +} + +bool CWinSystemAmlogic::InitWindowSystem() +{ + m_nativeDisplay = EGL_DEFAULT_DISPLAY; + + return CWinSystemBase::InitWindowSystem(); +} + +bool CWinSystemAmlogic::DestroyWindowSystem() +{ + return true; +} + +bool CWinSystemAmlogic::CreateNewWindow(const std::string& name, + bool fullScreen, + RESOLUTION_INFO& res, + PHANDLE_EVENT_FUNC userFunction) +{ + RESOLUTION_INFO current_resolution; + current_resolution.iWidth = current_resolution.iHeight = 0; + RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode(); + + m_nWidth = res.iWidth; + m_nHeight = res.iHeight; + m_displayWidth = res.iScreenWidth; + m_displayHeight = res.iScreenHeight; + m_fRefreshRate = res.fRefreshRate; + + if ((m_bWindowCreated && aml_get_native_resolution(¤t_resolution)) && + current_resolution.iWidth == res.iWidth && current_resolution.iHeight == res.iHeight && + current_resolution.iScreenWidth == res.iScreenWidth && current_resolution.iScreenHeight == res.iScreenHeight && + m_bFullScreen == fullScreen && current_resolution.fRefreshRate == res.fRefreshRate && + (current_resolution.dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK) && + m_stereo_mode == stereo_mode) + { + CLog::Log(LOGDEBUG, "CWinSystemEGL::CreateNewWindow: No need to create a new window"); + return true; + } + + int delay = CServiceBroker::GetSettings().GetInt("videoscreen.delayrefreshchange"); + if (delay > 0) + { + m_delayDispReset = true; + m_dispResetTimer.Set(delay * 100); + } + + { + CSingleLock lock(m_resourceSection); + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + { + (*i)->OnLostDisplay(); + } + } + + m_stereo_mode = stereo_mode; + m_bFullScreen = fullScreen; + + fbdev_window *nativeWindow = new fbdev_window; + nativeWindow->width = res.iScreenWidth; + nativeWindow->height = res.iScreenHeight; + m_nativeWindow = static_cast(nativeWindow); + + aml_set_native_resolution(res, m_framebuffer_name); + + if (!m_delayDispReset) + { + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + { + (*i)->OnResetDisplay(); + } + } + + return true; +} + +bool CWinSystemAmlogic::DestroyWindow() +{ + m_nativeWindow = nullptr; + + return true; +} + +void CWinSystemAmlogic::UpdateResolutions() +{ + CWinSystemBase::UpdateResolutions(); + + RESOLUTION_INFO resDesktop, curDisplay; + std::vector resolutions; + + if (!aml_probe_resolutions(resolutions) || resolutions.empty()) + { + CLog::Log(LOGWARNING, "%s: ProbeResolutions failed.",__FUNCTION__); + } + + /* ProbeResolutions includes already all resolutions. + * Only get desktop resolution so we can replace xbmc's desktop res + */ + if (aml_get_native_resolution(&curDisplay)) + { + resDesktop = curDisplay; + } + + RESOLUTION ResDesktop = RES_INVALID; + RESOLUTION res_index = RES_DESKTOP; + + for (size_t i = 0; i < resolutions.size(); i++) + { + // if this is a new setting, + // create a new empty setting to fill in. + if ((int)CDisplaySettings::GetInstance().ResolutionInfoSize() <= res_index) + { + RESOLUTION_INFO res; + CDisplaySettings::GetInstance().AddResolutionInfo(res); + } + + g_graphicsContext.ResetOverscan(resolutions[i]); + CDisplaySettings::GetInstance().GetResolutionInfo(res_index) = resolutions[i]; + + CLog::Log(LOGNOTICE, "Found resolution %d x %d for display %d with %d x %d%s @ %f Hz\n", + resolutions[i].iWidth, + resolutions[i].iHeight, + resolutions[i].iScreen, + resolutions[i].iScreenWidth, + resolutions[i].iScreenHeight, + resolutions[i].dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", + resolutions[i].fRefreshRate); + + if(resDesktop.iWidth == resolutions[i].iWidth && + resDesktop.iHeight == resolutions[i].iHeight && + resDesktop.iScreenWidth == resolutions[i].iScreenWidth && + resDesktop.iScreenHeight == resolutions[i].iScreenHeight && + (resDesktop.dwFlags & D3DPRESENTFLAG_MODEMASK) == (resolutions[i].dwFlags & D3DPRESENTFLAG_MODEMASK) && + fabs(resDesktop.fRefreshRate - resolutions[i].fRefreshRate) < FLT_EPSILON) + { + ResDesktop = res_index; + } + + res_index = (RESOLUTION)((int)res_index + 1); + } + + // swap desktop index for desktop res if available + if (ResDesktop != RES_INVALID) + { + CLog::Log(LOGNOTICE, "Found (%dx%d%s@%f) at %d, setting to RES_DESKTOP at %d", + resDesktop.iWidth, resDesktop.iHeight, + resDesktop.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", + resDesktop.fRefreshRate, + (int)ResDesktop, (int)RES_DESKTOP); + + RESOLUTION_INFO desktop = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP); + CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP) = CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop); + CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop) = desktop; + } +} + +bool CWinSystemAmlogic::Hide() +{ + return false; +} + +bool CWinSystemAmlogic::Show(bool show) +{ + std::string blank_framebuffer = "/sys/class/graphics/" + m_framebuffer_name + "/blank"; + SysfsUtils::SetInt(blank_framebuffer.c_str(), show ? 0 : 1); + return true; +} + +void CWinSystemAmlogic::Register(IDispResource *resource) +{ + CSingleLock lock(m_resourceSection); + m_resources.push_back(resource); +} + +void CWinSystemAmlogic::Unregister(IDispResource *resource) +{ + CSingleLock lock(m_resourceSection); + std::vector::iterator i = find(m_resources.begin(), m_resources.end(), resource); + if (i != m_resources.end()) + m_resources.erase(i); +} diff --git a/xbmc/windowing/amlogic/WinSystemAmlogic.h b/xbmc/windowing/amlogic/WinSystemAmlogic.h new file mode 100644 index 0000000000000..7d6b043cb0328 --- /dev/null +++ b/xbmc/windowing/amlogic/WinSystemAmlogic.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#pragma once + +#include "rendering/gles/RenderSystemGLES.h" +#include "threads/CriticalSection.h" +#include "windowing/WinSystem.h" +#include "threads/SystemClock.h" +#include "EGL/egl.h" + +class IDispResource; + +class CWinSystemAmlogic : public CWinSystemBase +{ +public: + CWinSystemAmlogic(); + virtual ~CWinSystemAmlogic(); + + bool InitWindowSystem() override; + bool DestroyWindowSystem() override; + + bool CreateNewWindow(const std::string& name, + bool fullScreen, + RESOLUTION_INFO& res, + PHANDLE_EVENT_FUNC userFunction) override; + + bool DestroyWindow() override; + void UpdateResolutions() override; + + bool Hide() override; + bool Show(bool show = true) override; + virtual void Register(IDispResource *resource); + virtual void Unregister(IDispResource *resource); +protected: + std::string m_framebuffer_name; + EGLDisplay m_nativeDisplay; + fbdev_window *m_nativeWindow; + + int m_displayWidth; + int m_displayHeight; + + RENDER_STEREO_MODE m_stereo_mode; + + bool m_delayDispReset; + XbmcThreads::EndTime m_dispResetTimer; + + CCriticalSection m_resourceSection; + std::vector m_resources; +}; diff --git a/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.cpp b/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.cpp new file mode 100644 index 0000000000000..524e6832047a2 --- /dev/null +++ b/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "VideoSyncAML.h" +#include "WinSystemAmlogicGLESContext.h" +#include "utils/log.h" +#include "threads/SingleLock.h" + +bool CWinSystemAmlogicGLESContext::InitWindowSystem() +{ + if (!CWinSystemAmlogic::InitWindowSystem()) + { + return false; + } + + if (!m_pGLContext.CreateDisplay(m_nativeDisplay, + EGL_OPENGL_ES2_BIT, + EGL_OPENGL_ES_API)) + { + return false; + } + + return true; +} + +bool CWinSystemAmlogicGLESContext::CreateNewWindow(const std::string& name, + bool fullScreen, + RESOLUTION_INFO& res, + PHANDLE_EVENT_FUNC userFunction) +{ + if (!CWinSystemAmlogic::CreateNewWindow(name, fullScreen, res, userFunction)) + { + return false; + } + + if (!m_pGLContext.CreateSurface(m_nativeWindow)) + { + return false; + } + + if (!m_pGLContext.CreateContext()) + { + return false; + } + + if (!m_pGLContext.BindContext()) + { + return false; + } + + if (!m_pGLContext.SurfaceAttrib()) + { + return false; + } + + if (!m_delayDispReset) + { + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + (*i)->OnResetDisplay(); + } + + return true; +} + +bool CWinSystemAmlogicGLESContext::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) +{ + CRenderSystemGLES::ResetRenderSystem(newWidth, newHeight, true, 0); + return true; +} + +bool CWinSystemAmlogicGLESContext::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) +{ + CreateNewWindow("", fullScreen, res, NULL); + CRenderSystemGLES::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate); + return true; +} + +void CWinSystemAmlogicGLESContext::SetVSyncImpl(bool enable) +{ + m_iVSyncMode = enable ? 10:0; + if (!m_pGLContext.SetVSync(enable)) + { + m_iVSyncMode = 0; + CLog::Log(LOGERROR, "%s,Could not set egl vsync", __FUNCTION__); + } +} + +void CWinSystemAmlogicGLESContext::PresentRenderImpl(bool rendered) +{ + if (m_delayDispReset && m_dispResetTimer.IsTimePast()) + { + m_delayDispReset = false; + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + (*i)->OnResetDisplay(); + } + if (!rendered) + return; + + m_pGLContext.SwapBuffers(); +} + +EGLDisplay CWinSystemAmlogicGLESContext::GetEGLDisplay() const +{ + return m_pGLContext.m_eglDisplay; +} + +EGLSurface CWinSystemAmlogicGLESContext::GetEGLSurface() const +{ + return m_pGLContext.m_eglSurface; +} + +EGLContext CWinSystemAmlogicGLESContext::GetEGLContext() const +{ + return m_pGLContext.m_eglContext; +} + +EGLConfig CWinSystemAmlogicGLESContext::GetEGLConfig() const +{ + return m_pGLContext.m_eglConfig; +} + +std::unique_ptr CWinSystemAmlogicGLESContext::GetVideoSync(void *clock) +{ + std::unique_ptr pVSync(new CVideoSyncAML(clock)); + return pVSync; +} + diff --git a/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.h b/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.h new file mode 100644 index 0000000000000..d2b40f9768dce --- /dev/null +++ b/xbmc/windowing/amlogic/WinSystemAmlogicGLESContext.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#pragma once + +#include "GLContextEGL.h" +#include "rendering/gles/RenderSystemGLES.h" +#include "utils/GlobalsHandling.h" +#include "WinSystemAmlogic.h" + +class CWinSystemAmlogicGLESContext : public CWinSystemAmlogic, public CRenderSystemGLES +{ +public: + CWinSystemAmlogicGLESContext() = default; + virtual ~CWinSystemAmlogicGLESContext() = default; + + bool InitWindowSystem() override; + bool CreateNewWindow(const std::string& name, + bool fullScreen, + RESOLUTION_INFO& res, + PHANDLE_EVENT_FUNC userFunction) override; + + bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override; + bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override; + + virtual std::unique_ptr GetVideoSync(void *clock) override; + + EGLDisplay GetEGLDisplay() const; + EGLSurface GetEGLSurface() const; + EGLContext GetEGLContext() const; + EGLConfig GetEGLConfig() const; +protected: + void SetVSyncImpl(bool enable) override; + void PresentRenderImpl(bool rendered) override; + +private: + CGLContextEGL m_pGLContext; + +}; + +XBMC_GLOBAL_REF(CWinSystemAmlogicGLESContext, g_Windowing); +#define g_Windowing XBMC_GLOBAL_USE(CWinSystemAmlogicGLESContext)