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-2012 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 "OgreOverlay.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 { 00081 enum ProfileGroupMask 00082 { 00084 OGREPROF_USER_DEFAULT = 0x00000001, 00086 OGREPROF_ALL = 0xFF000000, 00088 OGREPROF_GENERAL = 0x80000000, 00090 OGREPROF_CULLING = 0x40000000, 00092 OGREPROF_RENDERING = 0x20000000 00093 }; 00094 00105 class _OgreExport Profile : 00106 public ProfilerAlloc 00107 { 00108 00109 public: 00110 Profile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00111 ~Profile(); 00112 00113 protected: 00114 00116 String mName; 00118 uint32 mGroupID; 00119 00120 00121 }; 00122 00134 class _OgreExport Profiler : 00135 public Singleton<Profiler>, 00136 public ProfilerAlloc 00137 { 00138 public: 00139 Profiler(); 00140 ~Profiler(); 00141 00143 void setTimer(Timer* t); 00144 00146 Timer* getTimer(); 00147 00161 void beginProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00162 00177 void endProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); 00178 00182 void beginGPUEvent(const String& event); 00183 00187 void endGPUEvent(const String& event); 00188 00192 void markGPUEvent(const String& event); 00193 00199 void setEnabled(bool enabled); 00200 00202 bool getEnabled() const; 00203 00207 void enableProfile(const String& profileName); 00208 00212 void disableProfile(const String& profileName); 00213 00216 void setProfileGroupMask(uint32 mask) { mProfileMask = mask; } 00219 uint32 getProfileGroupMask() const { return mProfileMask; } 00220 00226 bool watchForMax(const String& profileName); 00227 00233 bool watchForMin(const String& profileName); 00234 00244 bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); 00245 00247 void logResults(); 00248 00250 void reset(); 00251 00252 enum DisplayMode 00253 { 00255 DISPLAY_PERCENTAGE, 00257 DISPLAY_MILLISECONDS 00258 }; 00259 00262 void setDisplayMode(DisplayMode d) { mDisplayMode = d; } 00265 DisplayMode getDisplayMode() const { return mDisplayMode; } 00266 00268 void setUpdateDisplayFrequency(uint freq); 00269 00271 uint getUpdateDisplayFrequency() const; 00272 00274 void setOverlayDimensions(Real width, Real height); 00275 00277 void setOverlayPosition(Real left, Real top); 00278 00279 Real getOverlayWidth() const; 00280 Real getOverlayHeight() const; 00281 Real getOverlayLeft() const; 00282 Real getOverlayTop() const; 00283 00299 static Profiler& getSingleton(void); 00315 static Profiler* getSingletonPtr(void); 00316 00317 00318 00319 protected: 00320 00322 void initialize(); 00323 00324 class ProfileInstance; 00325 friend class ProfileInstance; 00326 typedef list<OverlayElement*>::type ProfileBarList; 00327 00328 void displayResults(void); 00331 void displayResults(ProfileInstance* instance, ProfileBarList::iterator& bIter, Real& maxTimeMillisecs, Real& newGuiHeight, int& profileCount); 00332 00334 void processFrameStats(void); 00336 void processFrameStats(ProfileInstance* instance, Real& maxFrameTime); 00337 00339 void changeEnableState(); 00340 00342 OverlayContainer* createContainer(); 00343 00345 OverlayElement* createTextArea(const String& name, Real width, Real height, Real top, Real left, 00346 uint fontSize, const String& caption, bool show = true); 00347 00349 OverlayElement* createPanel(const String& name, Real width, Real height, Real top, Real left, 00350 const String& materialName, bool show = true); 00351 00352 00355 struct ProfileFrame 00356 { 00357 00359 ulong frameTime; 00360 00362 uint calls; 00363 00365 uint hierarchicalLvl; 00366 00367 }; 00368 00370 struct ProfileHistory 00371 { 00373 Real currentTimePercent; 00375 Real currentTimeMillisecs; 00376 00378 Real maxTimePercent; 00380 Real maxTimeMillisecs; 00381 00383 Real minTimePercent; 00385 Real minTimeMillisecs; 00386 00388 uint numCallsThisFrame; 00389 00391 Real totalTimePercent; 00393 Real totalTimeMillisecs; 00394 00397 ulong totalCalls; 00398 00400 uint hierarchicalLvl; 00401 00402 }; 00403 00405 class ProfileInstance : 00406 public ProfilerAlloc 00407 { 00408 friend class Profiler; 00409 public: 00410 ProfileInstance(void); 00411 virtual ~ProfileInstance(void); 00412 00413 typedef Ogre::map<String,ProfileInstance*>::type ProfileChildren; 00414 00415 void logResults(); 00416 void reset(); 00417 00418 inline bool watchForMax(void) { return history.currentTimePercent == history.maxTimePercent; } 00419 inline bool watchForMin(void) { return history.currentTimePercent == history.minTimePercent; } 00420 inline bool watchForLimit(Real limit, bool greaterThan = true) 00421 { 00422 if (greaterThan) 00423 return history.currentTimePercent > limit; 00424 else 00425 return history.currentTimePercent < limit; 00426 } 00427 00428 bool watchForMax(const String& profileName); 00429 bool watchForMin(const String& profileName); 00430 bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); 00431 00433 String name; 00434 00436 ProfileInstance* parent; 00437 00438 ProfileChildren children; 00439 00440 ProfileFrame frame; 00441 ulong frameNumber; 00442 00443 ProfileHistory history; 00444 00446 ulong currTime; 00447 00450 ulong accum; 00451 00453 uint hierarchicalLvl; 00454 }; 00455 00456 // lol. Uses typedef; put's original container type in name. 00457 typedef set<String>::type DisabledProfileMap; 00458 typedef ProfileInstance::ProfileChildren ProfileChildren; 00459 00460 ProfileInstance* mCurrent; 00461 ProfileInstance* mLast; 00462 ProfileInstance mRoot; 00463 00465 DisabledProfileMap mDisabledProfiles; 00466 00468 ProfileBarList mProfileBars; 00469 00471 bool mInitialized; 00472 00474 uint mMaxDisplayProfiles; 00475 00477 Overlay* mOverlay; 00478 00480 OverlayContainer* mProfileGui; 00481 00483 Real mBarHeight; 00484 00486 Real mGuiHeight; 00487 00489 Real mGuiWidth; 00490 00492 Real mGuiLeft; 00493 00495 Real mGuiTop; 00496 00498 Real mBarIndent; 00499 00501 Real mGuiBorderWidth; 00502 00504 Real mBarLineWidth; 00505 00507 Real mBarSpacing; 00508 00511 uint mUpdateDisplayFrequency; 00512 00514 uint mCurrentFrame; 00515 00517 Timer* mTimer; 00518 00520 ulong mTotalFrameTime; 00521 00523 bool mEnabled; 00524 00527 bool mNewEnableState; 00528 00530 uint32 mProfileMask; 00531 00533 DisplayMode mDisplayMode; 00534 00536 ulong mMaxTotalFrameTime; 00537 00539 Real mAverageFrameTime; 00540 bool mResetExtents; 00541 00542 00543 }; // end class 00547 } // end namespace 00548 00549 #endif
Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:22