Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels

This commit is contained in:
Andrzej Kapolka 2014-08-18 11:40:16 -07:00
commit b7bdaae691
6 changed files with 141 additions and 21 deletions

View file

@ -242,6 +242,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(&domainHandler, SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&)));
connect(&domainHandler, SIGNAL(connectedToDomain(const QString&)), SLOT(connectedToDomain(const QString&)));
connect(&domainHandler, SIGNAL(connectedToDomain(const QString&)), SLOT(updateWindowTitle()));
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
connect(&domainHandler, &DomainHandler::settingsReceived, this, &Application::domainSettingsReceived);
// hookup VoxelEditSender to PaymentManager so we can pay for octree edits
@ -3328,9 +3330,10 @@ void Application::updateWindowTitle(){
QString buildVersion = " (build " + applicationVersion() + ")";
NodeList* nodeList = NodeList::getInstance();
QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) ";
QString username = AccountManager::getInstance().getAccountInfo().getUsername();
QString title = QString() + (!username.isEmpty() ? username + " @ " : QString())
+ nodeList->getDomainHandler().getHostname() + buildVersion;
+ nodeList->getDomainHandler().getHostname() + connectionStatus + buildVersion;
AccountManager& accountManager = AccountManager::getInstance();
if (accountManager.getAccountInfo().hasBalance()) {

View file

@ -57,6 +57,9 @@ ApplicationOverlay::~ApplicationOverlay() {
const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f };
const float RETICLE_COLOR[] = { 0.0f, 198.0f / 255.0f, 244.0f / 255.0f };
const float CONNECTION_STATUS_BORDER_COLOR[] = { 1.0f, 0.0f, 0.0f };
const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f;
// Renders the overlays either to a texture or to the screen
void ApplicationOverlay::renderOverlay(bool renderToTexture) {
@ -115,6 +118,8 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
renderPointers();
renderDomainConnectionStatusBorder();
glPopMatrix();
@ -1234,6 +1239,30 @@ void ApplicationOverlay::renderTexturedHemisphere() {
}
void ApplicationOverlay::renderDomainConnectionStatusBorder() {
NodeList* nodeList = NodeList::getInstance();
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
QGLWidget* glWidget = Application::getInstance()->getGLWidget();
int right = glWidget->width();
int bottom = glWidget->height();
glColor3f(CONNECTION_STATUS_BORDER_COLOR[0],
CONNECTION_STATUS_BORDER_COLOR[1],
CONNECTION_STATUS_BORDER_COLOR[2]);
glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH);
glBegin(GL_LINE_LOOP);
glVertex2i(0, 0);
glVertex2i(0, bottom);
glVertex2i(right, bottom);
glVertex2i(right, 0);
glEnd();
}
}
QOpenGLFramebufferObject* ApplicationOverlay::getFramebufferObject() {
QSize size = Application::getInstance()->getGLWidget()->size();
if (!_framebufferObject || _framebufferObject->size() != size) {

View file

@ -56,6 +56,7 @@ private:
void renderAudioMeter();
void renderStatsAndLogs();
void renderTexturedHemisphere();
void renderDomainConnectionStatusBorder();
QOpenGLFramebufferObject* _framebufferObject;
float _trailingAudioLoudness;
@ -76,4 +77,4 @@ private:
GLuint _crosshairTexture;
};
#endif // hifi_ApplicationOverlay_h
#endif // hifi_ApplicationOverlay_h

View file

@ -36,6 +36,7 @@ DomainHandler::DomainHandler(QObject* parent) :
void DomainHandler::clearConnectionInfo() {
_uuid = QUuid();
_isConnected = false;
emit disconnectedFromDomain();
if (_handshakeTimer) {
_handshakeTimer->stop();
@ -129,6 +130,8 @@ void DomainHandler::setIsConnected(bool isConnected) {
// we've connected to new domain - time to ask it for global settings
requestDomainSettings();
} else {
emit disconnectedFromDomain();
}
}
}
@ -196,4 +199,4 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement
_sockAddr.setPort(dtlsPort);
// initializeDTLSSession();
}
}

