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