00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2013 Torus Knot Software Ltd 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a copy 00010 of this software and associated documentation files (the "Software"), to deal 00011 in the Software without restriction, including without limitation the rights 00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 copies of the Software, and to permit persons to whom the Software is 00014 furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 THE SOFTWARE. 00026 ----------------------------------------------------------------------------- 00027 */ 00028 /* 00029 00030 Although the code is original, many of the ideas for the profiler were borrowed from 00031 "Real-Time In-Game Profiling" by Steve Rabin which can be found in Game Programming 00032 Gems 1. 00033 00034 This code can easily be adapted to your own non-Ogre project. The only code that is 00035 Ogre-dependent is in the visualization/logging routines and the use of the Timer class. 00036 00037 Enjoy! 00038 00039 */ 00040 00041 #ifndef __Profiler_H__ 00042 #define __Profiler_H__ 00043 00044 #include "OgrePrerequisites.h" 00045 #include "OgreSingleton.h" 00046 #include "OgreString.h" 00047 #include "OgreHeaderPrefix.h" 00048 00049 #if OGRE_PROFILING == 1 00050 # define OgreProfile( a ) Ogre::Profile _OgreProfileInstance( (a) ) 00051 # define OgreProfileBegin( a ) Ogre::Profiler::getSingleton().beginProfile( (a) ) 00052 # define OgreProfileEnd( a ) Ogre::Profiler::getSingleton().endProfile( (a) ) 00053 # define OgreProfileGroup( a, g ) Ogre::Profile _OgreProfileInstance( (a), (g) ) 00054 # define OgreProfileBeginGroup( a, g ) Ogre::Profiler::getSingleton().beginProfile( (a), (g) ) 00055 # define OgreProfileEndGroup( a, g ) Ogre::Profiler::getSingleton().endProfile( (a), (g) ) 00056 # define OgreProfileBeginGPUEvent( g ) Ogre::Profiler::getSingleton().beginGPUEvent(g) 00057 # define OgreProfileEndGPUEvent( g ) Ogre::Profiler::getSingleton().endGPUEvent(g) 00058 # define OgreProfileMarkGPUEvent( e ) Ogre::Profiler::getSingleton().markGPUEvent(e) 00059 #else 00060 # define OgreProfile( a ) 00061 # define OgreProfileBegin( a ) 00062 # define OgreProfileEnd( a ) 00063 # define OgreProfileGroup( a, g ) 00064 # define OgreProfileBeginGroup( a, g ) 00065 # define OgreProfileEndGroup( a, g ) 00066 # define OgreProfileBeginGPUEvent( e ) 00067 # define OgreProfileEndGPUEvent( e ) 00068 # define OgreProfileMarkGPUEvent( e ) 00069 #endif 00070 00071 namespace Ogre { 00080 enum ProfileGroupMask 00081 { 00083 OGREPROF_USER_DEFAULT = 0x00000001, 00085 OGREPROF_ALL = 0xFF000000, 00087 OGREPROF_GENERAL = 0x80000000, 00089 OGREPROF_CULLING = 0x40000000, 00091 OGREPROF_RENDERING = 0x20000000 00092 }; 00093 00104 class _OgreExport Profile : 00105 public ProfilerAlloc 00106 { 00107 00108 public: 00109 Profile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00110 ~Profile(); 00111 00112 protected: 00113 00115 String mName; 00117 uint32 mGroupID; 00118 00119 }; 00120 00124 struct ProfileFrame 00125 { 00126 00128 ulong frameTime; 00129 00131 uint calls; 00132 00134 uint hierarchicalLvl; 00135 00136 }; 00137 00139 struct ProfileHistory 00140 { 00142 Real currentTimePercent; 00144 Real currentTimeMillisecs; 00145 00147 Real maxTimePercent; 00149 Real maxTimeMillisecs; 00150 00152 Real minTimePercent; 00154 Real minTimeMillisecs; 00155 00157 uint numCallsThisFrame; 00158 00160 Real totalTimePercent; 00162 Real totalTimeMillisecs; 00163 00166 ulong totalCalls; 00167 00169 uint hierarchicalLvl; 00170 00171 }; 00172 00174 class ProfileInstance : public ProfilerAlloc 00175 { 00176 friend class Profiler; 00177 public: 00178 ProfileInstance(void); 00179 virtual ~ProfileInstance(void); 00180 00181 typedef Ogre::map<String,ProfileInstance*>::type ProfileChildren; 00182 00183 void logResults(); 00184 void reset(); 00185 00186 inline bool watchForMax(void) { return history.currentTimePercent == history.maxTimePercent; } 00187 inline bool watchForMin(void) { return history.currentTimePercent == history.minTimePercent; } 00188 inline bool watchForLimit(Real limit, bool greaterThan = true) 00189 { 00190 if (greaterThan) 00191 return history.currentTimePercent > limit; 00192 else 00193 return history.currentTimePercent < limit; 00194 } 00195 00196 bool watchForMax(const String& profileName); 00197 bool watchForMin(const String& profileName); 00198 bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); 00199 00201 String name; 00202 00204 ProfileInstance* parent; 00205 00206 ProfileChildren children; 00207 00208 ProfileFrame frame; 00209 ulong frameNumber; 00210 00211 ProfileHistory history; 00212 00214 ulong currTime; 00215 00218 ulong accum; 00219 00221 uint hierarchicalLvl; 00222 }; 00223 00229 class _OgreExport ProfileSessionListener 00230 { 00231 public: 00232 enum DisplayMode 00233 { 00235 DISPLAY_PERCENTAGE, 00237 DISPLAY_MILLISECONDS 00238 }; 00239 00240 ProfileSessionListener() : mDisplayMode(DISPLAY_MILLISECONDS) {} 00241 virtual ~ProfileSessionListener() {} 00242 00244 virtual void initializeSession() = 0; 00245 00247 virtual void finializeSession() = 0; 00248 00253 virtual void changeEnableState(bool enabled) {}; 00254 00256 virtual void displayResults(const ProfileInstance& instance, ulong maxTotalFrameTime) {}; 00257 00259 void setDisplayMode(DisplayMode d) { mDisplayMode = d; } 00260 00262 DisplayMode getDisplayMode() const { return mDisplayMode; } 00263 00264 protected: 00266 DisplayMode mDisplayMode; 00267 }; 00268 00280 class _OgreExport Profiler : 00281 public Singleton<Profiler>, 00282 public ProfilerAlloc 00283 { 00284 public: 00285 Profiler(); 00286 ~Profiler(); 00287 00289 void setTimer(Timer* t); 00290 00292 Timer* getTimer(); 00293 00307 void beginProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00308 00323 void endProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00324 00328 void beginGPUEvent(const String& event); 00329 00333 void endGPUEvent(const String& event); 00334 00338 void markGPUEvent(const String& event); 00339 00345 void setEnabled(bool enabled); 00346 00348 bool getEnabled() const; 00349 00353 void enableProfile(const String& profileName); 00354 00358 void disableProfile(const String& profileName); 00359 00362 void setProfileGroupMask(uint32 mask) { mProfileMask = mask; } 00365 uint32 getProfileGroupMask() const { return mProfileMask; } 00366 00372 bool watchForMax(const String& profileName); 00373 00379 bool watchForMin(const String& profileName); 00380 00390 bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); 00391 00393 void logResults(); 00394 00396 void reset(); 00397 00399 void setUpdateDisplayFrequency(uint freq); 00400 00402 uint getUpdateDisplayFrequency() const; 00403 00410 void addListener(ProfileSessionListener* listener); 00411 00418 void removeListener(ProfileSessionListener* listener); 00419 00435 static Profiler& getSingleton(void); 00451 static Profiler* getSingletonPtr(void); 00452 00453 protected: 00454 friend class ProfileInstance; 00455 00456 typedef vector<ProfileSessionListener*>::type TProfileSessionListener; 00457 TProfileSessionListener mListeners; 00458 00460 void initialize(); 00461 00462 void displayResults(); 00463 00465 void processFrameStats(void); 00467 void processFrameStats(ProfileInstance* instance, Real& maxFrameTime); 00468 00470 void changeEnableState(); 00471 00472 // lol. Uses typedef; put's original container type in name. 00473 typedef set<String>::type DisabledProfileMap; 00474 typedef ProfileInstance::ProfileChildren ProfileChildren; 00475 00476 ProfileInstance* mCurrent; 00477 ProfileInstance* mLast; 00478 ProfileInstance mRoot; 00479 00481 DisabledProfileMap mDisabledProfiles; 00482 00484 bool mInitialized; 00485 00488 uint mUpdateDisplayFrequency; 00489 00491 uint mCurrentFrame; 00492 00494 Timer* mTimer; 00495 00497 ulong mTotalFrameTime; 00498 00500 bool mEnabled; 00501 00504 bool mNewEnableState; 00505 00507 uint32 mProfileMask; 00508 00510 ulong mMaxTotalFrameTime; 00511 00513 Real mAverageFrameTime; 00514 bool mResetExtents; 00515 00516 00517 }; // end class 00521 } // end namespace 00522 00523 #include "OgreHeaderSuffix.h" 00524 00525 #endif
Copyright © 2012 Torus Knot Software Ltd

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:45