From 83290bc8b7ac0a769c43b4df216ea2f289c12fe7 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Jul 2013 17:28:37 -0700 Subject: [PATCH] first cut at real voxel stats dialog box --- interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 25 +++++++- interface/src/Application.h | 7 +++ interface/src/ui/VoxelStatsDialog.cpp | 74 ++++++++++++++++++++++++ interface/src/ui/VoxelStatsDialog.h | 45 ++++++++++++++ libraries/voxels/src/VoxelSceneStats.cpp | 27 +++++++++ libraries/voxels/src/VoxelSceneStats.h | 21 +++++++ 7 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 interface/src/ui/VoxelStatsDialog.cpp create mode 100644 interface/src/ui/VoxelStatsDialog.h diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 829ccbff06..9625c1b78d 100755 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -75,7 +75,7 @@ add_subdirectory(external/fervor/) include_directories(external/fervor/) # run qt moc on qt-enabled headers -qt4_wrap_cpp(INTERFACE_SRCS src/Application.h src/AvatarVoxelSystem.h src/Webcam.h src/ui/BandwidthDialog.h) +qt4_wrap_cpp(INTERFACE_SRCS src/Application.h src/AvatarVoxelSystem.h src/Webcam.h src/ui/BandwidthDialog.h src/ui/VoxelStatsDialog.h) # create the executable, make it a bundle on OS X add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS}) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 345ede0274..fddfdfef07 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -176,6 +176,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _window(new QMainWindow(desktop())), _glWidget(new GLCanvas()), _bandwidthDialog(NULL), + _voxelStatsDialog(NULL), _displayLevels(false), _frameCount(0), _fps(120.0f), @@ -1097,6 +1098,21 @@ void Application::bandwidthDetailsClosed() { delete dlg; } +void Application::voxelStatsDetails() { + if (!_voxelStatsDialog) { + _voxelStatsDialog = new VoxelStatsDialog(_glWidget, &_voxelSceneStats); + connect(_voxelStatsDialog, SIGNAL(closed()), SLOT(voxelStatsDetailsClosed())); + _voxelStatsDialog->show(); + } + _voxelStatsDialog->raise(); +} + +void Application::voxelStatsDetailsClosed() { + QDialog* dlg = _voxelStatsDialog; + _voxelStatsDialog = NULL; + delete dlg; +} + void Application::editPreferences() { QDialog dialog(_glWidget); dialog.setWindowTitle("Interface Preferences"); @@ -1695,6 +1711,7 @@ void Application::initMenu() { (_bandwidthDisplayOn = toolsMenu->addAction("Bandwidth Display"))->setCheckable(true); _bandwidthDisplayOn->setChecked(true); toolsMenu->addAction("Bandwidth Details", this, SLOT(bandwidthDetails())); + toolsMenu->addAction("Voxel Stats Details", this, SLOT(voxelStatsDetails())); QMenu* voxelMenu = menuBar->addMenu("Voxels"); @@ -2128,6 +2145,9 @@ void Application::update(float deltaTime) { if (_bandwidthDialog) { _bandwidthDialog->update(); } + if (_voxelStatsDialog) { + _voxelStatsDialog->update(); + } // Update audio stats for procedural sounds #ifndef _WIN32 @@ -3361,9 +3381,8 @@ void* Application::networkReceive(void* args) { // immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first // then process any remaining bytes as if it was another packet if (messageData[0] == PACKET_TYPE_VOXEL_STATS) { - VoxelSceneStats stats; - int statsMessageLength = stats.unpackFromMessage(messageData, messageLength); - stats.printDebugDetails(); + int statsMessageLength = app->_voxelSceneStats.unpackFromMessage(messageData, messageLength); + app->_voxelSceneStats.printDebugDetails(); if (messageLength > statsMessageLength) { messageData += statsMessageLength; messageLength -= statsMessageLength; diff --git a/interface/src/Application.h b/interface/src/Application.h index 9333808a27..05df195a3e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -39,6 +39,7 @@ #include "ToolsPalette.h" #include "ui/ChatEntry.h" #include "ui/BandwidthDialog.h" +#include "ui/VoxelStatsDialog.h" #include "ViewFrustum.h" #include "VoxelSystem.h" #include "Webcam.h" @@ -116,6 +117,9 @@ private slots: void bandwidthDetails(); void editPreferences(); void bandwidthDetailsClosed(); + + void voxelStatsDetails(); + void voxelStatsDetailsClosed(); void pair(); @@ -277,6 +281,7 @@ private: BandwidthMeter _bandwidthMeter; BandwidthDialog* _bandwidthDialog; + VoxelStatsDialog* _voxelStatsDialog; SerialInterface _serialHeadSensor; QNetworkAccessManager* _networkAccessManager; @@ -406,6 +411,8 @@ private: ToolsPalette _palette; Swatch _swatch; + + VoxelSceneStats _voxelSceneStats; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp new file mode 100644 index 0000000000..455ea0cfb0 --- /dev/null +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -0,0 +1,74 @@ +// +// VoxelStatsDialog.cpp +// interface +// +// Created by Brad Hefta-Gaub on 7/19/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include +#include + +#include +#include + +#include + +#include "ui/VoxelStatsDialog.h" + + +VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) : + QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint), + _model(model) { + + char strBuf[64]; + + this->setWindowTitle("Voxel Statistics"); + + // Create layouter + QFormLayout* form = new QFormLayout(); + this->QDialog::setLayout(form); + + // Setup labels + for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) { + VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(i); + 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 = itemInfo.colorRGBA >> 8; + rgb = ((rgb & 0xfefefeu) >> 1) + ((rgb & 0xf8f8f8) >> 3); + palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb)); + label->setPalette(palette); + + snprintf(strBuf, sizeof(strBuf), " %s:", itemInfo.caption); + form->addRow(strBuf, label); + } +} + +void VoxelStatsDialog::paintEvent(QPaintEvent* event) { + + // Update labels + char strBuf[64]; + for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) { + QLabel* label = _labels[i]; + snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(i)); + label->setText(strBuf); + } + + this->QDialog::paintEvent(event); + this->setFixedSize(this->width(), this->height()); +} + +void VoxelStatsDialog::reject() { + // Just regularly close upon ESC + this->QDialog::close(); +} + +void VoxelStatsDialog::closeEvent(QCloseEvent* event) { + this->QDialog::closeEvent(event); + emit closed(); +} + + diff --git a/interface/src/ui/VoxelStatsDialog.h b/interface/src/ui/VoxelStatsDialog.h new file mode 100644 index 0000000000..1d30ec8881 --- /dev/null +++ b/interface/src/ui/VoxelStatsDialog.h @@ -0,0 +1,45 @@ +// +// VoxelStatsDialog.h +// interface +// +// Created by Brad Hefta-Gaub on 7/19/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__VoxelStatsDialog__ +#define __hifi__VoxelStatsDialog__ + +#include +#include + +#include + +class VoxelStatsDialog : public QDialog { + Q_OBJECT +public: + + // Sets up the UI + VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model); + +signals: + void closed(); + +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: + QLabel* _labels[VoxelSceneStats::ITEM_COUNT]; + VoxelSceneStats* _model; +}; + +#endif /* defined(__interface__VoxelStatsDialog__) */ + diff --git a/libraries/voxels/src/VoxelSceneStats.cpp b/libraries/voxels/src/VoxelSceneStats.cpp index ab25b725bb..02ee47c6c1 100644 --- a/libraries/voxels/src/VoxelSceneStats.cpp +++ b/libraries/voxels/src/VoxelSceneStats.cpp @@ -12,6 +12,7 @@ #include "VoxelNode.h" #include "VoxelSceneStats.h" + VoxelSceneStats::VoxelSceneStats() { reset(); _readyToSend = false; @@ -386,3 +387,29 @@ void VoxelSceneStats::printDebugDetails() { qDebug(" in packet bit : %lu\n", _existsInPacketBitsWritten); qDebug(" trees removed : %lu\n", _treesRemoved ); } + + +VoxelSceneStats::ItemInfo VoxelSceneStats::_ITEMS[] = { + { "Elapsed" , "usecs", 0x40ff40d0 }, + { "Encode" , "usecs", 0xffef40c0 }, + { "Packets" , "" , 0xd0d0d0a0 } +}; + +char* VoxelSceneStats::getItemValue(int item) { + switch(item) { + case ITEM_ELAPSED: + sprintf(_itemValueBuffer, "%llu", _elapsed); + break; + case ITEM_ENCODE: + sprintf(_itemValueBuffer, "%llu", _totalEncodeTime); + break; + case ITEM_PACKETS: + sprintf(_itemValueBuffer, "%d", _packets); + break; + default: + sprintf(_itemValueBuffer, ""); + break; + } + return _itemValueBuffer; +} + diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index 05545f3320..99880c591d 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -49,6 +49,22 @@ public: unsigned char* getStatsMessage() { return &_statsMessage[0]; } int getStatsMessageLength() const { return _statsMessageLength; } + enum { + ITEM_ELAPSED, + ITEM_ENCODE, + ITEM_PACKETS, + ITEM_COUNT + }; + + // Meta information about each stats item + struct ItemInfo { + char const* const caption; + char const* unitCaption; + unsigned colorRGBA; + }; + + ItemInfo& getItemInfo(int item) { return _ITEMS[item]; }; + char* getItemValue(int item); private: bool _readyToSend; @@ -124,6 +140,11 @@ private: // features related items bool _moving; bool _fullSceneDraw; + + + static ItemInfo _ITEMS[]; + static int const MAX_ITEM_VALUE_LENGTH = 40; + char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH]; }; #endif /* defined(__hifi__VoxelSceneStats__) */