mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 00:56:48 +02:00
Start on refactoring of bandwidth metrics
This commit is contained in:
parent
8a32bd2eed
commit
f0edba9a6b
15 changed files with 110 additions and 421 deletions
|
@ -774,19 +774,18 @@ void Application::controlledBroadcastToNodes(const QByteArray& packet, const Nod
|
|||
int nReceivingNodes = DependencyManager::get<NodeList>()->broadcastToNodes(packet, NodeSet() << type);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)
|
||||
BandwidthMeter::ChannelIndex channel;
|
||||
double bandwidth_amount = nReceivingNodes * packet.size();
|
||||
switch (type) {
|
||||
case NodeType::Agent:
|
||||
case NodeType::AvatarMixer:
|
||||
channel = BandwidthMeter::AVATARS;
|
||||
_bandwidthRecorder.avatarsChannel->output.updateValue(bandwidth_amount);
|
||||
break;
|
||||
case NodeType::EntityServer:
|
||||
channel = BandwidthMeter::OCTREE;
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(bandwidth_amount);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * packet.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1261,7 +1260,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
|
|||
int horizontalOffset = MIRROR_VIEW_WIDTH;
|
||||
Stats::getInstance()->checkClick(getMouseX(), getMouseY(),
|
||||
getMouseDragStartedX(), getMouseDragStartedY(), horizontalOffset);
|
||||
checkBandwidthMeterClick();
|
||||
}
|
||||
|
||||
// fire an action end event
|
||||
|
@ -1448,23 +1446,6 @@ void Application::idle() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::checkBandwidthMeterClick() {
|
||||
// ... to be called upon button release
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::UserInterface) &&
|
||||
glm::compMax(glm::abs(glm::ivec2(getMouseX() - getMouseDragStartedX(),
|
||||
getMouseY() - getMouseDragStartedY())))
|
||||
<= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH
|
||||
&& _bandwidthMeter.isWithinArea(getMouseX(), getMouseY(), glCanvas->width(), glCanvas->height())) {
|
||||
|
||||
// The bandwidth meter is visible, the click didn't get dragged too far and
|
||||
// we actually hit the bandwidth meter
|
||||
DependencyManager::get<DialogsManager>()->bandwidthDetails();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::setFullscreen(bool fullscreen) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen) != fullscreen) {
|
||||
Menu::getInstance()->getActionForOption(MenuOption::Fullscreen)->setChecked(fullscreen);
|
||||
|
@ -2398,7 +2379,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||
_bandwidthMeter.outputStream(BandwidthMeter::OCTREE).updateValue(packetLength);
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(packetLength);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3387,7 +3368,7 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
|
|||
}
|
||||
|
||||
void Application::packetSent(quint64 length) {
|
||||
_bandwidthMeter.outputStream(BandwidthMeter::OCTREE).updateValue(length);
|
||||
_bandwidthRecorder.octreeChannel->output.updateValue(length);
|
||||
}
|
||||
|
||||
const QString SETTINGS_KEY = "Settings";
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "devices/SixenseManager.h"
|
||||
#include "scripting/ControllerScriptingInterface.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
#include "ui/BandwidthMeter.h"
|
||||
#include "ui/HMDToolsDialog.h"
|
||||
#include "ui/ModelsBrowser.h"
|
||||
#include "ui/NodeBounds.h"
|
||||
|
@ -183,6 +182,7 @@ public:
|
|||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() { return _window; }
|
||||
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
||||
BandwidthRecorder* getBandwidthRecorder() { return &_bandwidthRecorder; }
|
||||
|
||||
EntityTree* getEntityClipboard() { return &_entityClipboard; }
|
||||
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
|
||||
|
@ -204,7 +204,6 @@ public:
|
|||
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
|
||||
|
||||
FaceTracker* getActiveFaceTracker();
|
||||
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
||||
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
|
||||
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
|
||||
Overlays& getOverlays() { return _overlays; }
|
||||
|
@ -435,7 +434,6 @@ private:
|
|||
|
||||
void updateShadowMap();
|
||||
void renderRearViewMirror(const QRect& region, bool billboard = false);
|
||||
void checkBandwidthMeterClick();
|
||||
void setMenuShortcutsEnabled(bool enabled);
|
||||
|
||||
static void attachNewHeadToNode(Node *newNode);
|
||||
|
@ -448,7 +446,6 @@ private:
|
|||
|
||||
ToolWindow* _toolWindow;
|
||||
|
||||
BandwidthMeter _bandwidthMeter;
|
||||
|
||||
QThread* _nodeThread;
|
||||
DatagramProcessor _datagramProcessor;
|
||||
|
@ -486,6 +483,9 @@ private:
|
|||
|
||||
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
||||
|
||||
BandwidthRecorder _bandwidthRecorder;
|
||||
|
||||
|
||||
AvatarManager _avatarManager;
|
||||
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
|
||||
|
||||
|
|
|
@ -769,8 +769,9 @@ void Audio::handleAudioInput() {
|
|||
nodeList->writeDatagram(audioDataPacket, packetBytes, audioMixer);
|
||||
_outgoingAvatarAudioSequenceNumber++;
|
||||
|
||||
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
|
||||
.updateValue(packetBytes);
|
||||
// Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO).updateValue(packetBytes);
|
||||
Application::getInstance()->
|
||||
getBandwidthRecorder()->audioChannel->output.updateValue(packetBytes);
|
||||
}
|
||||
delete[] inputAudioSamples;
|
||||
}
|
||||
|
@ -829,7 +830,10 @@ void Audio::addReceivedAudioToStream(const QByteArray& audioByteArray) {
|
|||
_receivedAudioStream.parseData(audioByteArray);
|
||||
}
|
||||
|
||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size());
|
||||
// Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size());
|
||||
Application::getInstance()->
|
||||
getBandwidthRecorder()->audioChannel->input.updateValue(audioByteArray.size());
|
||||
|
||||
}
|
||||
|
||||
void Audio::parseAudioEnvironmentData(const QByteArray &packet) {
|
||||
|
|
|
@ -117,7 +117,7 @@ void DatagramProcessor::processDatagrams() {
|
|||
Q_ARG(const QWeakPointer<Node>&, avatarMixer));
|
||||
}
|
||||
|
||||
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(incomingPacket.size());
|
||||
application->_bandwidthRecorder.avatarsChannel->input.updateValue(incomingPacket.size());
|
||||
break;
|
||||
}
|
||||
case PacketTypeDomainConnectionDenied: {
|
||||
|
|
|
@ -282,7 +282,6 @@ Menu::Menu() {
|
|||
addDisabledActionAndSeparator(viewMenu, "Stats");
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Percent);
|
||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, qApp, SLOT(toggleLogDialog()));
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true);
|
||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0,
|
||||
dialogsManager.data(), SLOT(bandwidthDetails()));
|
||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0,
|
||||
|
|
|
@ -120,7 +120,6 @@ namespace MenuOption {
|
|||
const QString AudioSourcePinkNoise = "Pink Noise";
|
||||
const QString AudioSourceSine440 = "Sine 440hz";
|
||||
const QString Avatars = "Avatars";
|
||||
const QString Bandwidth = "Bandwidth Display";
|
||||
const QString BandwidthDetails = "Bandwidth Details";
|
||||
const QString BlueSpeechSphere = "Blue Sphere While Speaking";
|
||||
const QString BookmarkLocation = "Bookmark Location";
|
||||
|
|
|
@ -899,7 +899,7 @@ int MetavoxelSystemClient::parseData(const QByteArray& packet) {
|
|||
} else {
|
||||
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
|
||||
}
|
||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size());
|
||||
Application::getInstance()->getBandwidthRecorder()->metavoxelsChannel->input.updateValue (packet.size());
|
||||
}
|
||||
return packet.size();
|
||||
}
|
||||
|
@ -1015,7 +1015,7 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
|
|||
} else {
|
||||
DependencyManager::get<NodeList>()->writeDatagram(data, _node);
|
||||
}
|
||||
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
|
||||
Application::getInstance()->getBandwidthRecorder()->metavoxelsChannel->output.updateValue (data.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -909,7 +909,6 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
|||
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor();
|
||||
BandwidthMeter* bandwidthMeter = application->getBandwidthMeter();
|
||||
NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay();
|
||||
|
||||
// Display stats and log text onscreen
|
||||
|
@ -923,11 +922,6 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
|||
// Onscreen text about position, servers, etc
|
||||
Stats::getInstance()->display(WHITE_TEXT, horizontalOffset, application->getFps(),
|
||||
application->getPacketsPerSecond(), application->getBytesPerSecond(), voxelPacketsToProcess);
|
||||
// Bandwidth meter
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {
|
||||
Stats::drawBackground(0x33333399, glCanvas->width() - 296, glCanvas->height() - 68, 296, 68);
|
||||
bandwidthMeter->render(glCanvas->width(), glCanvas->height());
|
||||
}
|
||||
}
|
||||
|
||||
// Show on-screen msec timer
|
||||
|
@ -936,8 +930,7 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
|||
quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
|
||||
sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));
|
||||
int timerBottom =
|
||||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
|
||||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats))
|
||||
? 80 : 20;
|
||||
drawText(glCanvas->width() - 100, glCanvas->height() - timerBottom,
|
||||
0.30f, 0.0f, 0, frameTimer, WHITE_TEXT);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BandwidthRecorder.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
|
||||
#include <QFormLayout>
|
||||
|
@ -19,56 +20,75 @@
|
|||
#include <QPalette>
|
||||
#include <QColor>
|
||||
|
||||
BandwidthDialog::BandwidthDialog(QWidget* parent, BandwidthMeter* model) :
|
||||
|
||||
BandwidthDialog::ChannelDisplay::ChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form) {
|
||||
this->ch = ch;
|
||||
this->input_label = setupLabel(form, "input");
|
||||
this->output_label = setupLabel(form, "output");
|
||||
}
|
||||
|
||||
|
||||
QLabel* BandwidthDialog::ChannelDisplay::setupLabel(QFormLayout* form, std::string i_or_o) {
|
||||
QLabel* label = new QLabel();
|
||||
char strBuf[64];
|
||||
|
||||
label->setAlignment(Qt::AlignRight);
|
||||
|
||||
QPalette palette = label->palette();
|
||||
unsigned rgb = ch->colorRGBA >> 8;
|
||||
rgb = ((rgb & 0xfefefeu) >> 1) + ((rgb & 0xf8f8f8) >> 3);
|
||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
|
||||
|
||||
label->setPalette(palette);
|
||||
|
||||
snprintf(strBuf, sizeof(strBuf), " %s %s Bandwidth:", i_or_o.c_str(), ch->caption);
|
||||
form->addRow(strBuf, label);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BandwidthDialog::ChannelDisplay::setLabelText() {
|
||||
char strBuf[64];
|
||||
snprintf(strBuf, sizeof(strBuf), "%0.0f %s", ch->input.getValue() * ch->unitScale, ch->unitCaption);
|
||||
input_label->setText(strBuf);
|
||||
snprintf(strBuf, sizeof(strBuf), "%0.0f %s", ch->output.getValue() * ch->unitScale, ch->unitCaption);
|
||||
output_label->setText(strBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BandwidthDialog::BandwidthDialog(QWidget* parent, BandwidthRecorder* model) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
|
||||
_model(model) {
|
||||
|
||||
char strBuf[64];
|
||||
|
||||
this->setWindowTitle("Bandwidth Details");
|
||||
|
||||
// Create layouter
|
||||
QFormLayout* form = new QFormLayout();
|
||||
this->QDialog::setLayout(form);
|
||||
|
||||
// Setup labels
|
||||
for (size_t i = 0; i < BandwidthMeter::N_STREAMS; ++i) {
|
||||
bool input = i % 2 == 0;
|
||||
BandwidthMeter::ChannelInfo& ch = _model->channelInfo(BandwidthMeter::ChannelIndex(i / 2));
|
||||
QLabel* label = _labels[i] = new QLabel();
|
||||
label->setAlignment(Qt::AlignRight);
|
||||
|
||||
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
|
||||
QPalette palette = label->palette();
|
||||
unsigned rgb = ch.colorRGBA >> 8;
|
||||
rgb = ((rgb & 0xfefefeu) >> 1) + ((rgb & 0xf8f8f8) >> 3);
|
||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
|
||||
label->setPalette(palette);
|
||||
|
||||
snprintf(strBuf, sizeof(strBuf), " %s %s Bandwidth:", input ? "Input" : "Output", ch.caption);
|
||||
form->addRow(strBuf, label);
|
||||
}
|
||||
audioChannelDisplay = new ChannelDisplay(_model->audioChannel, form);
|
||||
avatarsChannelDisplay = new ChannelDisplay(_model->avatarsChannel, form);
|
||||
octreeChannelDisplay = new ChannelDisplay(_model->octreeChannel, form);
|
||||
metavoxelsChannelDisplay = new ChannelDisplay(_model->metavoxelsChannel, form);
|
||||
}
|
||||
|
||||
|
||||
BandwidthDialog::~BandwidthDialog() {
|
||||
for (size_t i = 0; i < BandwidthMeter::N_STREAMS; ++i) {
|
||||
delete _labels[i];
|
||||
}
|
||||
delete audioChannelDisplay;
|
||||
delete avatarsChannelDisplay;
|
||||
delete octreeChannelDisplay;
|
||||
delete metavoxelsChannelDisplay;
|
||||
}
|
||||
|
||||
void BandwidthDialog::paintEvent(QPaintEvent* event) {
|
||||
|
||||
// Update labels
|
||||
char strBuf[64];
|
||||
for (size_t i = 0; i < BandwidthMeter::N_STREAMS; ++i) {
|
||||
BandwidthMeter::ChannelIndex chIdx = BandwidthMeter::ChannelIndex(i / 2);
|
||||
bool input = i % 2 == 0;
|
||||
BandwidthMeter::ChannelInfo& ch = _model->channelInfo(chIdx);
|
||||
BandwidthMeter::Stream& s = input ? _model->inputStream(chIdx) : _model->outputStream(chIdx);
|
||||
QLabel* label = _labels[i];
|
||||
snprintf(strBuf, sizeof(strBuf), "%0.2f %s", s.getValue() * ch.unitScale, ch.unitCaption);
|
||||
label->setText(strBuf);
|
||||
}
|
||||
void BandwidthDialog::paintEvent(QPaintEvent* event) {
|
||||
audioChannelDisplay->setLabelText();
|
||||
avatarsChannelDisplay->setLabelText();
|
||||
octreeChannelDisplay->setLabelText();
|
||||
metavoxelsChannelDisplay->setLabelText();
|
||||
|
||||
this->QDialog::paintEvent(event);
|
||||
this->setFixedSize(this->width(), this->height());
|
||||
|
|
|
@ -14,17 +14,36 @@
|
|||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QFormLayout>
|
||||
|
||||
#include "BandwidthMeter.h"
|
||||
#include "BandwidthRecorder.h"
|
||||
|
||||
|
||||
class BandwidthDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Sets up the UI based on the configuration of the BandwidthMeter
|
||||
BandwidthDialog(QWidget* parent, BandwidthMeter* model);
|
||||
// Sets up the UI based on the configuration of the BandwidthRecorder
|
||||
BandwidthDialog(QWidget* parent, BandwidthRecorder* model);
|
||||
~BandwidthDialog();
|
||||
|
||||
class ChannelDisplay {
|
||||
public:
|
||||
ChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form);
|
||||
QLabel* setupLabel(QFormLayout* form, std::string i_or_o);
|
||||
void setLabelText();
|
||||
|
||||
private:
|
||||
BandwidthRecorder::Channel *ch;
|
||||
|
||||
QLabel* input_label;
|
||||
QLabel* output_label;
|
||||
};
|
||||
|
||||
ChannelDisplay* audioChannelDisplay;
|
||||
ChannelDisplay* avatarsChannelDisplay;
|
||||
ChannelDisplay* octreeChannelDisplay;
|
||||
ChannelDisplay* metavoxelsChannelDisplay;
|
||||
|
||||
signals:
|
||||
|
||||
void closed();
|
||||
|
@ -34,16 +53,13 @@ public slots:
|
|||
void reject();
|
||||
|
||||
protected:
|
||||
|
||||
// State <- data model held by BandwidthMeter
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
// Emits a 'closed' signal when this dialog is closed.
|
||||
void closeEvent(QCloseEvent*);
|
||||
|
||||
private:
|
||||
BandwidthMeter* _model;
|
||||
QLabel* _labels[BandwidthMeter::N_STREAMS];
|
||||
BandwidthRecorder* _model;
|
||||
};
|
||||
|
||||
#endif // hifi_BandwidthDialog_h
|
||||
|
|
|
@ -1,243 +0,0 @@
|
|||
//
|
||||
// BandwidthMeter.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Tobias Schwinger on 6/20/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
|
||||
#include "BandwidthMeter.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
namespace { // .cpp-local
|
||||
|
||||
int const AREA_WIDTH = -280; // Width of the area used. Aligned to the right when negative.
|
||||
int const AREA_HEIGHT = -40; // Height of the area used. Aligned to the bottom when negative.
|
||||
int const BORDER_DISTANCE_HORIZ = -10; // Distance to edge of screen (use negative value when width is negative).
|
||||
int const BORDER_DISTANCE_VERT = -15; // Distance to edge of screen (use negative value when height is negative).
|
||||
|
||||
int SPACING_VERT_BARS = 2; // Vertical distance between input and output bar
|
||||
int SPACING_RIGHT_CAPTION_IN_OUT = 4; // IN/OUT <--> |######## : |
|
||||
int SPACING_LEFT_CAPTION_UNIT = 4; // |######## : | <--> UNIT
|
||||
int PADDING_HORIZ_VALUE = 2; // |<-->X.XX<:-># |
|
||||
|
||||
unsigned const COLOR_TEXT = 0xedededff; // ^ ^ ^ ^ ^ ^
|
||||
unsigned const COLOR_FRAME = 0xe0e0e0b0; // | | |
|
||||
unsigned const COLOR_INDICATOR = 0xc0c0c0b0; // |
|
||||
|
||||
char const* CAPTION_IN = "In";
|
||||
char const* CAPTION_OUT = "Out";
|
||||
char const* CAPTION_UNIT = "Mbps";
|
||||
|
||||
double const UNIT_SCALE = 8000.0 / (1024.0 * 1024.0); // Bytes/ms -> Mbps
|
||||
int const INITIAL_SCALE_MAXIMUM_INDEX = 250; // / 9: exponent, % 9: mantissa - 2, 0 o--o 2 * 10^-10
|
||||
int const MIN_METER_SCALE = 10; // 10Mbps
|
||||
int const NUMBER_OF_MARKERS = 10;
|
||||
}
|
||||
|
||||
BandwidthMeter::ChannelInfo BandwidthMeter::_CHANNELS[] = {
|
||||
{ "Audio" , "Kbps", 8000.0 / 1024.0, 0x33cc99ff },
|
||||
{ "Avatars" , "Kbps", 8000.0 / 1024.0, 0xffef40c0 },
|
||||
{ "Octree" , "Kbps", 8000.0 / 1024.0, 0xd0d0d0a0 },
|
||||
{ "Metavoxels", "Kbps", 8000.0 / 1024.0, 0xd0d0d0a0 }
|
||||
};
|
||||
|
||||
BandwidthMeter::BandwidthMeter() :
|
||||
_textRenderer(TextRenderer::getInstance(INCONSOLATA_FONT_FAMILY, -1, INCONSOLATA_FONT_WEIGHT, false)),
|
||||
_scaleMaxIndex(INITIAL_SCALE_MAXIMUM_INDEX) {
|
||||
|
||||
_channels = static_cast<ChannelInfo*>( malloc(sizeof(_CHANNELS)) );
|
||||
memcpy(_channels, _CHANNELS, sizeof(_CHANNELS));
|
||||
}
|
||||
|
||||
BandwidthMeter::~BandwidthMeter() {
|
||||
|
||||
free(_channels);
|
||||
}
|
||||
|
||||
BandwidthMeter::Stream::Stream(float msToAverage) : _value(0.0f), _msToAverage(msToAverage) {
|
||||
_prevTime.start();
|
||||
}
|
||||
|
||||
void BandwidthMeter::Stream::updateValue(double amount) {
|
||||
|
||||
// Determine elapsed time
|
||||
double dt = (double)_prevTime.nsecsElapsed() / 1000000.0; // ns to ms
|
||||
|
||||
// Ignore this value when timer imprecision yields dt = 0
|
||||
if (dt == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_prevTime.start();
|
||||
|
||||
// Compute approximate average
|
||||
_value = glm::mix(_value, amount / dt,
|
||||
glm::clamp(dt / _msToAverage, 0.0, 1.0));
|
||||
}
|
||||
|
||||
void BandwidthMeter::setColorRGBA(unsigned c) {
|
||||
|
||||
glColor4ub(GLubyte( c >> 24),
|
||||
GLubyte((c >> 16) & 0xff),
|
||||
GLubyte((c >> 8) & 0xff),
|
||||
GLubyte( c & 0xff));
|
||||
}
|
||||
|
||||
void BandwidthMeter::renderBox(int x, int y, int w, int h) {
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(x, y, w, h);
|
||||
}
|
||||
|
||||
void BandwidthMeter::renderVerticalLine(int x, int y, int h) {
|
||||
DependencyManager::get<GeometryCache>()->renderLine(glm::vec2(x, y), glm::vec2(x, y + h));
|
||||
}
|
||||
|
||||
inline int BandwidthMeter::centered(int subject, int object) {
|
||||
return (object - subject) / 2;
|
||||
}
|
||||
|
||||
bool BandwidthMeter::isWithinArea(int x, int y, int screenWidth, int screenHeight) {
|
||||
|
||||
int minX = BORDER_DISTANCE_HORIZ + (AREA_WIDTH >= 0 ? 0 : screenWidth + AREA_WIDTH);
|
||||
int minY = BORDER_DISTANCE_VERT + (AREA_HEIGHT >= 0 ? 0 : screenHeight + AREA_HEIGHT);
|
||||
|
||||
return x >= minX && x < minX + glm::abs(AREA_WIDTH) &&
|
||||
y >= minY && y < minY + glm::abs(AREA_HEIGHT);
|
||||
}
|
||||
|
||||
void BandwidthMeter::render(int screenWidth, int screenHeight) {
|
||||
|
||||
int x = BORDER_DISTANCE_HORIZ + (AREA_WIDTH >= 0 ? 0 : screenWidth + AREA_WIDTH);
|
||||
int y = BORDER_DISTANCE_VERT + (AREA_HEIGHT >= 0 ? 0 : screenHeight + AREA_HEIGHT);
|
||||
int w = glm::abs(AREA_WIDTH), h = glm::abs(AREA_HEIGHT);
|
||||
|
||||
// Determine total
|
||||
float totalIn = 0.0f, totalOut = 0.0f;
|
||||
for (size_t i = 0; i < N_CHANNELS; ++i) {
|
||||
|
||||
totalIn += inputStream(ChannelIndex(i)).getValue();
|
||||
totalOut += outputStream(ChannelIndex(i)).getValue();
|
||||
}
|
||||
totalIn *= UNIT_SCALE;
|
||||
totalOut *= UNIT_SCALE;
|
||||
float totalMax = glm::max(totalIn, totalOut);
|
||||
|
||||
// Get font / caption metrics
|
||||
QFontMetrics const& fontMetrics = _textRenderer->metrics();
|
||||
int fontDescent = fontMetrics.descent();
|
||||
int labelWidthIn = fontMetrics.width(CAPTION_IN);
|
||||
int labelWidthOut = fontMetrics.width(CAPTION_OUT);
|
||||
int labelWidthInOut = glm::max(labelWidthIn, labelWidthOut);
|
||||
int labelHeight = fontMetrics.ascent() + fontDescent;
|
||||
int labelWidthUnit = fontMetrics.width(CAPTION_UNIT);
|
||||
int labelsWidth = labelWidthInOut + SPACING_RIGHT_CAPTION_IN_OUT + SPACING_LEFT_CAPTION_UNIT + labelWidthUnit;
|
||||
|
||||
// Calculate coordinates and dimensions
|
||||
int barX = x + labelWidthInOut + SPACING_RIGHT_CAPTION_IN_OUT;
|
||||
int barWidth = w - labelsWidth;
|
||||
int barHeight = (h - SPACING_VERT_BARS) / 2;
|
||||
int textYcenteredLine = h - centered(labelHeight, h) - fontDescent;
|
||||
int textYupperLine = barHeight - centered(labelHeight, barHeight) - fontDescent;
|
||||
int textYlowerLine = h - centered(labelHeight, barHeight) - fontDescent;
|
||||
|
||||
// Center of coordinate system -> upper left of bar
|
||||
glPushMatrix();
|
||||
glTranslatef((float)barX, (float)y, 0.0f);
|
||||
|
||||
// Render captions
|
||||
setColorRGBA(COLOR_TEXT);
|
||||
_textRenderer->draw(barWidth + SPACING_LEFT_CAPTION_UNIT, textYcenteredLine, CAPTION_UNIT);
|
||||
_textRenderer->draw(-labelWidthIn - SPACING_RIGHT_CAPTION_IN_OUT, textYupperLine, CAPTION_IN);
|
||||
_textRenderer->draw(-labelWidthOut - SPACING_RIGHT_CAPTION_IN_OUT, textYlowerLine, CAPTION_OUT);
|
||||
|
||||
// Render vertical lines for the frame
|
||||
setColorRGBA(COLOR_FRAME);
|
||||
renderVerticalLine(0, 0, h);
|
||||
renderVerticalLine(barWidth, 0, h);
|
||||
|
||||
// Adjust scale
|
||||
int steps;
|
||||
double step, scaleMax;
|
||||
bool commit = false;
|
||||
do {
|
||||
steps = (_scaleMaxIndex % 9) + 2;
|
||||
step = pow(10.0, (_scaleMaxIndex / 9) - 10);
|
||||
scaleMax = step * steps;
|
||||
if (commit) {
|
||||
// printLog("Bandwidth meter scale: %d\n", _scaleMaxIndex);
|
||||
break;
|
||||
}
|
||||
if (totalMax < scaleMax * 0.5) {
|
||||
_scaleMaxIndex = glm::max(0, _scaleMaxIndex - 1);
|
||||
commit = true;
|
||||
} else if (totalMax > scaleMax) {
|
||||
_scaleMaxIndex += 1;
|
||||
commit = true;
|
||||
}
|
||||
} while (commit);
|
||||
|
||||
step = scaleMax / NUMBER_OF_MARKERS;
|
||||
if (scaleMax < MIN_METER_SCALE) {
|
||||
scaleMax = MIN_METER_SCALE;
|
||||
}
|
||||
|
||||
// Render scale indicators
|
||||
setColorRGBA(COLOR_INDICATOR);
|
||||
for (int j = NUMBER_OF_MARKERS; --j > 0;) {
|
||||
renderVerticalLine((barWidth * j) / NUMBER_OF_MARKERS, 0, h);
|
||||
}
|
||||
|
||||
// Render bars
|
||||
int xIn = 0, xOut = 0;
|
||||
for (size_t i = 0; i < N_CHANNELS; ++i) {
|
||||
|
||||
ChannelIndex chIdx = ChannelIndex(i);
|
||||
int wIn = (int)(barWidth * inputStream(chIdx).getValue() * UNIT_SCALE / scaleMax);
|
||||
int wOut = (int)(barWidth * outputStream(chIdx).getValue() * UNIT_SCALE / scaleMax);
|
||||
|
||||
setColorRGBA(channelInfo(chIdx).colorRGBA);
|
||||
|
||||
if (wIn > 0) {
|
||||
renderBox(xIn, 0, wIn, barHeight);
|
||||
}
|
||||
xIn += wIn;
|
||||
|
||||
if (wOut > 0) {
|
||||
renderBox(xOut, h - barHeight, wOut, barHeight);
|
||||
}
|
||||
xOut += wOut;
|
||||
}
|
||||
|
||||
// Render numbers
|
||||
char fmtBuf[8];
|
||||
setColorRGBA(COLOR_TEXT);
|
||||
sprintf(fmtBuf, "%0.1f", totalIn);
|
||||
_textRenderer->draw(glm::max(xIn - fontMetrics.width(fmtBuf) - PADDING_HORIZ_VALUE,
|
||||
PADDING_HORIZ_VALUE),
|
||||
textYupperLine, fmtBuf);
|
||||
sprintf(fmtBuf, "%0.1f", totalOut);
|
||||
_textRenderer->draw(glm::max(xOut - fontMetrics.width(fmtBuf) - PADDING_HORIZ_VALUE,
|
||||
PADDING_HORIZ_VALUE),
|
||||
textYlowerLine, fmtBuf);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// After rendering, indicate that no data has been sent/received since the last feed.
|
||||
// This way, the meters fall when not continuously fed.
|
||||
for (size_t i = 0; i < N_CHANNELS; ++i) {
|
||||
inputStream(ChannelIndex(i)).updateValue(0);
|
||||
outputStream(ChannelIndex(i)).updateValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
//
|
||||
// BandwidthMeter.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Tobias Schwinger on 6/20/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_BandwidthMeter_h
|
||||
#define hifi_BandwidthMeter_h
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <TextRenderer.h>
|
||||
|
||||
|
||||
class BandwidthMeter {
|
||||
|
||||
public:
|
||||
|
||||
BandwidthMeter();
|
||||
~BandwidthMeter();
|
||||
|
||||
void render(int screenWidth, int screenHeight);
|
||||
bool isWithinArea(int x, int y, int screenWidth, int screenHeight);
|
||||
|
||||
// Number of channels / streams.
|
||||
static size_t const N_CHANNELS = 4;
|
||||
static size_t const N_STREAMS = N_CHANNELS * 2;
|
||||
|
||||
// Channel usage.
|
||||
enum ChannelIndex { AUDIO, AVATARS, OCTREE, METAVOXELS };
|
||||
|
||||
// Meta information held for a communication channel (bidirectional).
|
||||
struct ChannelInfo {
|
||||
|
||||
char const* const caption;
|
||||
char const* unitCaption;
|
||||
double unitScale;
|
||||
unsigned colorRGBA;
|
||||
};
|
||||
|
||||
// Representation of a data stream (unidirectional; input or output).
|
||||
class Stream {
|
||||
|
||||
public:
|
||||
|
||||
Stream(float msToAverage = 3000.0f);
|
||||
void updateValue(double amount);
|
||||
double getValue() const { return _value; }
|
||||
|
||||
private:
|
||||
double _value; // Current value.
|
||||
double _msToAverage; // Milliseconds to average.
|
||||
QElapsedTimer _prevTime; // Time of last feed.
|
||||
};
|
||||
|
||||
// Data model accessors
|
||||
Stream& inputStream(ChannelIndex i) { return _streams[i * 2]; }
|
||||
Stream const& inputStream(ChannelIndex i) const { return _streams[i * 2]; }
|
||||
Stream& outputStream(ChannelIndex i) { return _streams[i * 2 + 1]; }
|
||||
Stream const& outputStream(ChannelIndex i) const { return _streams[i * 2 + 1]; }
|
||||
ChannelInfo& channelInfo(ChannelIndex i) { return _channels[i]; }
|
||||
ChannelInfo const& channelInfo(ChannelIndex i) const { return _channels[i]; }
|
||||
|
||||
private:
|
||||
static void setColorRGBA(unsigned c);
|
||||
static void renderBox(int x, int y, int w, int h);
|
||||
static void renderVerticalLine(int x, int y, int h);
|
||||
|
||||
static inline int centered(int subject, int object);
|
||||
|
||||
|
||||
static ChannelInfo _CHANNELS[];
|
||||
|
||||
TextRenderer* _textRenderer;
|
||||
ChannelInfo* _channels;
|
||||
Stream _streams[N_STREAMS];
|
||||
int _scaleMaxIndex;
|
||||
};
|
||||
|
||||
#endif // hifi_BandwidthMeter_h
|
|
@ -102,7 +102,7 @@ void DialogsManager::editAnimations() {
|
|||
|
||||
void DialogsManager::bandwidthDetails() {
|
||||
if (! _bandwidthDialog) {
|
||||
_bandwidthDialog = new BandwidthDialog(qApp->getWindow(), qApp->getBandwidthMeter());
|
||||
_bandwidthDialog = new BandwidthDialog(qApp->getWindow(), qApp->getBandwidthRecorder());
|
||||
connect(_bandwidthDialog, SIGNAL(closed()), _bandwidthDialog, SLOT(deleteLater()));
|
||||
|
||||
if (_hmdToolsDialog) {
|
||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
|||
const int STATS_PELS_PER_LINE = 20;
|
||||
|
||||
const int STATS_GENERAL_MIN_WIDTH = 165;
|
||||
const int STATS_BANDWIDTH_MIN_WIDTH = 150;
|
||||
const int STATS_PING_MIN_WIDTH = 190;
|
||||
const int STATS_GEO_MIN_WIDTH = 240;
|
||||
const int STATS_OCTREE_MIN_WIDTH = 410;
|
||||
|
@ -49,6 +50,7 @@ Stats::Stats():
|
|||
_recentMaxPackets(0),
|
||||
_resetRecentMaxPacketsSoon(true),
|
||||
_generalStatsWidth(STATS_GENERAL_MIN_WIDTH),
|
||||
_bandwidthStatsWidth(STATS_BANDWIDTH_MIN_WIDTH),
|
||||
_pingStatsWidth(STATS_PING_MIN_WIDTH),
|
||||
_geoStatsWidth(STATS_GEO_MIN_WIDTH),
|
||||
_octreeStatsWidth(STATS_OCTREE_MIN_WIDTH),
|
||||
|
@ -129,6 +131,7 @@ void Stats::resetWidth(int width, int horizontalOffset) {
|
|||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
int extraSpace = glCanvas->width() - horizontalOffset -2
|
||||
- STATS_GENERAL_MIN_WIDTH
|
||||
- STATS_BANDWIDTH_MIN_WIDTH
|
||||
- (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0)
|
||||
- STATS_GEO_MIN_WIDTH
|
||||
- STATS_OCTREE_MIN_WIDTH;
|
||||
|
@ -136,6 +139,7 @@ void Stats::resetWidth(int width, int horizontalOffset) {
|
|||
int panels = 4;
|
||||
|
||||
_generalStatsWidth = STATS_GENERAL_MIN_WIDTH;
|
||||
_bandwidthStatsWidth = STATS_BANDWIDTH_MIN_WIDTH;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) {
|
||||
_pingStatsWidth = STATS_PING_MIN_WIDTH;
|
||||
} else {
|
||||
|
@ -147,11 +151,13 @@ void Stats::resetWidth(int width, int horizontalOffset) {
|
|||
|
||||
if (extraSpace > panels) {
|
||||
_generalStatsWidth += (int) extraSpace / panels;
|
||||
_bandwidthStatsWidth += (int) extraSpace / panels;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) {
|
||||
_pingStatsWidth += (int) extraSpace / panels;
|
||||
}
|
||||
_geoStatsWidth += (int) extraSpace / panels;
|
||||
_octreeStatsWidth += glCanvas->width() - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
|
||||
_octreeStatsWidth += glCanvas->width() -
|
||||
(_generalStatsWidth + _bandwidthStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,7 +234,7 @@ void Stats::display(
|
|||
|
||||
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayTimingDetails)) {
|
||||
|
||||
columnOneWidth = _generalStatsWidth + _pingStatsWidth + _geoStatsWidth; // make it 3 columns wide...
|
||||
columnOneWidth = _generalStatsWidth + _bandwidthStatsWidth + _pingStatsWidth + _geoStatsWidth; // 4 columns wide...
|
||||
// we will also include room for 1 line per timing record and a header of 4 lines
|
||||
lines += 4;
|
||||
|
||||
|
@ -395,7 +401,7 @@ void Stats::display(
|
|||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
horizontalOffset = _lastHorizontalOffset + _generalStatsWidth + _pingStatsWidth + 2;
|
||||
horizontalOffset = _lastHorizontalOffset + _generalStatsWidth + _bandwidthStatsWidth + _pingStatsWidth + 2;
|
||||
}
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
|
@ -473,7 +479,7 @@ void Stats::display(
|
|||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
horizontalOffset = _lastHorizontalOffset + _generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3;
|
||||
horizontalOffset = _lastHorizontalOffset + _generalStatsWidth + _bandwidthStatsWidth + _pingStatsWidth + _geoStatsWidth + 3;
|
||||
|
||||
lines = _expanded ? 14 : 3;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ private:
|
|||
bool _resetRecentMaxPacketsSoon;
|
||||
|
||||
int _generalStatsWidth;
|
||||
int _bandwidthStatsWidth;
|
||||
int _pingStatsWidth;
|
||||
int _geoStatsWidth;
|
||||
int _octreeStatsWidth;
|
||||
|
|
Loading…
Reference in a new issue