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

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:22 2004