diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/llscenemonitor.cpp | |
parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) |
Fix line endlings
Diffstat (limited to 'indra/newview/llscenemonitor.cpp')
-rw-r--r-- | indra/newview/llscenemonitor.cpp | 1514 |
1 files changed, 757 insertions, 757 deletions
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 5f7adfec90..8e45a60f86 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -1,757 +1,757 @@ -/**
- * @file llscenemonitor.cpp
- * @brief monitor the scene loading process.
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llrendertarget.h"
-#include "llscenemonitor.h"
-#include "llviewerwindow.h"
-#include "llviewerdisplay.h"
-#include "llviewercontrol.h"
-#include "llviewershadermgr.h"
-#include "llui.h"
-#include "llstartup.h"
-#include "llappviewer.h"
-#include "llwindow.h"
-#include "llpointer.h"
-#include "llspatialpartition.h"
-#include "llagent.h"
-#include "pipeline.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerpartsim.h"
-
-LLSceneMonitorView* gSceneMonitorView = NULL;
-
-//
-//The procedures of monitoring when the scene finishes loading visually,
-//i.e., no pixel differences among frames, are:
-//1, freeze all dynamic objects and avatars;
-//2, (?) disable all sky and water;
-//3, capture frames periodically, by calling "capture()";
-//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff;
-//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "calcDiffAggregate()";
-//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()";
-//END.
-//
-
-LLSceneMonitor::LLSceneMonitor() :
- mEnabled(false),
- mDiff(NULL),
- mDiffResult(0.f),
- mDiffTolerance(0.1f),
- mDiffState(WAITING_FOR_NEXT_DIFF),
- mDebugViewerVisible(false),
- mQueryObject(0),
- mDiffPixelRatio(0.5f)
-{
- mFrames[0] = NULL;
- mFrames[1] = NULL;
-}
-
-LLSceneMonitor::~LLSceneMonitor()
-{
- mDiffState = VIEWER_QUITTING;
- reset();
-
- mDitheringTexture = NULL;
-}
-
-void LLSceneMonitor::reset()
-{
- delete mFrames[0];
- delete mFrames[1];
- delete mDiff;
-
- mFrames[0] = NULL;
- mFrames[1] = NULL;
- mDiff = NULL;
-
- mMonitorRecording.reset();
- mSceneLoadRecording.reset();
- mRecordingTimer.reset();
-
- unfreezeScene();
-
- if(mQueryObject > 0)
- {
- LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(mQueryObject);
- mQueryObject = 0;
- }
-}
-
-void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height)
-{
-#if 1
- //4 * 4 matrix
- mDitherMatrixWidth = 4;
- S32 dither_matrix[4][4] =
- {
- {1, 9, 3, 11},
- {13, 5, 15, 7},
- {4, 12, 2, 10},
- {16, 8, 14, 6}
- };
-
- mDitherScale = 255.f / 17;
-#else
- //8 * 8 matrix
- mDitherMatrixWidth = 16;
- S32 dither_matrix[16][16] =
- {
- {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},
- {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},
- {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},
- {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
- {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
- {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
- {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
- {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22},
- {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},
- {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},
- {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},
- {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
- {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
- {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
- {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
- {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}
- };
-
- mDitherScale = 255.f / 65;
-#endif
-
- LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3);
- U8* data = image_raw->getData();
- for (S32 i = 0; i < mDitherMatrixWidth; i++)
- {
- for (S32 j = 0; j < mDitherMatrixWidth; j++)
- {
- U8 val = dither_matrix[i][j];
- *data++ = val;
- *data++ = val;
- *data++ = val;
- }
- }
-
- mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), false) ;
- mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP);
- mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT);
-
- mDitherScaleS = (F32)width / mDitherMatrixWidth;
- mDitherScaleT = (F32)height / mDitherMatrixWidth;
-}
-
-void LLSceneMonitor::setDebugViewerVisible(bool visible)
-{
- mDebugViewerVisible = visible;
-}
-
-LLRenderTarget& LLSceneMonitor::getCaptureTarget()
-{
- LLRenderTarget* cur_target = NULL;
-
- S32 width = gViewerWindow->getWorldViewWidthRaw();
- S32 height = gViewerWindow->getWorldViewHeightRaw();
-
- if(!mFrames[0])
- {
- mFrames[0] = new LLRenderTarget();
- mFrames[0]->allocate(width, height, GL_RGB);
- gGL.getTexUnit(0)->bind(mFrames[0]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- cur_target = mFrames[0];
- }
- else if(!mFrames[1])
- {
- mFrames[1] = new LLRenderTarget();
- mFrames[1]->allocate(width, height, GL_RGB);
- gGL.getTexUnit(0)->bind(mFrames[1]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- cur_target = mFrames[1];
- }
- else //swap
- {
- cur_target = mFrames[0];
- mFrames[0] = mFrames[1];
- mFrames[1] = cur_target;
- }
-
- if(cur_target->getWidth() != width || cur_target->getHeight() != height) //size changed
- {
- cur_target->resize(width, height);
- }
-
- // we're promising the target exists
- return *cur_target;
-}
-
-void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp)
-{
- if(mEnabled)
- {
- mAvatarPauseHandles.push_back(avatarp->requestPause());
- }
-}
-
-void LLSceneMonitor::freezeScene()
-{
- if(!mEnabled)
- {
- return;
- }
-
- //freeze all avatars
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- freezeAvatar((LLCharacter*)(*iter));
- }
-
- // freeze everything else
- gSavedSettings.setBOOL("FreezeTime", true);
-
- //disable sky, water and clouds
- gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
-
- //disable particle system
- LLViewerPartSim::getInstance()->enable(false);
-}
-
-void LLSceneMonitor::unfreezeScene()
-{
- //thaw all avatars
- mAvatarPauseHandles.clear();
-
- if(mDiffState == VIEWER_QUITTING)
- {
- return;
- }
-
- // thaw everything else
- gSavedSettings.setBOOL("FreezeTime", false);
-
- //enable sky, water and clouds
- gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
-
- //enable particle system
- LLViewerPartSim::getInstance()->enable(true);
-}
-
-void LLSceneMonitor::capture()
-{
- static U32 last_capture_frame = 0;
- static LLCachedControl<bool> monitor_enabled(gSavedSettings, "SceneLoadingMonitorEnabled");
- static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime");
- static bool force_capture = true;
-
- bool enabled = monitor_enabled || mDebugViewerVisible;
- if(mEnabled != enabled)
- {
- if(mEnabled)
- {
- mEnabled = enabled;
- unfreezeScene();
- reset();
- force_capture = true;
- }
- else
- {
- mEnabled = enabled;
- reset();
- freezeScene();
- }
- }
-
- if (mEnabled
- && (mMonitorRecording.getSum(*LLViewerCamera::getVelocityStat()) > 0.1f
- || mMonitorRecording.getSum(*LLViewerCamera::getAngularVelocityStat()) > 0.05f))
- {
- reset();
- freezeScene();
- force_capture = true;
- }
-
- if(mEnabled
- && (mRecordingTimer.getElapsedTimeF32() > scene_load_sample_time()
- || force_capture)
- && last_capture_frame != gFrameCount)
- {
- force_capture = false;
-
- mSceneLoadRecording.resume();
- mMonitorRecording.resume();
-
- last_capture_frame = gFrameCount;
-
- LLRenderTarget& cur_target = getCaptureTarget();
-
- U32 old_FBO = LLRenderTarget::sCurFBO;
-
- gGL.getTexUnit(0)->bind(&cur_target);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer.
-
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, cur_target.getWidth(), cur_target.getHeight()); //copy the content
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, old_FBO);
-
- mDiffState = NEED_DIFF;
- }
-}
-
-bool LLSceneMonitor::needsUpdate() const
-{
- return mDiffState == NEED_DIFF;
-}
-
-static LLStaticHashedString sDitherScale("dither_scale");
-static LLStaticHashedString sDitherScaleS("dither_scale_s");
-static LLStaticHashedString sDitherScaleT("dither_scale_t");
-
-void LLSceneMonitor::compare()
-{
-#ifdef LL_WINDOWS
- if(mDiffState != NEED_DIFF)
- {
- return;
- }
-
- if(!mFrames[0] || !mFrames[1])
- {
- return;
- }
- if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight())
- { //size does not match
- return;
- }
-
- mDiffState = EXECUTE_DIFF;
-
- S32 width = gViewerWindow->getWindowWidthRaw();
- S32 height = gViewerWindow->getWindowHeightRaw();
- if(!mDiff)
- {
- mDiff = new LLRenderTarget();
- mDiff->allocate(width, height, GL_RGBA);
-
- generateDitheringTexture(width, height);
- }
- else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
- {
- mDiff->resize(width, height);
- generateDitheringTexture(width, height);
- }
-
- mDiff->bindTarget();
- mDiff->clear();
-
- gTwoTextureCompareProgram.bind();
-
- gTwoTextureCompareProgram.uniform1f(sDitherScale, mDitherScale);
- gTwoTextureCompareProgram.uniform1f(sDitherScaleS, mDitherScaleS);
- gTwoTextureCompareProgram.uniform1f(sDitherScaleT, mDitherScaleT);
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->bind(mFrames[0]);
- gGL.getTexUnit(0)->activate();
-
- gGL.getTexUnit(1)->activate();
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->bind(mFrames[1]);
- gGL.getTexUnit(1)->activate();
-
- gGL.getTexUnit(2)->activate();
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->bind(mDitheringTexture);
- gGL.getTexUnit(2)->activate();
-
- gl_rect_2d_simple_tex(width, height);
-
- mDiff->flush();
-
- gTwoTextureCompareProgram.unbind();
-
- gGL.getTexUnit(0)->disable();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
- gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (!mDebugViewerVisible)
- {
- calcDiffAggregate();
- }
-#endif
-}
-
-static LLStaticHashedString sTolerance("tolerance");
-
-//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it.
-void LLSceneMonitor::calcDiffAggregate()
-{
-#ifdef LL_WINDOWS
-
- if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible)
- {
- return;
- }
-
- if(!mQueryObject)
- {
- mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName();
- }
-
- LLGLDepthTest depth(true, false, GL_ALWAYS);
- if(!mDebugViewerVisible)
- {
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- }
-
- LLGLSLShader* cur_shader = NULL;
-
- cur_shader = LLGLSLShader::sCurBoundShaderPtr;
- gOneTextureFilterProgram.bind();
- gOneTextureFilterProgram.uniform1f(sTolerance, mDiffTolerance);
-
- if(mDiffState == EXECUTE_DIFF)
- {
- glBeginQuery(GL_SAMPLES_PASSED, mQueryObject);
- }
-
- gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
-
- if(mDiffState == EXECUTE_DIFF)
- {
- glEndQuery(GL_SAMPLES_PASSED);
- mDiffState = WAIT_ON_RESULT;
- }
-
- gOneTextureFilterProgram.unbind();
-
- if(cur_shader != NULL)
- {
- cur_shader->bind();
- }
-
- if(!mDebugViewerVisible)
- {
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- }
-#endif
-}
-
-static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference");
-void LLSceneMonitor::fetchQueryResult()
-{
- // also throttle timing here, to avoid going below sample time due to phasing with frame capture
- static LLCachedControl<F32> scene_load_sample_time_control(gSavedSettings, "SceneLoadingMonitorSampleTime");
- F32Seconds scene_load_sample_time = (F32Seconds)scene_load_sample_time_control();
-
- if(mDiffState == WAIT_ON_RESULT
- && !LLAppViewer::instance()->quitRequested())
- {
- mDiffState = WAITING_FOR_NEXT_DIFF;
-
- GLuint available = 0;
- glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available);
- if(available)
- {
- GLuint count = 0;
- glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count);
-
- mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face)
-
- LL_DEBUGS("SceneMonitor") << "Frame difference: " << mDiffResult << LL_ENDL;
- record(sFramePixelDiff, mDiffResult);
-
- static LLCachedControl<F32> diff_threshold(gSavedSettings,"SceneLoadingMonitorPixelDiffThreshold");
- F32Seconds elapsed_time = mRecordingTimer.getElapsedTimeF32();
-
- if (elapsed_time > scene_load_sample_time)
- {
- if(mDiffResult > diff_threshold())
- {
- mSceneLoadRecording.extend();
- llassert_always(mSceneLoadRecording.getResults().getLastRecording().getDuration() > scene_load_sample_time);
- }
- else
- {
- mSceneLoadRecording.nextPeriod();
- }
- mRecordingTimer.reset();
- }
- }
- }
-}
-
-//dump results to a file _scene_xmonitor_results.csv
-void LLSceneMonitor::dumpToFile(const std::string &file_name)
-{
- if (!hasResults()) return;
-
- LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;
- try
- {
- llofstream os(file_name.c_str());
-
- os << std::setprecision(10);
-
- LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
- const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
-
- F64Seconds frame_time;
-
- os << "Stat";
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
- os << ", " << frame_time.value();
- }
- os << '\n';
-
- os << "Sample period(s)";
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
- os << ", " << frame_time.value();
- }
- os << '\n';
-
-
- typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
- for (auto& it : trace_count::instance_snapshot())
- {
- std::ostringstream row;
- row << std::setprecision(10);
-
- row << it.getName();
-
- const char* unit_label = it.getUnitLabel();
- if (unit_label[0])
- {
- row << "(" << unit_label << ")";
- }
-
- S32 samples = 0;
-
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(it);
- row << ", " << recording.getSum(it);
- }
-
- row << '\n';
-
- if (samples > 0)
- {
- os << row.str();
- }
- }
-
- typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
-
- for (auto& it : trace_event::instance_snapshot())
- {
- std::ostringstream row;
- row << std::setprecision(10);
- row << it.getName();
-
- const char* unit_label = it.getUnitLabel();
- if (unit_label[0])
- {
- row << "(" << unit_label << ")";
- }
-
- S32 samples = 0;
-
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(it);
- F64 mean = recording.getMean(it);
- if (llisnan(mean))
- {
- row << ", n/a";
- }
- else
- {
- row << ", " << mean;
- }
- }
-
- row << '\n';
-
- if (samples > 0)
- {
- os << row.str();
- }
- }
-
- typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
-
- for (auto& it : trace_sample::instance_snapshot())
- {
- std::ostringstream row;
- row << std::setprecision(10);
- row << it.getName();
-
- const char* unit_label = it.getUnitLabel();
- if (unit_label[0])
- {
- row << "(" << unit_label << ")";
- }
-
- S32 samples = 0;
-
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(it);
- F64 mean = recording.getMean(it);
- if (llisnan(mean))
- {
- row << ", n/a";
- }
- else
- {
- row << ", " << mean;
- }
- }
-
- row << '\n';
-
- if (samples > 0)
- {
- os << row.str();
- }
- }
-
- os.flush();
- os.close();
- }
- catch (const std::ios_base::failure &e)
- {
- LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL;
- }
-}
-
-//-------------------------------------------------------------------------------------------------------------
-//definition of class LLSceneMonitorView
-//-------------------------------------------------------------------------------------------------------------
-LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect)
- : LLFloater(LLSD())
-{
- setRect(rect);
- setVisible(false);
-
- setCanMinimize(false);
- setCanClose(true);
-
- sTeleportFinishConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLSceneMonitorView::onTeleportFinished, this));
-}
-
-LLSceneMonitorView::~LLSceneMonitorView()
-{
- sTeleportFinishConnection.disconnect();
-}
-
-void LLSceneMonitorView::onClose(bool app_quitting)
-{
- setVisible(false);
-}
-
-void LLSceneMonitorView::onClickCloseBtn(bool app_quitting)
-{
- setVisible(false);
-}
-
-void LLSceneMonitorView::onTeleportFinished()
-{
- if(isInVisibleChain())
- {
- LLSceneMonitor::getInstance()->reset();
- }
-}
-
-void LLSceneMonitorView::onVisibilityChange(bool visible)
-{
- LLSceneMonitor::getInstance()->setDebugViewerVisible(visible);
-}
-
-void LLSceneMonitorView::draw()
-{
- const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget();
- if(!target)
- {
- return;
- }
-
- F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio();
- S32 height = (S32)(target->getHeight() * ratio);
- S32 width = (S32)(target->getWidth() * ratio);
-
- LLRect new_rect;
- new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
- setRect(new_rect);
-
- //draw background
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
-
- LLSceneMonitor::getInstance()->calcDiffAggregate();
-
- //show some texts
- LLColor4 color = LLColor4::white;
- S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
-
- S32 lines = 0;
- std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult());
- LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
- lines++;
-
- num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance());
- LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
- lines++;
-
- num_str = llformat("Sampling time: %.3f seconds", gSavedSettings.getF32("SceneLoadingMonitorSampleTime"));
- LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
- lines++;
-
- num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getResults().getDuration().value());
- LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
- lines++;
-
- LLView::draw();
-}
-
+/** + * @file llscenemonitor.cpp + * @brief monitor the scene loading process. + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llrendertarget.h" +#include "llscenemonitor.h" +#include "llviewerwindow.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewershadermgr.h" +#include "llui.h" +#include "llstartup.h" +#include "llappviewer.h" +#include "llwindow.h" +#include "llpointer.h" +#include "llspatialpartition.h" +#include "llagent.h" +#include "pipeline.h" +#include "llviewerparcelmgr.h" +#include "llviewerpartsim.h" + +LLSceneMonitorView* gSceneMonitorView = NULL; + +// +//The procedures of monitoring when the scene finishes loading visually, +//i.e., no pixel differences among frames, are: +//1, freeze all dynamic objects and avatars; +//2, (?) disable all sky and water; +//3, capture frames periodically, by calling "capture()"; +//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff; +//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "calcDiffAggregate()"; +//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()"; +//END. +// + +LLSceneMonitor::LLSceneMonitor() : + mEnabled(false), + mDiff(NULL), + mDiffResult(0.f), + mDiffTolerance(0.1f), + mDiffState(WAITING_FOR_NEXT_DIFF), + mDebugViewerVisible(false), + mQueryObject(0), + mDiffPixelRatio(0.5f) +{ + mFrames[0] = NULL; + mFrames[1] = NULL; +} + +LLSceneMonitor::~LLSceneMonitor() +{ + mDiffState = VIEWER_QUITTING; + reset(); + + mDitheringTexture = NULL; +} + +void LLSceneMonitor::reset() +{ + delete mFrames[0]; + delete mFrames[1]; + delete mDiff; + + mFrames[0] = NULL; + mFrames[1] = NULL; + mDiff = NULL; + + mMonitorRecording.reset(); + mSceneLoadRecording.reset(); + mRecordingTimer.reset(); + + unfreezeScene(); + + if(mQueryObject > 0) + { + LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(mQueryObject); + mQueryObject = 0; + } +} + +void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height) +{ +#if 1 + //4 * 4 matrix + mDitherMatrixWidth = 4; + S32 dither_matrix[4][4] = + { + {1, 9, 3, 11}, + {13, 5, 15, 7}, + {4, 12, 2, 10}, + {16, 8, 14, 6} + }; + + mDitherScale = 255.f / 17; +#else + //8 * 8 matrix + mDitherMatrixWidth = 16; + S32 dither_matrix[16][16] = + { + {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, + {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, + {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, + {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, + {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, + {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, + {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, + {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}, + {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, + {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, + {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, + {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, + {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, + {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, + {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, + {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22} + }; + + mDitherScale = 255.f / 65; +#endif + + LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3); + U8* data = image_raw->getData(); + for (S32 i = 0; i < mDitherMatrixWidth; i++) + { + for (S32 j = 0; j < mDitherMatrixWidth; j++) + { + U8 val = dither_matrix[i][j]; + *data++ = val; + *data++ = val; + *data++ = val; + } + } + + mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), false) ; + mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP); + mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT); + + mDitherScaleS = (F32)width / mDitherMatrixWidth; + mDitherScaleT = (F32)height / mDitherMatrixWidth; +} + +void LLSceneMonitor::setDebugViewerVisible(bool visible) +{ + mDebugViewerVisible = visible; +} + +LLRenderTarget& LLSceneMonitor::getCaptureTarget() +{ + LLRenderTarget* cur_target = NULL; + + S32 width = gViewerWindow->getWorldViewWidthRaw(); + S32 height = gViewerWindow->getWorldViewHeightRaw(); + + if(!mFrames[0]) + { + mFrames[0] = new LLRenderTarget(); + mFrames[0]->allocate(width, height, GL_RGB); + gGL.getTexUnit(0)->bind(mFrames[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + cur_target = mFrames[0]; + } + else if(!mFrames[1]) + { + mFrames[1] = new LLRenderTarget(); + mFrames[1]->allocate(width, height, GL_RGB); + gGL.getTexUnit(0)->bind(mFrames[1]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + cur_target = mFrames[1]; + } + else //swap + { + cur_target = mFrames[0]; + mFrames[0] = mFrames[1]; + mFrames[1] = cur_target; + } + + if(cur_target->getWidth() != width || cur_target->getHeight() != height) //size changed + { + cur_target->resize(width, height); + } + + // we're promising the target exists + return *cur_target; +} + +void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp) +{ + if(mEnabled) + { + mAvatarPauseHandles.push_back(avatarp->requestPause()); + } +} + +void LLSceneMonitor::freezeScene() +{ + if(!mEnabled) + { + return; + } + + //freeze all avatars + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + freezeAvatar((LLCharacter*)(*iter)); + } + + // freeze everything else + gSavedSettings.setBOOL("FreezeTime", true); + + //disable sky, water and clouds + gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + + //disable particle system + LLViewerPartSim::getInstance()->enable(false); +} + +void LLSceneMonitor::unfreezeScene() +{ + //thaw all avatars + mAvatarPauseHandles.clear(); + + if(mDiffState == VIEWER_QUITTING) + { + return; + } + + // thaw everything else + gSavedSettings.setBOOL("FreezeTime", false); + + //enable sky, water and clouds + gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + + //enable particle system + LLViewerPartSim::getInstance()->enable(true); +} + +void LLSceneMonitor::capture() +{ + static U32 last_capture_frame = 0; + static LLCachedControl<bool> monitor_enabled(gSavedSettings, "SceneLoadingMonitorEnabled"); + static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime"); + static bool force_capture = true; + + bool enabled = monitor_enabled || mDebugViewerVisible; + if(mEnabled != enabled) + { + if(mEnabled) + { + mEnabled = enabled; + unfreezeScene(); + reset(); + force_capture = true; + } + else + { + mEnabled = enabled; + reset(); + freezeScene(); + } + } + + if (mEnabled + && (mMonitorRecording.getSum(*LLViewerCamera::getVelocityStat()) > 0.1f + || mMonitorRecording.getSum(*LLViewerCamera::getAngularVelocityStat()) > 0.05f)) + { + reset(); + freezeScene(); + force_capture = true; + } + + if(mEnabled + && (mRecordingTimer.getElapsedTimeF32() > scene_load_sample_time() + || force_capture) + && last_capture_frame != gFrameCount) + { + force_capture = false; + + mSceneLoadRecording.resume(); + mMonitorRecording.resume(); + + last_capture_frame = gFrameCount; + + LLRenderTarget& cur_target = getCaptureTarget(); + + U32 old_FBO = LLRenderTarget::sCurFBO; + + gGL.getTexUnit(0)->bind(&cur_target); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer. + + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, cur_target.getWidth(), cur_target.getHeight()); //copy the content + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, old_FBO); + + mDiffState = NEED_DIFF; + } +} + +bool LLSceneMonitor::needsUpdate() const +{ + return mDiffState == NEED_DIFF; +} + +static LLStaticHashedString sDitherScale("dither_scale"); +static LLStaticHashedString sDitherScaleS("dither_scale_s"); +static LLStaticHashedString sDitherScaleT("dither_scale_t"); + +void LLSceneMonitor::compare() +{ +#ifdef LL_WINDOWS + if(mDiffState != NEED_DIFF) + { + return; + } + + if(!mFrames[0] || !mFrames[1]) + { + return; + } + if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight()) + { //size does not match + return; + } + + mDiffState = EXECUTE_DIFF; + + S32 width = gViewerWindow->getWindowWidthRaw(); + S32 height = gViewerWindow->getWindowHeightRaw(); + if(!mDiff) + { + mDiff = new LLRenderTarget(); + mDiff->allocate(width, height, GL_RGBA); + + generateDitheringTexture(width, height); + } + else if(mDiff->getWidth() != width || mDiff->getHeight() != height) + { + mDiff->resize(width, height); + generateDitheringTexture(width, height); + } + + mDiff->bindTarget(); + mDiff->clear(); + + gTwoTextureCompareProgram.bind(); + + gTwoTextureCompareProgram.uniform1f(sDitherScale, mDitherScale); + gTwoTextureCompareProgram.uniform1f(sDitherScaleS, mDitherScaleS); + gTwoTextureCompareProgram.uniform1f(sDitherScaleT, mDitherScaleT); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->bind(mFrames[0]); + gGL.getTexUnit(0)->activate(); + + gGL.getTexUnit(1)->activate(); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->bind(mFrames[1]); + gGL.getTexUnit(1)->activate(); + + gGL.getTexUnit(2)->activate(); + gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->bind(mDitheringTexture); + gGL.getTexUnit(2)->activate(); + + gl_rect_2d_simple_tex(width, height); + + mDiff->flush(); + + gTwoTextureCompareProgram.unbind(); + + gGL.getTexUnit(0)->disable(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(2)->disable(); + gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); + + if (!mDebugViewerVisible) + { + calcDiffAggregate(); + } +#endif +} + +static LLStaticHashedString sTolerance("tolerance"); + +//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it. +void LLSceneMonitor::calcDiffAggregate() +{ +#ifdef LL_WINDOWS + + if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible) + { + return; + } + + if(!mQueryObject) + { + mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName(); + } + + LLGLDepthTest depth(true, false, GL_ALWAYS); + if(!mDebugViewerVisible) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + LLGLSLShader* cur_shader = NULL; + + cur_shader = LLGLSLShader::sCurBoundShaderPtr; + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1f(sTolerance, mDiffTolerance); + + if(mDiffState == EXECUTE_DIFF) + { + glBeginQuery(GL_SAMPLES_PASSED, mQueryObject); + } + + gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); + + if(mDiffState == EXECUTE_DIFF) + { + glEndQuery(GL_SAMPLES_PASSED); + mDiffState = WAIT_ON_RESULT; + } + + gOneTextureFilterProgram.unbind(); + + if(cur_shader != NULL) + { + cur_shader->bind(); + } + + if(!mDebugViewerVisible) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } +#endif +} + +static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference"); +void LLSceneMonitor::fetchQueryResult() +{ + // also throttle timing here, to avoid going below sample time due to phasing with frame capture + static LLCachedControl<F32> scene_load_sample_time_control(gSavedSettings, "SceneLoadingMonitorSampleTime"); + F32Seconds scene_load_sample_time = (F32Seconds)scene_load_sample_time_control(); + + if(mDiffState == WAIT_ON_RESULT + && !LLAppViewer::instance()->quitRequested()) + { + mDiffState = WAITING_FOR_NEXT_DIFF; + + GLuint available = 0; + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available); + if(available) + { + GLuint count = 0; + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count); + + mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face) + + LL_DEBUGS("SceneMonitor") << "Frame difference: " << mDiffResult << LL_ENDL; + record(sFramePixelDiff, mDiffResult); + + static LLCachedControl<F32> diff_threshold(gSavedSettings,"SceneLoadingMonitorPixelDiffThreshold"); + F32Seconds elapsed_time = mRecordingTimer.getElapsedTimeF32(); + + if (elapsed_time > scene_load_sample_time) + { + if(mDiffResult > diff_threshold()) + { + mSceneLoadRecording.extend(); + llassert_always(mSceneLoadRecording.getResults().getLastRecording().getDuration() > scene_load_sample_time); + } + else + { + mSceneLoadRecording.nextPeriod(); + } + mRecordingTimer.reset(); + } + } + } +} + +//dump results to a file _scene_xmonitor_results.csv +void LLSceneMonitor::dumpToFile(const std::string &file_name) +{ + if (!hasResults()) return; + + LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; + try + { + llofstream os(file_name.c_str()); + + os << std::setprecision(10); + + LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); + const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); + + F64Seconds frame_time; + + os << "Stat"; + for (S32 frame = 1; frame <= frame_count; frame++) + { + frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); + } + os << '\n'; + + os << "Sample period(s)"; + for (S32 frame = 1; frame <= frame_count; frame++) + { + frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); + } + os << '\n'; + + + typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count; + for (auto& it : trace_count::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + row << ", " << recording.getSum(it); + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event; + + for (auto& it : trace_event::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample; + + for (auto& it : trace_sample::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + os.flush(); + os.close(); + } + catch (const std::ios_base::failure &e) + { + LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL; + } +} + +//------------------------------------------------------------------------------------------------------------- +//definition of class LLSceneMonitorView +//------------------------------------------------------------------------------------------------------------- +LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect) + : LLFloater(LLSD()) +{ + setRect(rect); + setVisible(false); + + setCanMinimize(false); + setCanClose(true); + + sTeleportFinishConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLSceneMonitorView::onTeleportFinished, this)); +} + +LLSceneMonitorView::~LLSceneMonitorView() +{ + sTeleportFinishConnection.disconnect(); +} + +void LLSceneMonitorView::onClose(bool app_quitting) +{ + setVisible(false); +} + +void LLSceneMonitorView::onClickCloseBtn(bool app_quitting) +{ + setVisible(false); +} + +void LLSceneMonitorView::onTeleportFinished() +{ + if(isInVisibleChain()) + { + LLSceneMonitor::getInstance()->reset(); + } +} + +void LLSceneMonitorView::onVisibilityChange(bool visible) +{ + LLSceneMonitor::getInstance()->setDebugViewerVisible(visible); +} + +void LLSceneMonitorView::draw() +{ + const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget(); + if(!target) + { + return; + } + + F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio(); + S32 height = (S32)(target->getHeight() * ratio); + S32 width = (S32)(target->getWidth() * ratio); + + LLRect new_rect; + new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); + setRect(new_rect); + + //draw background + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + + LLSceneMonitor::getInstance()->calcDiffAggregate(); + + //show some texts + LLColor4 color = LLColor4::white; + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); + + S32 lines = 0; + std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Sampling time: %.3f seconds", gSavedSettings.getF32("SceneLoadingMonitorSampleTime")); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getResults().getDuration().value()); + LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); + lines++; + + LLView::draw(); +} + |