OgreProfiler.h
Go to the documentation of this file.
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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:22