From 3ce488307f5394e51ff006458a8245bdbd5e6bfa Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 25 Oct 2012 23:29:49 +0200 Subject: Performance counters --- src/app/app.cpp | 77 ++++++++++++++++++++++ src/app/app.h | 40 ++++++++++++ src/graphics/engine/engine.cpp | 144 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 247 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/app/app.cpp b/src/app/app.cpp index 4af3870..823bc77 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -122,6 +122,12 @@ CApplication::CApplication() m_curTimeStamp = CreateTimeStamp(); m_lastTimeStamp = CreateTimeStamp(); + for (int i = 0; i < PCNT_MAX; ++i) + { + m_performanceCounters[i][0] = CreateTimeStamp(); + m_performanceCounters[i][1] = CreateTimeStamp(); + } + m_joystickEnabled = false; m_mouseMode = MOUSE_SYSTEM; @@ -171,6 +177,12 @@ CApplication::~CApplication() DestroyTimeStamp(m_baseTimeStamp); DestroyTimeStamp(m_curTimeStamp); DestroyTimeStamp(m_lastTimeStamp); + + for (int i = 0; i < PCNT_MAX; ++i) + { + DestroyTimeStamp(m_performanceCounters[i][0]); + DestroyTimeStamp(m_performanceCounters[i][1]); + } } ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[]) @@ -718,6 +730,14 @@ int CApplication::Run() while (true) { + ResetPerformanceCounters(); + + if (m_active) + { + StartPerformanceCounter(PCNT_ALL); + StartPerformanceCounter(PCNT_EVENT_PROCESSING); + } + // To be sure no old event remains m_private->currentEvent.type = SDL_NOEVENT; @@ -829,21 +849,38 @@ int CApplication::Run() m_robotMain->EventProcess(event); } + StopPerformanceCounter(PCNT_EVENT_PROCESSING); + + StartPerformanceCounter(PCNT_UPDATE_ALL); + // Prepare and process step simulation event event = CreateUpdateEvent(); if (event.type != EVENT_NULL && m_robotMain != nullptr) { + StartPerformanceCounter(PCNT_UPDATE_ENGINE); m_engine->FrameUpdate(); + StopPerformanceCounter(PCNT_UPDATE_ENGINE); + m_sound->FrameMove(m_relTime); + StartPerformanceCounter(PCNT_UPDATE_GAME); m_robotMain->EventProcess(event); + StopPerformanceCounter(PCNT_UPDATE_GAME); } + StopPerformanceCounter(PCNT_UPDATE_ALL); + /* Update mouse position explicitly right before rendering * because mouse events are usually way behind */ UpdateMouse(); + StartPerformanceCounter(PCNT_RENDER_ALL); Render(); + StopPerformanceCounter(PCNT_RENDER_ALL); + + StopPerformanceCounter(PCNT_ALL); + + UpdatePerformanceCountersData(); if (m_lowCPU) { @@ -1451,3 +1488,43 @@ bool CApplication::GetLowCPU() { return m_lowCPU; } + +void CApplication::StartPerformanceCounter(PerformanceCounter counter) +{ + GetCurrentTimeStamp(m_performanceCounters[counter][0]); +} + +void CApplication::StopPerformanceCounter(PerformanceCounter counter) +{ + GetCurrentTimeStamp(m_performanceCounters[counter][1]); +} + +float CApplication::GetPerformanceCounterData(PerformanceCounter counter) +{ + return m_performanceCountersData[counter]; +} + +void CApplication::ResetPerformanceCounters() +{ + for (int i = 0; i < PCNT_MAX; ++i) + { + StartPerformanceCounter(static_cast(i)); + StopPerformanceCounter(static_cast(i)); + } +} + +void CApplication::UpdatePerformanceCountersData() +{ + long long sum = TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0], + m_performanceCounters[PCNT_ALL][1]); + + for (int i = 0; i < PCNT_MAX; ++i) + { + long long diff = TimeStampExactDiff(m_performanceCounters[i][0], + m_performanceCounters[i][1]); + + m_performanceCountersData[static_cast(i)] = + static_cast(diff) / static_cast(sum); + } +} + diff --git a/src/app/app.h b/src/app/app.h index 66b5848..84da0eb 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -113,6 +113,31 @@ enum MouseMode MOUSE_NONE, //! < no cursor visible }; +/** + * \enum PerformanceCounter + * \brief Type of counter testing performance + */ +enum PerformanceCounter +{ + PCNT_EVENT_PROCESSING, //! < event processing (except update events) + + PCNT_UPDATE_ALL, //! < the whole frame update process + PCNT_UPDATE_ENGINE, //! < frame update in CEngine + PCNT_UPDATE_PARTICLE, //! < frame update in CParticle + PCNT_UPDATE_GAME, //! < frame update in CRobotMain + + PCNT_RENDER_ALL, //! < the whole rendering process + PCNT_RENDER_PARTICLE, //! < rendering the particles in 3D + PCNT_RENDER_WATER, //! < rendering the water + PCNT_RENDER_TERRAIN, //! < rendering the terrain + PCNT_RENDER_OBJECTS, //! < rendering the 3D objects + PCNT_RENDER_INTERFACE, //! < rendering 2D interface + + PCNT_ALL, //! < all counters together + + PCNT_MAX +}; + struct ApplicationPrivate; /** @@ -301,6 +326,13 @@ public: bool GetLowCPU(); //@} + //! Management of performance counters + //@{ + void StartPerformanceCounter(PerformanceCounter counter); + void StopPerformanceCounter(PerformanceCounter counter); + float GetPerformanceCounterData(PerformanceCounter counter); + //@} + protected: //! Creates the window's SDL_Surface bool CreateVideoSurface(); @@ -321,6 +353,11 @@ protected: //! Closes the joystick device void CloseJoystick(); + //! Resets all performance counters to zero + void ResetPerformanceCounters(); + //! Updates performance counters from gathered timer data + void UpdatePerformanceCountersData(); + protected: //! Instance manager CInstanceManager* m_iMan; @@ -363,6 +400,9 @@ protected: SystemTimeStamp* m_lastTimeStamp; SystemTimeStamp* m_curTimeStamp; + SystemTimeStamp* m_performanceCounters[PCNT_MAX][2]; + float m_performanceCountersData[PCNT_MAX]; + long long m_realAbsTimeBase; long long m_realAbsTime; long long m_realRelTime; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index ca10304..856c2d4 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -378,7 +378,11 @@ void CEngine::FrameUpdate() float rTime = m_app->GetRelTime(); m_lightMan->UpdateProgression(rTime); + + m_app->StartPerformanceCounter(PCNT_UPDATE_PARTICLE); m_particle->FrameParticle(rTime); + m_app->StopPerformanceCounter(PCNT_UPDATE_PARTICLE); + ComputeDistance(); UpdateGeometry(); @@ -409,7 +413,7 @@ void CEngine::FrameUpdate() { m_groundMark.intensity = 0.0f; m_groundMark.phase = ENG_GR_MARK_PHASE_NULL; - m_groundMark.draw = false; + m_groundMark.draw = false; } } } @@ -3020,7 +3024,9 @@ void CEngine::Render() if (m_drawWorld) Draw3DScene(); + m_app->StartPerformanceCounter(PCNT_RENDER_INTERFACE); DrawInterface(); + m_app->StopPerformanceCounter(PCNT_RENDER_INTERFACE); // End the scene m_device->EndScene(); @@ -3051,12 +3057,13 @@ void CEngine::Draw3DScene() if (m_waterMode) m_water->DrawBack(); // draws water background + m_app->StartPerformanceCounter(PCNT_RENDER_TERRAIN); + + // Draw terrain with shadows, if shadows enabled if (m_shadowVisible) { m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN); - // Draw the terrain - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) { EngineObjLevel1& p1 = m_objectTree[l1]; @@ -3122,7 +3129,11 @@ void CEngine::Draw3DScene() DrawShadow(); } - // Draw objects (non-terrain) + m_app->StopPerformanceCounter(PCNT_RENDER_TERRAIN); + + // Draw other objects (and if shadows disabled, also terrain) + + m_app->StartPerformanceCounter(PCNT_RENDER_OBJECTS); bool transparent = false; @@ -3274,11 +3285,21 @@ void CEngine::Draw3DScene() } } + m_app->StopPerformanceCounter(PCNT_RENDER_OBJECTS); + m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN); - if (m_waterMode) m_water->DrawSurf(); // draws water surface + if (m_waterMode) + { + m_app->StartPerformanceCounter(PCNT_RENDER_WATER); + m_water->DrawSurf(); // draws water surface + m_app->StopPerformanceCounter(PCNT_RENDER_WATER); + } + m_app->StartPerformanceCounter(PCNT_RENDER_PARTICLE); m_particle->DrawParticle(SH_WORLD); // draws the particles of the 3D world + m_app->StopPerformanceCounter(PCNT_RENDER_PARTICLE); + m_lightning->Draw(); // draws lightning if (m_lensMode) DrawForegroundImage(); // draws the foreground @@ -4220,15 +4241,10 @@ void CEngine::DrawStats() if (!m_showStats) return; - std::stringstream str; - str << "Triangles: "; - str << m_statisticTriangle; - std::string triangleText = str.str(); - float height = m_text->GetAscent(FONT_COLOBOT, 12.0f); float width = 0.2f; - Math::Point pos(0.04f, 0.04f + height); + Math::Point pos(0.04f, 0.04f + 17 * height); SetState(ENG_RSTATE_OPAQUE_COLOR); @@ -4236,9 +4252,9 @@ void CEngine::DrawStats() VertexCol vertex[4] = { - VertexCol(Math::Vector(pos.x , pos.y - height, 0.0f), black), + VertexCol(Math::Vector(pos.x , pos.y - 17 * height, 0.0f), black), VertexCol(Math::Vector(pos.x , pos.y + height, 0.0f), black), - VertexCol(Math::Vector(pos.x + width, pos.y - height, 0.0f), black), + VertexCol(Math::Vector(pos.x + width, pos.y - 17 * height, 0.0f), black), VertexCol(Math::Vector(pos.x + width, pos.y + height, 0.0f), black) }; @@ -4246,7 +4262,107 @@ void CEngine::DrawStats() SetState(ENG_RSTATE_TEXT); - m_text->DrawText(triangleText, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + std::stringstream str; + + str.str(""); + str << "Event processing: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_EVENT_PROCESSING); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Frame update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Engine update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Particle update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Game update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + float otherUpdate = Math::Max(0.0f, m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME)); + + str.str(""); + str << "Other update: " << std::fixed << std::setprecision(2) << otherUpdate; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Frame render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_ALL); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Particle render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Water render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_WATER); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Terrain render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Objects render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "UI render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + float otherRender = m_app->GetPerformanceCounterData(PCNT_RENDER_ALL) - + m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE) - + m_app->GetPerformanceCounterData(PCNT_RENDER_WATER) - + m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN) - + m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS) - + m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE); + + str.str(""); + str << "Other render: " << std::fixed << std::setprecision(2) << otherRender; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Triangles: " << m_statisticTriangle; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.y -= height; -- cgit v1.2.3-1-g7c22