diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index d6bfb64a353d7..87900b0074db1 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2333,7 +2333,7 @@ void CApplication::Render() flip = true; //fps limiter, make sure each frame lasts at least singleFrameTime milliseconds - if (limitFrames || !flip) + if ((limitFrames || !flip) && !m_benchmarkTimer) { if (!limitFrames) singleFrameTime = 40; //if not flipping, loop at 25 fps @@ -5036,7 +5036,11 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr) void CApplication::Process() { MEASURE_FUNCTION; - + if (m_benchmarkTimer && XbmcThreads::SystemClockMillis() >= m_benchmarkTimer) + { + Stop(0); + return; + } // dispatch the messages generated by python or other threads to the current window g_windowManager.DispatchThreadMessages(); diff --git a/xbmc/Application.h b/xbmc/Application.h index 650fc876908ad..c9d6c166534be 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -348,6 +348,11 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs return m_bTestMode; } + void SetBenchmarkTimer(unsigned int timer) + { + m_benchmarkTimer = timer; + } + bool IsPresentFrame(); void Minimize(); diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index ed73cb7d25493..82a78f6db5512 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -2045,6 +2045,8 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI bool bReturn = false; int condition = abs(condition1); + if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END) + return GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item); if (item && condition >= LISTITEM_START && condition < LISTITEM_END) bReturn = GetItemBool(item, condition); // Ethernet Link state checking @@ -2145,10 +2147,6 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI bReturn = m_playerShowInfo; else if (condition == PLAYER_SHOWCODEC) bReturn = m_playerShowCodec; - else if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END) - { - return GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item); - } else if (condition == SYSTEM_HASLOCKS) bReturn = g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE; else if (condition == SYSTEM_HAS_PVR) diff --git a/xbmc/XBApplicationEx.cpp b/xbmc/XBApplicationEx.cpp index 93c4b67ce887a..07e4120663f6c 100644 --- a/xbmc/XBApplicationEx.cpp +++ b/xbmc/XBApplicationEx.cpp @@ -42,6 +42,7 @@ CXBApplicationEx::CXBApplicationEx() m_AppFocused = true; m_ExitCode = EXITCODE_QUIT; m_renderGUI = false; + m_benchmarkTimer = 0; } CXBApplicationEx::~CXBApplicationEx() @@ -91,6 +92,10 @@ INT CXBApplicationEx::Run() const BYTE MAX_EXCEPTION_COUNT = 10; #endif + m_firstFrameTime = XbmcThreads::SystemClockMillis(); + if (m_benchmarkTimer) + m_benchmarkTimer += m_firstFrameTime; + // Run xbmc while (!m_bStop) { @@ -209,9 +214,17 @@ INT CXBApplicationEx::Run() } } #endif + m_totalFrames++; } // while (!m_bStop) + unsigned int uptime = lastFrameTime - m_firstFrameTime; Destroy(); CLog::Log(LOGNOTICE, "application stopped..." ); + + if (m_benchmarkTimer) + { + printf("Processed %llu Frames in %i msec.\n",m_totalFrames, uptime); + } + return m_ExitCode; } diff --git a/xbmc/XBApplicationEx.h b/xbmc/XBApplicationEx.h index ff0be990cc784..44b980d26b68b 100644 --- a/xbmc/XBApplicationEx.h +++ b/xbmc/XBApplicationEx.h @@ -55,6 +55,9 @@ class CXBApplicationEx : public IWindowManagerCallback INT Run(); VOID Destroy(); + unsigned long long m_totalFrames; + unsigned int m_benchmarkTimer; + unsigned int m_firstFrameTime; private: }; diff --git a/xbmc/guilib/GUIControl.cpp b/xbmc/guilib/GUIControl.cpp index 1cd6164aae803..e50d00627b25c 100644 --- a/xbmc/guilib/GUIControl.cpp +++ b/xbmc/guilib/GUIControl.cpp @@ -58,7 +58,8 @@ CGUIControl::CGUIControl() } CGUIControl::CGUIControl(int parentID, int controlID, float posX, float posY, float width, float height) -: m_hitRect(posX, posY, posX + width, posY + height) +: m_hitRect(posX, posY, posX + width, posY + height), + m_cachedRenderRegion(0,0,0,0) { m_posX = posX; m_posY = posY; @@ -161,9 +162,13 @@ void CGUIControl::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyreg void CGUIControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { // update our render region - m_renderRegion = g_graphicsContext.generateAABB(CalcRenderRegion()); + CRect region(CalcRenderRegion()); + if (region != m_cachedRenderRegion) + { + m_cachedRenderRegion = region; + m_renderRegion = g_graphicsContext.generateAABB(m_cachedRenderRegion); + } } - // the main render routine. // 1. set the animation transform // 2. if visible, paint diff --git a/xbmc/guilib/GUIControl.h b/xbmc/guilib/GUIControl.h index b5449b1d3f3ca..3a34309aa878f 100644 --- a/xbmc/guilib/GUIControl.h +++ b/xbmc/guilib/GUIControl.h @@ -357,6 +357,7 @@ class CGUIControl bool m_controlIsDirty; CRect m_renderRegion; // In screen coordinates + CRect m_cachedRenderRegion; }; #endif diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp index 94f248ba7fe12..f3594fba80ab4 100644 --- a/xbmc/guilib/GraphicContext.cpp +++ b/xbmc/guilib/GraphicContext.cpp @@ -52,7 +52,8 @@ CGraphicContext::CGraphicContext(void) : m_Resolution(RES_INVALID), /*m_windowResolution,*/ m_guiScaleX(1.0f), - m_guiScaleY(1.0f) + m_guiScaleY(1.0f), + m_groupTransformSize(0) /*,m_cameras, */ /*m_origins, */ /*m_clipRegions,*/ diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h index 5743598403d88..d1ba2c21110d3 100644 --- a/xbmc/guilib/GraphicContext.h +++ b/xbmc/guilib/GraphicContext.h @@ -171,16 +171,17 @@ class CGraphicContext : public CCriticalSection void ClipRect(CRect &vertex, CRect &texture, CRect *diffuse = NULL); inline unsigned int AddGUITransform() { - unsigned int size = m_groupTransform.size(); m_groupTransform.push(m_guiTransform); - UpdateFinalTransform(m_groupTransform.top()); - return size; + m_groupTransformSize++; + UpdateFinalTransform(m_guiTransform); + return m_groupTransformSize - 1; } inline TransformMatrix AddTransform(const TransformMatrix &matrix) { - ASSERT(m_groupTransform.size()); - TransformMatrix absoluteMatrix = m_groupTransform.size() ? m_groupTransform.top() * matrix : matrix; + ASSERT(m_groupTransformSize); + TransformMatrix absoluteMatrix = m_groupTransformSize ? m_groupTransform.top() * matrix : matrix; m_groupTransform.push(absoluteMatrix); + m_groupTransformSize++; UpdateFinalTransform(absoluteMatrix); return absoluteMatrix; } @@ -188,20 +189,24 @@ class CGraphicContext : public CCriticalSection { // TODO: We only need to add it to the group transform as other transforms may be added on top of this one later on // Once all transforms are cached then this can be removed and UpdateFinalTransform can be called directly - ASSERT(m_groupTransform.size()); + ASSERT(m_groupTransformSize); m_groupTransform.push(matrix); + m_groupTransformSize++; UpdateFinalTransform(m_groupTransform.top()); } inline unsigned int RemoveTransform() { - ASSERT(m_groupTransform.size()); - if (m_groupTransform.size()) + ASSERT(m_groupTransformSize); + if (m_groupTransformSize) + { m_groupTransform.pop(); - if (m_groupTransform.size()) + m_groupTransformSize--; + } + if (m_groupTransformSize) UpdateFinalTransform(m_groupTransform.top()); else UpdateFinalTransform(TransformMatrix()); - return m_groupTransform.size(); + return m_groupTransformSize; } CRect generateAABB(const CRect &rect) const; @@ -232,7 +237,7 @@ class CGraphicContext : public CCriticalSection TransformMatrix m_guiTransform; TransformMatrix m_finalTransform; std::stack m_groupTransform; - + unsigned int m_groupTransformSize; CRect m_scissors; }; diff --git a/xbmc/settings/AppParamParser.cpp b/xbmc/settings/AppParamParser.cpp index 491b9e529debd..0eb0c3eda5e0d 100644 --- a/xbmc/settings/AppParamParser.cpp +++ b/xbmc/settings/AppParamParser.cpp @@ -92,6 +92,7 @@ void CAppParamParser::DisplayHelp() printf("Usage: xbmc [OPTION]... [FILE]...\n\n"); printf("Arguments:\n"); printf(" -d \t\tdelay seconds before starting\n"); + printf(" --benchmark=n\t\tEnable meaningless benchmark mode. Run for msec then display the number of frames rendered\n"); printf(" -fs\t\t\tRuns XBMC in full screen\n"); printf(" --standalone\t\tXBMC runs in a stand alone environment without a window \n"); printf("\t\t\tmanager and supporting applications. For example, that\n"); @@ -137,6 +138,13 @@ void CAppParamParser::ParseArg(const CStdString &arg) m_testmode = true; else if (arg.substr(0, 11) == "--settings=") g_advancedSettings.AddSettingsFile(arg.substr(11)); + else if (arg.substr(0, 12) == "--benchmark=") + { + unsigned int benchmark_time = atoi(arg.substr(12).c_str()); + if (benchmark_time) + g_application.SetBenchmarkTimer(benchmark_time); + } + else if (arg.length() != 0 && arg[0] != '-') { if (m_testmode)