diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/include/IrrCompileConfig.h Irrlicht_starsonata/include/IrrCompileConfig.h --- irrlicht-svn-ss/trunk/include/IrrCompileConfig.h 2007-07-26 02:11:22.000000000 +0200 +++ Irrlicht_starsonata/include/IrrCompileConfig.h 2008-05-14 05:57:46.000000000 +0200 @@ -224,5 +224,8 @@ precision will be lower but speed higher #undef _IRR_COMPILE_WITH_DIRECT3D_9_ #endif +// enable/disable profiler +#define IRR_PROFILE 1 + #endif // __IRR_COMPILE_CONFIG_H_INCLUDED__ diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/include/irrlicht.h Irrlicht_starsonata/include/irrlicht.h --- irrlicht-svn-ss/trunk/include/irrlicht.h 2007-07-26 02:11:22.000000000 +0200 +++ Irrlicht_starsonata/include/irrlicht.h 2008-05-14 05:43:46.000000000 +0200 @@ -139,6 +143,7 @@ #include "SViewFrustum.h" #include "irrTypes.h" #include "coreutil.h" +#include "profiler.h" /*! \mainpage Irrlicht Engine 1.3.1 API documentation * diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/include/profiler.h Irrlicht_starsonata/include/profiler.h --- irrlicht-svn-ss/trunk/include/profiler.h 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht_starsonata/include/profiler.h 2008-08-20 14:22:17.000000000 +0200 @@ -0,0 +1,463 @@ +#ifndef __PROFILER_H_INCLUDED__ +#define __PROFILER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "irrTypes.h" +#include "rect.h" +#include "irrString.h" +#include "irrArray.h" +#include "ITimer.h" +#include "IGUIEnvironment.h" +#include "IGUIListbox.h" +#include + +namespace irr +{ +struct ProfileData +{ + friend class Profiler; + + ProfileData() + { + GroupId = 0; + reset(); + } + + bool operator<(const ProfileData& pd) const + { + return Id < pd.Id; + } + +private: + ProfileData(u32 id) : Id(id) {} // just to be used for searching + + void reset() + { + CountCalls = 0; + HighestTime = 0; + LowestTime = UINT_MAX; + TimeSum = 0; + LastTimeStarted = 0; + } + + u32 Id; + u32 GroupId; + core::stringw Name; + + u32 CountCalls; + u32 HighestTime; + u32 LowestTime; + u32 TimeSum; + + u32 LastTimeStarted; +}; + +class Profiler +{ +public: + Profiler() + : IrrTimer(0) + , GuiID(-1) + , DisplayRect(20, 20, 600, 400) + , OverviewGroupId(0) + { + addGroup(OverviewGroupId, "overview"); + ProfileGroups[0].GroupId = UINT_MAX; // overview does not belong to itself so it does not get printed on printAll + CurrentGroupId = OverviewGroupId; + } + + virtual ~Profiler() + { + } + + void init(irr::ITimer * irrlichtTimer, s32 guiId) + { + IrrTimer = irrlichtTimer; + GuiID = guiId; + } + + // set the rectangle used for the display listbox + void setDisplayRect(const core::rect &rect_) + { + DisplayRect = rect_; + } + + inline void add(u32 id_, u32 groupId_, const core::stringw &name_); + inline void addGroup(u32 groupId_, const core::stringw &name_); + + inline void start(u32 id_); + inline void stop(u32 id_); + + inline void reset(u32 id_); + inline void resetGroup(u32 groupId_); + inline void resetAll(); + inline void show(gui::IGUIEnvironment* env_); // print current display group on screen + inline void hide(gui::IGUIEnvironment* env_); + inline void print(core::stringw &ostream, bool suppressUncalled_=true); // write current display group into string + inline void printAll(core::stringw &ostream, bool includeOverview=false,bool suppressUncalled_=true); // write all groups itno string + + inline void setDisplayGroup(u32 groupId_); + inline void nextDisplayGroup(); + inline void previousDisplayGroup(); + inline void firstDisplayGroup(); + +protected: + inline void printGroup(core::stringw &ostream, u32 groupId_, bool suppressUncalled_); + inline core::stringw makeDataString(const ProfileData & data_); + inline core::stringw makeTitleString(); + +private: + irr::ITimer * IrrTimer; + s32 GuiID; + core::rect DisplayRect; + u32 OverviewGroupId; + u32 CurrentGroupId; + core::array ProfileDatas; + core::array ProfileGroups; +}; + +IRRLICHT_API Profiler* IRRCALLCONV getProfiler(); +extern Profiler gPROFILER; + + +// inline implementation +void Profiler::add(u32 id, u32 groupId, const core::stringw &name) +{ + ProfileData data; + data.Id = id; + data.GroupId = groupId; + data.Name = name; + + s32 idx = ProfileDatas.binary_search(data); + if ( idx < 0 ) + { + ProfileDatas.push_back(data); + ProfileDatas.sort(); + } + else + { + ProfileDatas[idx] = data; + } +} + +void Profiler::addGroup(u32 groupId, const core::stringw &name) +{ + ProfileData group; + group.Id = groupId; + group.GroupId = OverviewGroupId; + group.Name = name; + + s32 idx = ProfileGroups.binary_search(group); + if ( idx < 0 ) + { + ProfileGroups.push_back(group); + ProfileGroups.sort(); + } + else + { + ProfileGroups[idx] = group; + } +} + +void Profiler::start(u32 id) +{ + s32 idx = ProfileDatas.binary_search(ProfileData(id)); + if ( idx >= 0 && IrrTimer ) + { + ProfileDatas[idx].LastTimeStarted = IrrTimer->getRealTime(); + } +} + +void Profiler::stop(u32 id) +{ + s32 idx = ProfileDatas.binary_search(ProfileData(id)); + if ( idx >= 0 && IrrTimer ) + { + ProfileData &data = ProfileDatas[idx]; + u32 diffTime = IrrTimer->getRealTime() - data.LastTimeStarted; + if ( data.LastTimeStarted == 0 ) + return; + + ++data.CountCalls; + data.TimeSum += diffTime; + if ( diffTime > data.HighestTime ) + data.HighestTime = diffTime; + if ( diffTime < data.LowestTime ) + data.LowestTime = diffTime; + data.LastTimeStarted = 0; + + + s32 idxGroup = ProfileGroups.binary_search(ProfileData(data.GroupId)); + if ( idxGroup >= 0 ) + { + ProfileData & group = ProfileGroups[idxGroup]; + ++group.CountCalls; + group.TimeSum += diffTime; + if ( diffTime > group.HighestTime ) + group.HighestTime = diffTime; + if ( diffTime < group.LowestTime ) + group.LowestTime = diffTime; + group.LastTimeStarted = 0; + } + } +} + +void Profiler::reset(u32 id) +{ + s32 idx = ProfileDatas.binary_search(ProfileData(id)); + if ( idx >= 0 ) + { + ProfileData &data = ProfileDatas[idx]; + + s32 idxGroup = ProfileGroups.binary_search(ProfileData(data.GroupId)); + if ( idxGroup >= 0 ) + { + ProfileData & group = ProfileGroups[idxGroup]; + group.CountCalls -= data.CountCalls; + group.TimeSum -= data.TimeSum; + } + + data.reset(); + } +} + +void Profiler::resetGroup(u32 groupId) +{ + for ( u32 i=0; iaddListBox(DisplayRect, 0, GuiID, true); + + core::stringw wstrTitle(makeTitleString()); + listBox->addItem(wstrTitle.c_str()); + + s32 idxGroup = ProfileGroups.binary_search(ProfileData(CurrentGroupId)); + if ( idxGroup < 0 ) + return; + + core::stringw wstrGroup(makeDataString(ProfileGroups[idxGroup])); + listBox->addItem(wstrGroup.c_str()); + + // show overview over groups? + if ( CurrentGroupId == OverviewGroupId ) + { + for ( u32 i=0; iaddItem(wstrData.c_str()); + } + } + } + // show data for current group + else + { + for ( u32 i=0; iaddItem(wstrData.c_str()); + } + } + } +} + +void Profiler::hide(irr::gui::IGUIEnvironment* env_) +{ + if ( !env_) + return; + + gui::IGUIElement* root = env_->getRootGUIElement(); + gui::IGUIElement* e = root->getElementFromId(GuiID, true); + if (e) + { + e->remove(); + } +} + +void Profiler::setDisplayGroup(u32 groupId) +{ + CurrentGroupId = groupId; +} + +void Profiler::nextDisplayGroup() +{ + s32 idxGroup = ProfileGroups.binary_search(ProfileData(CurrentGroupId)); + if ( idxGroup < 0 ) + { + CurrentGroupId = 0; + } + else + { + ++idxGroup; + idxGroup %= ProfileGroups.size(); + CurrentGroupId = ProfileGroups[idxGroup].Id; + } +} + +void Profiler::previousDisplayGroup() +{ + s32 idxGroup = ProfileGroups.binary_search(ProfileData(CurrentGroupId)); + if ( idxGroup == 0 ) + { + idxGroup = ProfileGroups.size()-1; + } + else + { + --idxGroup; + } + if ( idxGroup < 0 ) + { + CurrentGroupId = 0; + } + else + { + CurrentGroupId = ProfileGroups[idxGroup].Id; + } +} + +void Profiler::firstDisplayGroup() +{ + if ( !ProfileGroups.size() ) + { + CurrentGroupId = 0; + } + else + { + CurrentGroupId = ProfileGroups[0].Id; + } +} + +// print current active group +void Profiler::print(core::stringw &ostream, bool suppressUncalled) +{ + ostream += makeTitleString(); + printGroup(ostream, CurrentGroupId, suppressUncalled); +} + +void Profiler::printAll(core::stringw &ostream, bool includeOverview, bool suppressUncalled) +{ + ostream += makeTitleString(); + for ( u32 i=0; i 0) + && ProfileGroups[i].GroupId == OverviewGroupId ) + { + ostream += makeDataString(ProfileGroups[i]); + } + } + } + // print all data in a group + else + { + for ( u32 i=0; i 0) + && ProfileDatas[i].GroupId == groupId ) + { + ostream += makeDataString(ProfileDatas[i]); + } + } + } +} + +core::stringw Profiler::makeTitleString() +{ + return core::stringw("name calls time(sum) time(avg) time(max) time(min) \n"); +} + +core::stringw Profiler::makeDataString(const ProfileData & data_) +{ + core::stringw ostr; + + if ( data_.CountCalls > 0 ) + { + // don't we all sometimes dream of stl-streaming in irrlicht? +#ifdef _MSC_VER +#pragma warning(disable:4996) // 'sprintf' was declared deprecated +#endif + char dummy[1023]; + core::stringc name( data_.Name.c_str() ); // not a perfect conversion but don't wanna fight with finding platform independent wide-char printfs now + sprintf(dummy, "%-15.15s%-12u%-12u%-12u%-12u%-12u\n", + name.c_str(), data_.CountCalls, data_.TimeSum, + data_.TimeSum / data_.CountCalls, data_.HighestTime, + (data_.LowestTime <= data_.HighestTime ? data_.LowestTime : 0) + ); + dummy[1022] = 0; + ostr += core::stringw(dummy); +#ifdef _MSC_VER +#pragma warning(default :4996) // 'sprintf' was declared deprecated +#endif + } + else + { + ostr += data_.Name; + ostr += L"\n"; + } + + return ostr; +} + +} // namespace irr + +#if IRR_PROFILE + #define PROFILE_ADD(id_, groupId_, name_) irr::getProfiler()->add(id_, groupId_, name_) + #define PROFILE_ADD_GROUP(groupId_, name_) irr::getProfiler()->addGroup(groupId_, name_) + #define PROFILE_START(id_) irr::getProfiler()->start(id_) + #define PROFILE_STOP(id_) irr::getProfiler()->stop(id_) +#else + #define PROFILE_ADD(id_, groupId_, name_) + #define PROFILE_ADD_GROUP(groupId_, name_) + #define PROFILE_START(id_) + #define PROFILE_STOP(id_) +#endif // IRR_PROFILE + +#endif // __PROFILER_H_INCLUDED__ diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CIrrDeviceStub.cpp Irrlicht_starsonata/source/Irrlicht/CIrrDeviceStub.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CIrrDeviceStub.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CIrrDeviceStub.cpp 2008-05-15 04:19:58.000000000 +0200 @@ -12,6 +12,8 @@ #include "CTimer.h" #include "CLogger.h" #include "irrString.h" +#include "profiler.h" +#include "profile_ids.h" namespace irr { @@ -31,6 +33,13 @@ CIrrDeviceStub::CIrrDeviceStub(const cha os::Printer::log(s.c_str(), ELL_INFORMATION); checkVersion(version); + + PROFILE_ADD_GROUP(EPG_IRRLICHT, "Irrlicht"); + PROFILE_ADD(EPD_TESTING1, EPG_IRRLICHT, "TESTING1"); + PROFILE_ADD(EPD_TESTING2, EPG_IRRLICHT, "TESTING2"); + PROFILE_ADD(EPD_TESTING3, EPG_IRRLICHT, "TESTING3"); + PROFILE_ADD(EPD_TESTING4, EPG_IRRLICHT, "TESTING4"); + PROFILE_ADD(EPD_TESTING5, EPG_IRRLICHT, "TESTING5"); } diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/profile_ids.h Irrlicht_starsonata/source/Irrlicht/profile_ids.h --- irrlicht-svn-ss/trunk/source/Irrlicht/profile_ids.h 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht_starsonata/source/Irrlicht/profile_ids.h 2008-05-15 03:31:22.000000000 +0200 @@ -0,0 +1,22 @@ +#ifndef __IRR_PROFILE_IDS_H_INCLUDED__ +#define __IRR_PROFILE_IDS_H_INCLUDED__ + +enum EPROFILE_GROUP +{ + //! general group for irrlicht profiling + EPG_IRRLICHT = 1, +}; + +enum EPROFILE_DATA +{ + //! Testing are just thought for those moments when you just need some + //! profiling which you will remove again after you're finished profiling. + //! They are addded in CIrrDeviceStub right after creating a device + EPD_TESTING1 = 1, + EPD_TESTING2, + EPD_TESTING3, + EPD_TESTING4, + EPD_TESTING5, +}; + +#endif // #define __IRR_PROFILE_IDS_H_INCLUDED__ diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/profiler.cpp Irrlicht_starsonata/source/Irrlicht/profiler.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/profiler.cpp 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht_starsonata/source/Irrlicht/profiler.cpp 2008-05-14 22:45:26.000000000 +0200 @@ -0,0 +1,13 @@ +#include "profiler.h" + +namespace irr +{ + +Profiler gPROFILER; + +IRRLICHT_API Profiler* IRRCALLCONV getProfiler() +{ + return &gPROFILER; +} + +} // namespace irr