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 Fri May 14 23:22:35 2004