Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreProfiler.cpp

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 © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #include "OgreStableHeaders.h"
    00026 /*
    00027
    00028     Although the code is original, many of the ideas for the profiler were borrowed from
    00029 "Real-Time In-Game Profiling" by Steve Rabin which can be found in Game Programming
    00030 Gems 1.
    00031
    00032     This code can easily be adapted to your own non-Ogre project. The only code that is
    00033 Ogre-dependent is in the visualization/logging routines and the use of the Timer class.
    00034
    00035     Enjoy!
    00036
    00037 */
    00038
    00039 #include "OgreProfiler.h"
    00040 #include "OgreTimer.h"
    00041 #include "OgreLogManager.h"
    00042 #include "OgreStringConverter.h"
    00043 #include "OgreOverlayManager.h"
    00044 #include "OgreOverlay.h"
    00045 #include "OgreGuiManager.h"
    00046 #include "OgreGuiElement.h"
    00047 #include "OgreGuiContainer.h"
    00048
    00049 namespace Ogre {
    00050     //-----------------------------------------------------------------------
    00051     // PROFILE DEFINITIONS
    00052     //-----------------------------------------------------------------------
    00053     template<> Profiler* Singleton<Profiler>::ms_Singleton = 0;
    00054     Profiler* Profiler::getSingletonPtr(void)
    00055     {
    00056         return ms_Singleton;
    00057     }
    00058     Profiler& Profiler::getSingleton(void)
    00059     {
    00060         assert( ms_Singleton );  return ( *ms_Singleton );
    00061     }
    00062     //-----------------------------------------------------------------------
    00063     Profile::Profile(const String& profileName) {
    00064
    00065         mName = profileName;
    00066
    00067         Ogre::Profiler::getSingleton().beginProfile(profileName);
    00068
    00069     }
    00070     //-----------------------------------------------------------------------
    00071     Profile::~Profile() {
    00072
    00073         Ogre::Profiler::getSingleton().endProfile(mName);
    00074
    00075     }
    00076     //-----------------------------------------------------------------------
    00077
    00078
    00079     //-----------------------------------------------------------------------
    00080     // PROFILER DEFINITIONS
    00081     //-----------------------------------------------------------------------
    00082     Profiler::Profiler() {
    00083
    00084         // init some variables
    00085         mTimer = 0;
    00086         mTotalFrameTime = 0;
    00087         mUpdateDisplayFrequency = 0;
    00088         mCurrentFrame = 0;
    00089         mEnabled = mNewEnableState = false; // the profiler starts out as disabled
    00090         mEnableStateChangePending = false;
    00091         mInitialized = false;
    00092         maxProfiles = 50;
    00093
    00094         // by default the display will be updated every 10 frames
    00095         mUpdateDisplayFrequency = 10;
    00096
    00097     }
    00098     //-----------------------------------------------------------------------
    00099     Profiler::~Profiler() {
    00100
    00101         if (!mProfileHistory.empty()) {
    00102             // log the results of our profiling before we quit
    00103             logResults();
    00104         }
    00105
    00106         // clear all our lists
    00107         mProfiles.clear();
    00108         mProfileFrame.clear();
    00109         mProfileHistoryMap.clear();
    00110         mProfileHistory.clear();
    00111         mDisabledProfiles.clear();
    00112         mProfileBars.clear();
    00113
    00114     }
    00115     //-----------------------------------------------------------------------
    00116     void Profiler::initialize() {
    00117
    00118         // init some gui characteristics
    00119         mBarHeight = 10; //0.02;
    00120         mGuiBorderWidth = 10; //0.02;
    00121         mGuiHeight = 25; //0.05;
    00122         mGuiWidth = 250; //0.15;
    00123         mBarIndent = mGuiWidth;
    00124         mBarLineWidth = 2;
    00125
    00126         // create a new overlay to hold our Profiler display
    00127         mOverlay = (Overlay*)OverlayManager::getSingleton().create("Profiler");
    00128         mOverlay->setZOrder(500);
    00129
    00130         // this panel will be the main container for our profile bars
    00131         mProfileGui = createContainer();
    00132
    00133         GuiElement* element;
    00134
    00135         // we create the little "ticks" above the profiles
    00136         for (uint k = 1; k < 10; ++k) { // we don't want a tick at 0% or 100%
    00137
    00138             if (k != 5) { // we don't want a tick at 50%
    00139                 element = createTextArea("ProfileKeyLine" + StringConverter::toString(k), 20, 10, 2, mGuiWidth * (1 + k * .1), 9, "|");
    00140                 mProfileGui->addChild(element);
    00141             }
    00142
    00143         }
    00144
    00145         // we create a 0% marker
    00146         element = createTextArea("ProfileKey0", 50, 10, 2, mGuiWidth * 0.99, 9, "0%");
    00147         mProfileGui->addChild(element);
    00148
    00149         // we create a 50% marker
    00150         element = createTextArea("ProfileyKey50", 50, 10, 2, mGuiWidth * 1.48, 9, "50%");
    00151         mProfileGui->addChild(element);
    00152
    00153         // we create a 100% marker
    00154         element = createTextArea("ProfileKey100", 50, 10, 2, mGuiWidth * 1.98, 9, "100%");
    00155         mProfileGui->addChild(element);
    00156
    00157         // we create an initial pool of 50 profile bars
    00158         for (uint i = 0; i < maxProfiles; ++i) {
    00159
    00160             // this is for the profile name and the number of times it was called in a frame
    00161             element = createTextArea("profileText" + StringConverter::toString(i), 90, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, 14, "", false);
    00162             mProfileGui->addChild(element);
    00163             mProfileBars.push_back(element);
    00164
    00165             // this indicates the current frame time
    00166             element = createPanel("currBar" + StringConverter::toString(i), 0, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, mBarIndent, "Core/ProfilerCurrent", false);
    00167             mProfileGui->addChild(element);
    00168             mProfileBars.push_back(element);
    00169
    00170             // this indicates the minimum frame time
    00171             element = createPanel("minBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerMin", false);
    00172             mProfileGui->addChild(element);
    00173             mProfileBars.push_back(element);
    00174
    00175             // this indicates the maximum frame time
    00176             element = createPanel("maxBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerMax", false);
    00177             mProfileGui->addChild(element);
    00178             mProfileBars.push_back(element);
    00179
    00180             // this indicates the average frame time
    00181             element = createPanel("avgBar" + StringConverter::toString(i), mBarLineWidth, mBarHeight, mGuiBorderWidth + (mBarHeight * 2) * i, 0, "Core/ProfilerAvg", false);
    00182             mProfileGui->addChild(element);
    00183             mProfileBars.push_back(element);
    00184
    00185         }
    00186
    00187         // throw everything all the GUI stuff into the overlay and display it
    00188         mOverlay->add2D(mProfileGui);
    00189         mOverlay->show();
    00190
    00191     }
    00192     //-----------------------------------------------------------------------
    00193     void Profiler::setTimer(Timer* t) {
    00194
    00195         mTimer = t;
    00196
    00197     }
    00198     //-----------------------------------------------------------------------
    00199     Timer* Profiler::getTimer() {
    00200
    00201         assert(mTimer && "Timer not set!");
    00202         return mTimer;
    00203
    00204     }
    00205     //-----------------------------------------------------------------------
    00206     void Profiler::setEnabled(bool enabled) {
    00207
    00208         if (!mInitialized && enabled) {
    00209
    00210             // the user wants to enable the Profiler for the first time
    00211             // so we initialize the GUI stuff
    00212             initialize();
    00213             mInitialized = true;
    00214             mEnabled = true;
    00215
    00216         }
    00217         else {
    00218             // We store this enable/disable request until the frame ends
    00219             // (don't want to screw up any open profiles!)
    00220             mEnableStateChangePending = true;
    00221             mNewEnableState = enabled;
    00222         }
    00223
    00224     }
    00225     //-----------------------------------------------------------------------
    00226     bool Profiler::getEnabled() const {
    00227
    00228         return mEnabled;
    00229
    00230     }
    00231     //-----------------------------------------------------------------------
    00232     void Profiler::disableProfile(const String& profileName) {
    00233
    00234         // make sure the profile isn't already disabled
    00235         DisabledProfileMap::iterator iter;
    00236         iter = mDisabledProfiles.find(profileName);
    00237
    00238         // make sure you don't disable a profile in the middle of that profile
    00239         ProfileStack::iterator pIter;
    00240         for (pIter = mProfiles.begin(); pIter != mProfiles.end(); ++pIter) {
    00241
    00242             if (profileName == (*pIter).name)
    00243                 break;
    00244
    00245         }
    00246
    00247         // if those two conditions are met, disable the profile
    00248         if ( (iter == mDisabledProfiles.end()) && (pIter == mProfiles.end()) ) {
    00249
    00250             mDisabledProfiles.insert(std::pair<String, bool>(profileName, true));
    00251
    00252         }
    00253
    00254     }
    00255     //-----------------------------------------------------------------------
    00256     void Profiler::enableProfile(const String& profileName) {
    00257
    00258         // make sure the profile is actually disabled
    00259         DisabledProfileMap::iterator iter;
    00260         iter = mDisabledProfiles.find(profileName);
    00261
    00262         // make sure you don't enable a profile in the middle of that profile
    00263         ProfileStack::iterator pIter;
    00264         for (pIter = mProfiles.begin(); pIter != mProfiles.end(); ++pIter) {
    00265
    00266             if (profileName == (*pIter).name)
    00267                 break;
    00268
    00269         }
    00270
    00271         // if those two conditions are met, enable the profile by removing it from
    00272         // the disabled list
    00273         if ( (iter != mDisabledProfiles.end()) && (pIter == mProfiles.end()) ) {
    00274
    00275             mDisabledProfiles.erase(iter);
    00276
    00277         }
    00278
    00279     }
    00280     //-----------------------------------------------------------------------
    00281     void Profiler::beginProfile(const String& profileName) {
    00282
    00283         // if the profiler is enabled
    00284         if (!mEnabled) {
    00285
    00286             return;
    00287
    00288         }
    00289
    00290         // empty string is reserved for the root
    00291         assert ((profileName != "") && ("Profile name can't be an empty string"));
    00292
    00293         ProfileStack::iterator iter;
    00294         for (iter = mProfiles.begin(); iter != mProfiles.end(); ++iter) {
    00295
    00296             if ((*iter).name == profileName) {
    00297
    00298                 break;
    00299
    00300             }
    00301
    00302         }
    00303
    00304         // make sure this profile isn't being used more than once
    00305         assert ((iter == mProfiles.end()) && ("This profile name is already being used"));
    00306
    00307         // we only process this profile if isn't disabled
    00308         DisabledProfileMap::iterator dIter;
    00309         dIter = mDisabledProfiles.find(profileName);
    00310         if ( dIter != mDisabledProfiles.end() ) {
    00311
    00312             return;
    00313
    00314         }
    00315
    00316         ProfileInstance p;
    00317
    00318         // this is the root, it has no parent
    00319         if (mProfiles.empty()) {
    00320
    00321             p.parent = "";
    00322
    00323         }
    00324         // otherwise peek at the stack and use the top as the parent
    00325         else {
    00326
    00327             ProfileInstance parent = mProfiles.back();
    00328             p.parent = parent.name;
    00329
    00330         }
    00331
    00332         // need a timer to profile!
    00333         assert (mTimer && "Timer not set!");
    00334
    00335         ProfileFrameList::iterator fIter;
    00336         ProfileHistoryList::iterator hIter;
    00337
    00338         // we check to see if this profile has been called in the frame before
    00339         for (fIter = mProfileFrame.begin(); fIter != mProfileFrame.end(); ++fIter) {
    00340
    00341             if ((*fIter).name == profileName)
    00342                 break;
    00343
    00344         }
    00345         // if it hasn't been called before, set its position in the stack
    00346         if (fIter == mProfileFrame.end()) {
    00347
    00348             ProfileFrame f;
    00349             f.name = profileName;
    00350             f.frameTime = 0;
    00351             f.calls = 0;
    00352             f.hierarchicalLvl = (uint) mProfiles.size();
    00353             mProfileFrame.push_back(f);
    00354
    00355         }
    00356
    00357         // we check to see if this profile has been called in the app before
    00358         ProfileHistoryMap::iterator histMapIter;
    00359         histMapIter = mProfileHistoryMap.find(profileName);
    00360
    00361         // if not we add a profile with just the name into the history
    00362         if (histMapIter == mProfileHistoryMap.end()) {
    00363
    00364             ProfileHistory h;
    00365             h.name = profileName;
    00366             h.numCallsThisFrame = 0;
    00367             h.totalTime = 0;
    00368             h.totalCalls = 0;
    00369             h.maxTime = 0;
    00370             h.minTime = 1;
    00371             h.hierarchicalLvl = p.hierarchicalLvl;
    00372             h.currentTime = 0;
    00373
    00374             // we add this to the history
    00375             hIter = mProfileHistory.insert(mProfileHistory.end(), h);
    00376
    00377             // for quick look-ups, we'll add it to the history map as well
    00378             mProfileHistoryMap.insert(std::pair<String, ProfileHistoryList::iterator>(profileName, hIter));
    00379
    00380         }
    00381
    00382         // add the stats to this profile and push it on the stack
    00383         // we do this at the very end of the function to get the most
    00384         // accurate timing results
    00385         p.name = profileName;
    00386         p.currTime = mTimer->getMicroseconds();
    00387         p.accum = 0;
    00388         p.hierarchicalLvl = (uint) mProfiles.size();
    00389         mProfiles.push_back(p);
    00390
    00391     }
    00392     //-----------------------------------------------------------------------
    00393     void Profiler::endProfile(const String& profileName) {
    00394
    00395         // if the profiler is enabled
    00396         if(!mEnabled) {
    00397
    00398             return;
    00399
    00400         }
    00401
    00402         // need a timer to profile!
    00403         assert (mTimer && "Timer not set!");
    00404
    00405         // get the end time of this profile
    00406         // we do this as close the beginning of this function as possible
    00407         // to get more accurate timing results
    00408         ulong endTime = mTimer->getMicroseconds();
    00409
    00410         // empty string is reserved for designating an empty parent
    00411         assert ((profileName != "") && ("Profile name can't be an empty string"));
    00412
    00413         // we only process this profile if isn't disabled
    00414         DisabledProfileMap::iterator dIter;
    00415         dIter = mDisabledProfiles.find(profileName);
    00416         if ( dIter != mDisabledProfiles.end() ) {
    00417
    00418             return;
    00419
    00420         }
    00421
    00422         // stack shouldnt be empty
    00423         assert (!mProfiles.empty());
    00424
    00425         // get the start of this profile
    00426         ProfileInstance bProfile;
    00427         bProfile = mProfiles.back();
    00428         mProfiles.pop_back();
    00429
    00430         // calculate the elapsed time of this profile
    00431         ulong timeElapsed = endTime - bProfile.currTime;
    00432
    00433         // update parent's accumalator if it isn't the root
    00434         if (bProfile.parent != "") {
    00435
    00436             // find the parent
    00437             ProfileStack::iterator iter;
    00438             for(iter = mProfiles.begin(); iter != mProfiles.end(); ++iter) {
    00439
    00440                 if ((*iter).name == bProfile.parent)
    00441                     break;
    00442
    00443             }
    00444
    00445             // the parent should be found
    00446             assert(iter != mProfiles.end());
    00447
    00448             // add this profile's time to the parent's accumlator
    00449             (*iter).accum += timeElapsed;
    00450
    00451         }
    00452
    00453         // we find the profile in this frame
    00454         ProfileFrameList::iterator iter;
    00455         for (iter = mProfileFrame.begin(); iter != mProfileFrame.end(); ++iter) {
    00456
    00457             if ((*iter).name == bProfile.name)
    00458                 break;
    00459
    00460         }
    00461
    00462         // we subtract the time the children profiles took from this profile
    00463         (*iter).frameTime += timeElapsed - bProfile.accum;
    00464         (*iter).calls++;
    00465
    00466         // the stack is empty and all the profiles have been completed
    00467         // we have reached the end of the frame so process the frame statistics
    00468         if (mProfiles.empty()) {
    00469
    00470             // we know that the time elapsed of the main loop is the total time the frame took
    00471             mTotalFrameTime = timeElapsed;
    00472
    00473             // we got all the information we need, so process the profiles
    00474             // for this frame
    00475             processFrameStats();
    00476
    00477             // clear the frame stats for next frame
    00478             mProfileFrame.clear();
    00479
    00480             // we display everything to the screen
    00481             displayResults();
    00482
    00483             // if the profiler received a request to be enabled or disabled
    00484             // we reached the end of the frame so we can safely do this
    00485             if (mEnableStateChangePending) {
    00486
    00487                 changeEnableState();
    00488
    00489             }
    00490
    00491         }
    00492
    00493     }
    00494     //-----------------------------------------------------------------------
    00495     void Profiler::processFrameStats() {
    00496
    00497         ProfileFrameList::iterator frameIter;
    00498         ProfileHistoryList::iterator historyIter;
    00499
    00500         // we set the number of times each profile was called per frame to 0
    00501         // because not all profiles are called every frame
    00502         for (historyIter = mProfileHistory.begin(); historyIter != mProfileHistory.end(); ++historyIter) {
    00503
    00504             (*historyIter).numCallsThisFrame = 0;
    00505
    00506         }
    00507
    00508         // iterate through each of the profiles processed during this frame
    00509         for (frameIter = mProfileFrame.begin(); frameIter != mProfileFrame.end(); ++frameIter) {
    00510
    00511             String s = (*frameIter).name;
    00512
    00513             // use our map to find the appropriate profile in the history
    00514             historyIter = (*mProfileHistoryMap.find(s)).second;
    00515
    00516             // extract the frame stats
    00517             ulong frameTime = (*frameIter).frameTime;
    00518             uint calls = (*frameIter).calls;
    00519             uint lvl = (*frameIter).hierarchicalLvl;
    00520
    00521             // calculate what percentage of frame time this profile took
    00522             Real framePercentage = (Real) frameTime / (Real) mTotalFrameTime;
    00523
    00524             // update the profile stats
    00525             (*historyIter).currentTime = framePercentage;
    00526             (*historyIter).totalTime += framePercentage;
    00527             (*historyIter).totalCalls++;
    00528             (*historyIter).numCallsThisFrame = calls;
    00529             (*historyIter).hierarchicalLvl = lvl;
    00530
    00531             // if we find a new minimum for this profile, update it
    00532             if ((framePercentage) < ((*historyIter).minTime)) {
    00533
    00534                 (*historyIter).minTime = framePercentage;
    00535
    00536             }
    00537
    00538             // if we find a new maximum for this profile, update it
    00539             if ((framePercentage) > ((*historyIter).maxTime)) {
    00540
    00541                 (*historyIter).maxTime = framePercentage;
    00542
    00543             }
    00544
    00545         }
    00546
    00547     }
    00548     //-----------------------------------------------------------------------
    00549     void Profiler::displayResults() {
    00550
    00551         if (!mEnabled) {
    00552
    00553             return;
    00554
    00555         }
    00556
    00557         // if its time to update the display
    00558         if (mCurrentFrame >= mUpdateDisplayFrequency) {
    00559
    00560             mCurrentFrame = 0;
    00561
    00562             ProfileHistoryList::iterator iter;
    00563             ProfileBarList::iterator bIter;
    00564
    00565             GuiElement* g;
    00566
    00567             Real newGuiHeight = mGuiHeight;
    00568
    00569             int temp = 0; // dummy variable for weird Ogre issue
    00570
    00571             // go through each profile and display it
    00572             for (iter = mProfileHistory.begin(), bIter = mProfileBars.begin();
    00573                 iter != mProfileHistory.end() && bIter != mProfileBars.end();
    00574                 ++iter, ++bIter)
    00575             {
    00576
    00577                 // display the profile's name and the number of times it was called in a frame
    00578                 g = *bIter;
    00579                 g->show();
    00580                 g->setCaption((*iter).name + " (" + StringConverter::toString((*iter).numCallsThisFrame) + ")");
    00581                 g->setLeft(10 + (*iter).hierarchicalLvl * 15);
    00582
    00583                 // display the main bar that show the percentage of the frame time that this
    00584                 // profile has taken
    00585                 bIter++;
    00586                 g = *bIter;
    00587                 g->show();
    00588                 // most of this junk has been set before, but we do this to get around a weird
    00589                 // Ogre gui issue (bug?)
    00590                 g->setMetricsMode(GMM_PIXELS);
    00591                 g->setHeight(mBarHeight);
    00592                 g->setWidth(((*iter).currentTime) * mGuiWidth);
    00593                 g->setLeft(mGuiWidth);
    00594                 g->setTop(mGuiBorderWidth + temp * mBarHeight * 2);
    00595
    00596                 // display line to indicate the minimum frame time for this profile
    00597                 bIter++;
    00598                 g = *bIter;
    00599                 g->show();
    00600                 g->setLeft(mBarIndent + (*iter).minTime * mGuiWidth);
    00601
    00602                 // display line to indicate the maximum frame time for this profile
    00603                 bIter++;
    00604                 g = *bIter;
    00605                 g->show();
    00606                 g->setLeft(mBarIndent + (*iter).maxTime * mGuiWidth);
    00607
    00608                 // display line to indicate the average frame time for this profile
    00609                 bIter++;
    00610                 g = *bIter;
    00611                 g->show();
    00612                 if ((*iter).totalCalls != 0)
    00613                     g->setLeft(mBarIndent + ((*iter).totalTime / (*iter).totalCalls) * mGuiWidth);
    00614                 else
    00615                     g->setLeft(mBarIndent);
    00616                 // we set the height of the display with respect to the number of profiles displayed
    00617                 newGuiHeight += mBarHeight * 2;
    00618
    00619                 temp++;
    00620
    00621             }
    00622
    00623             // set the main display dimensions
    00624             mProfileGui->setMetricsMode(GMM_PIXELS);
    00625             mProfileGui->setHeight(newGuiHeight);
    00626             mProfileGui->setWidth(mGuiWidth * 2 + 15);
    00627             mProfileGui->setTop(5);
    00628             mProfileGui->setLeft(5);
    00629
    00630             // we hide all the remaining pre-created bars
    00631             for (; bIter != mProfileBars.end(); ++bIter) {
    00632
    00633                 (*bIter)->hide();
    00634
    00635             }
    00636
    00637         }
    00638
    00639         // not time to update the display yet
    00640         else {
    00641
    00642             mCurrentFrame++;
    00643
    00644         }
    00645
    00646     }
    00647     //-----------------------------------------------------------------------
    00648     bool Profiler::watchForMax(const String& profileName) {
    00649
    00650         ProfileHistoryMap::iterator mapIter;
    00651         ProfileHistoryList::iterator iter;
    00652
    00653         mapIter = mProfileHistoryMap.find(profileName);
    00654
    00655         // if we don't find the profile, return false
    00656         if (mapIter == mProfileHistoryMap.end())
    00657             return false;
    00658
    00659         iter = (*mapIter).second;
    00660
    00661         return ((*iter).currentTime == (*iter).maxTime);
    00662
    00663     }
    00664     //-----------------------------------------------------------------------
    00665     bool Profiler::watchForMin(const String& profileName) {
    00666
    00667         ProfileHistoryMap::iterator mapIter;
    00668         ProfileHistoryList::iterator iter;
    00669
    00670         mapIter = mProfileHistoryMap.find(profileName);
    00671
    00672         // if we don't find the profile, return false
    00673         if (mapIter == mProfileHistoryMap.end())
    00674             return false;
    00675
    00676         iter = (*mapIter).second;
    00677
    00678         return ((*iter).currentTime == (*iter).minTime);
    00679
    00680     }
    00681     //-----------------------------------------------------------------------
    00682     bool Profiler::watchForLimit(const String& profileName, Real limit, bool greaterThan) {
    00683
    00684         ProfileHistoryMap::iterator mapIter;
    00685         ProfileHistoryList::iterator iter;
    00686
    00687         mapIter = mProfileHistoryMap.find(profileName);
    00688
    00689         // if we don't find the profile, return false
    00690         if (mapIter == mProfileHistoryMap.end())
    00691             return false;
    00692
    00693         iter = (*mapIter).second;
    00694
    00695         if (greaterThan)
    00696             return ((*iter).currentTime > limit);
    00697         else
    00698             return ((*iter).currentTime < limit);
    00699
    00700     }
    00701     //-----------------------------------------------------------------------
    00702     void Profiler::logResults() {
    00703
    00704         ProfileHistoryList::iterator iter;
    00705
    00706         LogManager::getSingleton().logMessage("----------------------Profiler Results----------------------");
    00707
    00708         for (iter = mProfileHistory.begin(); iter != mProfileHistory.end(); ++iter) {
    00709
    00710             // create an indent that represents the hierarchical order of the profile
    00711             String indent = "";
    00712             for (uint i = 0; i < (*iter).hierarchicalLvl; ++i) {
    00713
    00714                 indent = indent + "   ";
    00715
    00716             }
    00717
    00718             LogManager::getSingleton().logMessage(indent + "Name " + (*iter).name + " | Min " + StringConverter::toString((*iter).minTime) + " | Max " + StringConverter::toString((*iter).maxTime) + " | Avg "+ StringConverter::toString((*iter).totalTime / (*iter).totalCalls));
    00719
    00720         }
    00721
    00722         LogManager::getSingleton().logMessage("------------------------------------------------------------");
    00723
    00724     }
    00725     //-----------------------------------------------------------------------
    00726     void Profiler::reset() {
    00727
    00728         ProfileHistoryList::iterator iter;
    00729         for (iter = mProfileHistory.begin(); iter != mProfileHistory.end(); ++iter) {
    00730
    00731             (*iter).currentTime = (*iter).maxTime = (*iter).totalTime = 0;
    00732             (*iter).numCallsThisFrame = (*iter).totalCalls = 0;
    00733
    00734             (*iter).minTime = 1;
    00735
    00736         }
    00737
    00738     }
    00739     //-----------------------------------------------------------------------
    00740     void Profiler::setUpdateDisplayFrequency(uint freq) {
    00741
    00742         mUpdateDisplayFrequency = freq;
    00743
    00744     }
    00745     //-----------------------------------------------------------------------
    00746     uint Profiler::getUpdateDisplayFrequency() const {
    00747
    00748         return mUpdateDisplayFrequency;
    00749
    00750     }
    00751     //-----------------------------------------------------------------------
    00752     void Profiler::changeEnableState() {
    00753
    00754         if (mNewEnableState) {
    00755
    00756             mOverlay->show();
    00757
    00758         }
    00759         else {
    00760
    00761             mOverlay->hide();
    00762
    00763         }
    00764         mEnabled = mNewEnableState;
    00765         mEnableStateChangePending = false;
    00766
    00767     }
    00768     //-----------------------------------------------------------------------
    00769     GuiContainer* Profiler::createContainer() {
    00770
    00771         GuiContainer* container = (GuiContainer*) GuiManager::getSingleton().createGuiElement("BorderPanel", "profiler");
    00772         container->setMetricsMode(GMM_PIXELS);
    00773         container->setMaterialName("Core/StatsBlockCenter");
    00774         container->setHeight(mGuiHeight);
    00775         container->setWidth(mGuiWidth * 2 + 15);
    00776         container->setParameter("border_size", "1 1 1 1");
    00777         container->setParameter("border_material", "Core/StatsBlockBorder");
    00778         container->setParameter("border_topleft_uv", "0.0000 1.0000 0.0039 0.9961");
    00779         container->setParameter("border_top_uv", "0.0039 1.0000 0.9961 0.9961");
    00780         container->setParameter("border_topright_uv", "0.9961 1.0000 1.0000 0.9961");
    00781         container->setParameter("border_left_uv","0.0000 0.9961 0.0039 0.0039");
    00782         container->setParameter("border_right_uv","0.9961 0.9961 1.0000 0.0039");
    00783         container->setParameter("border_bottomleft_uv","0.0000 0.0039 0.0039 0.0000");
    00784         container->setParameter("border_bottom_uv","0.0039 0.0039 0.9961 0.0000");
    00785         container->setParameter("border_bottomright_uv","0.9961 0.0039 1.0000 0.0000");
    00786         container->setLeft(5);
    00787         container->setTop(5);
    00788
    00789         return container;
    00790
    00791     }
    00792     //-----------------------------------------------------------------------
    00793     GuiElement* Profiler::createTextArea(const String& name, Real width, Real height, Real top, Real left,
    00794                                          uint fontSize, const String& caption, bool show) {
    00795
    00796
    00797         GuiElement* textArea = GuiManager::getSingleton().createGuiElement("TextArea", name);
    00798         textArea->setMetricsMode(GMM_PIXELS);
    00799         textArea->setWidth(width);
    00800         textArea->setHeight(height);
    00801         textArea->setTop(top);
    00802         textArea->setLeft(left);
    00803         textArea->setParameter("font_name", "TrebuchetMSBold");
    00804         textArea->setParameter("char_height", StringConverter::toString(fontSize));
    00805         textArea->setCaption(caption);
    00806         textArea->setParameter("colour_top", "1 1 1");
    00807         textArea->setParameter("colour_bottom", "1 1 1");
    00808
    00809         if (show) {
    00810             textArea->show();
    00811         }
    00812         else {
    00813             textArea->hide();
    00814         }
    00815
    00816         return textArea;
    00817
    00818     }
    00819     //-----------------------------------------------------------------------
    00820     GuiElement* Profiler::createPanel(const String& name, Real width, Real height, Real top, Real left,
    00821                                       const String& materialName, bool show) {
    00822
    00823         GuiElement* panel = GuiManager::getSingleton().createGuiElement("Panel", name);
    00824         panel->setMetricsMode(GMM_PIXELS);
    00825         panel->setWidth(width);
    00826         panel->setHeight(height);
    00827         panel->setTop(top);
    00828         panel->setLeft(left);
    00829         panel->setMaterialName(materialName);
    00830
    00831         if (show) {
    00832             panel->show();
    00833         }
    00834         else {
    00835             panel->hide();
    00836         }
    00837
    00838         return panel;
    00839
    00840     }
    00841     //-----------------------------------------------------------------------
    00842
    00843 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:39 2004