View file

@ -70,6 +70,7 @@ private slots:
signals:
void hostnameChanged(const QString& hostname);
void connectedToDomain(const QString& hostname);
void disconnectedFromDomain();
void settingsReceived(const QJsonObject& domainSettingsObject);
void settingsReceiveFail();

View file

@ -16,12 +16,14 @@
#include <cerrno>
#include <stdio.h>
#include <MovingMinMaxAvg.h> // for MovingMinMaxAvg
#include <MovingMinMaxAvg.h>
#include <SequenceNumberStats.h>
#include <StdDev.h>
#include <SharedUtil.h> // for usecTimestampNow
#include <SimpleMovingAverage.h>
#include <StdDev.h>
const quint64 MSEC_TO_USEC = 1000;
const quint64 LARGE_STATS_TIME = 500; // we don't expect stats calculation to take more than this many usecs
void runSend(const char* addressOption, int port, int gap, int size, int report);
void runReceive(const char* addressOption, int port, int gap, int size, int report);
@ -77,25 +79,37 @@ void runSend(const char* addressOption, int port, int gap, int size, int report)
servaddr.sin_addr.s_addr = inet_addr(addressOption);
servaddr.sin_port = htons(port);
const int SAMPLES_FOR_30_SECONDS = 30 * 1000000 / gap;
const int SAMPLES_FOR_SECOND = 1000000 / gap;
std::cout << "SAMPLES_FOR_SECOND:" << SAMPLES_FOR_SECOND << "\n";
const int INTERVALS_PER_30_SECONDS = 30;
std::cout << "INTERVALS_PER_30_SECONDS:" << INTERVALS_PER_30_SECONDS << "\n";
const int SAMPLES_FOR_30_SECONDS = 30 * SAMPLES_FOR_SECOND;
std::cout << "SAMPLES_FOR_30_SECONDS:" << SAMPLES_FOR_30_SECONDS << "\n";
const int REPORTS_FOR_30_SECONDS = 30 * MSECS_PER_SECOND / report;
std::cout << "REPORTS_FOR_30_SECONDS:" << REPORTS_FOR_30_SECONDS << "\n";
const int SAMPLES_PER_REPORT = report * MSEC_TO_USEC / gap;
std::cout << "SAMPLES_PER_REPORT:" << SAMPLES_PER_REPORT << "\n";
int intervalsPerReport = report / MSEC_TO_USEC;
if (intervalsPerReport < 1) {
intervalsPerReport = 1;
}
std::cout << "intervalsPerReport:" << intervalsPerReport << "\n";
MovingMinMaxAvg<int> timeGaps(SAMPLES_FOR_SECOND, INTERVALS_PER_30_SECONDS);
MovingMinMaxAvg<int> timeGapsPerReport(SAMPLES_FOR_SECOND, intervalsPerReport);
char* outputBuffer = new char[size];
memset(outputBuffer, 0, size);
quint16 outgoingSequenceNumber = 0;
MovingMinMaxAvg<int> timeGaps(1, SAMPLES_FOR_30_SECONDS);
MovingMinMaxAvg<int> timeGapsPerReport(1, SAMPLES_PER_REPORT);
StDev stDevReportInterval;
StDev stDev30s;
StDev stDev;
SimpleMovingAverage averageNetworkTime(SAMPLES_FOR_30_SECONDS);
SimpleMovingAverage averageStatsCalcultionTime(SAMPLES_FOR_30_SECONDS);
float lastStatsCalculationTime = 0.0f; // we add out stats calculation time in the next calculation window
bool hasStatsCalculationTime = false;
quint64 last = usecTimestampNow();
quint64 lastReport = 0;
@ -111,19 +125,37 @@ void runSend(const char* addressOption, int port, int gap, int size, int report)
// pack seq num
memcpy(outputBuffer, &outgoingSequenceNumber, sizeof(quint16));
quint64 networkStart = usecTimestampNow();
int n = sendto(sockfd, outputBuffer, size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
quint64 networkEnd = usecTimestampNow();
float networkElapsed = (float)(networkEnd - networkStart);
if (n < 0) {
std::cout << "Send error: " << strerror(errno) << "\n";
}
outgoingSequenceNumber++;
quint64 statsCalcultionStart = usecTimestampNow();
int gapDifferece = actualGap - gap;
timeGaps.update(gapDifferece);
timeGapsPerReport.update(gapDifferece);
stDev.addValue(gapDifferece);
stDev30s.addValue(gapDifferece);
stDevReportInterval.addValue(gapDifferece);
last = now;
// track out network time and stats calculation times
averageNetworkTime.updateAverage(networkElapsed);
// for our stats calculation time, we actually delay the updating by one sample.
// we do this so that the calculation of the average timing for the stats calculation
// happen inside of the calculation processing. This ensures that tracking stats on
// stats calculation doesn't side effect the remaining running time.
if (hasStatsCalculationTime) {
averageStatsCalcultionTime.updateAverage(lastStatsCalculationTime);
}
if (now - lastReport >= (report * MSEC_TO_USEC)) {
@ -144,6 +176,9 @@ void runSend(const char* addressOption, int port, int gap, int size, int report)
<< "max: " << timeGapsPerReport.getWindowMax() << " usecs, "
<< "avg: " << timeGapsPerReport.getWindowAverage() << " usecs, "
<< "stdev: " << stDevReportInterval.getStDev() << " usecs\n"
<< "Average Execution Times Last 30s:\n"
<< " network: " << averageNetworkTime.getAverage() << " usecs average\n"
<< " stats: " << averageStatsCalcultionTime.getAverage() << " usecs average"
<< "\n";
stDevReportInterval.reset();
@ -153,6 +188,14 @@ void runSend(const char* addressOption, int port, int gap, int size, int report)
lastReport = now;
}
quint64 statsCalcultionEnd = usecTimestampNow();
lastStatsCalculationTime = (float)(statsCalcultionEnd - statsCalcultionStart);
if (lastStatsCalculationTime > LARGE_STATS_TIME) {
qDebug() << "WARNING -- unexpectedly large lastStatsCalculationTime=" << lastStatsCalculationTime;
}
hasStatsCalculationTime = true;
}
}
delete[] outputBuffer;
@ -184,21 +227,26 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
myaddr.sin_port = htons(port);
const int SAMPLES_FOR_30_SECONDS = 30 * 1000000 / gap;
const int SAMPLES_FOR_SECOND = 1000000 / gap;
std::cout << "SAMPLES_FOR_SECOND:" << SAMPLES_FOR_SECOND << "\n";
const int INTERVALS_PER_30_SECONDS = 30;
std::cout << "INTERVALS_PER_30_SECONDS:" << INTERVALS_PER_30_SECONDS << "\n";
const int SAMPLES_FOR_30_SECONDS = 30 * SAMPLES_FOR_SECOND;
std::cout << "SAMPLES_FOR_30_SECONDS:" << SAMPLES_FOR_30_SECONDS << "\n";
const int SAMPLES_PER_REPORT = report * MSEC_TO_USEC / gap;
std::cout << "SAMPLES_PER_REPORT:" << SAMPLES_PER_REPORT << "\n";
const int REPORTS_FOR_30_SECONDS = 30 * MSECS_PER_SECOND / report;
std::cout << "REPORTS_FOR_30_SECONDS:" << REPORTS_FOR_30_SECONDS << "\n";
int intervalsPerReport = report / MSEC_TO_USEC;
if (intervalsPerReport < 1) {
intervalsPerReport = 1;
}
std::cout << "intervalsPerReport:" << intervalsPerReport << "\n";
MovingMinMaxAvg<int> timeGaps(SAMPLES_FOR_SECOND, INTERVALS_PER_30_SECONDS);
MovingMinMaxAvg<int> timeGapsPerReport(SAMPLES_FOR_SECOND, intervalsPerReport);
char* inputBuffer = new char[size];
memset(inputBuffer, 0, size);
MovingMinMaxAvg<int> timeGaps(1, SAMPLES_FOR_30_SECONDS);
MovingMinMaxAvg<int> timeGapsPerReport(1, SAMPLES_PER_REPORT);
SequenceNumberStats seqStats(REPORTS_FOR_30_SECONDS);
@ -206,6 +254,11 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
StDev stDev30s;
StDev stDev;
SimpleMovingAverage averageNetworkTime(SAMPLES_FOR_30_SECONDS);
SimpleMovingAverage averageStatsCalcultionTime(SAMPLES_FOR_30_SECONDS);
float lastStatsCalculationTime = 0.0f; // we add out stats calculation time in the next calculation window
bool hasStatsCalculationTime = false;
if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
std::cout << "bind failed\n";
return;
@ -213,9 +266,14 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
quint64 last = 0; // first case
quint64 lastReport = 0;
while (true) {
quint64 networkStart = usecTimestampNow();
n = recvfrom(sockfd, inputBuffer, size, 0, NULL, NULL); // we don't care about where it came from
quint64 networkEnd = usecTimestampNow();
float networkElapsed = (float)(networkEnd - networkStart);
if (n < 0) {
std::cout << "Receive error: " << strerror(errno) << "\n";
}
@ -228,8 +286,11 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
last = usecTimestampNow();
std::cout << "first packet received\n";
} else {
quint64 statsCalcultionStart = usecTimestampNow();
quint64 now = usecTimestampNow();
int actualGap = now - last;
int gapDifferece = actualGap - gap;
timeGaps.update(gapDifferece);
timeGapsPerReport.update(gapDifferece);
@ -237,6 +298,17 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
stDev30s.addValue(gapDifferece);
stDevReportInterval.addValue(gapDifferece);
last = now;
// track out network time and stats calculation times
averageNetworkTime.updateAverage(networkElapsed);
// for our stats calculation time, we actually delay the updating by one sample.
// we do this so that the calculation of the average timing for the stats calculation
// happen inside of the calculation processing. This ensures that tracking stats on
// stats calculation doesn't side effect the remaining running time.
if (hasStatsCalculationTime) {
averageStatsCalcultionTime.updateAverage(lastStatsCalculationTime);
}
if (now - lastReport >= (report * MSEC_TO_USEC)) {
@ -258,9 +330,12 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
<< "max: " << timeGapsPerReport.getWindowMax() << " usecs, "
<< "avg: " << timeGapsPerReport.getWindowAverage() << " usecs, "
<< "stdev: " << stDevReportInterval.getStDev() << " usecs\n"
<< "Average Execution Times Last 30s:\n"
<< " network: " << averageNetworkTime.getAverage() << " usecs average\n"
<< " stats: " << averageStatsCalcultionTime.getAverage() << " usecs average"
<< "\n";
stDevReportInterval.reset();
if (stDev30s.getSamples() > SAMPLES_FOR_30_SECONDS) {
stDev30s.reset();
}
@ -282,6 +357,14 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo
lastReport = now;
}
quint64 statsCalcultionEnd = usecTimestampNow();
lastStatsCalculationTime = (float)(statsCalcultionEnd - statsCalcultionStart);
if (lastStatsCalculationTime > LARGE_STATS_TIME) {
qDebug() << "WARNING -- unexpectedly large lastStatsCalculationTime=" << lastStatsCalculationTime;
}
hasStatsCalculationTime = true;
}
}
delete[] inputBuffer;