aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2021-11-04 09:16:00 +0100
committerPierre Ossman <ossman@cendio.se>2021-11-04 09:18:13 +0100
commit08554668c2c3b9b50c4b06188fc95b75b9e70628 (patch)
treee043cbd5c5463a47f0c63e4e94a830ba0ef637ea
parent479ec11a2ee29a5321a28118c2d69307d752e216 (diff)
downloadtigervnc-08554668c2c3b9b50c4b06188fc95b75b9e70628.tar.gz
tigervnc-08554668c2c3b9b50c4b06188fc95b75b9e70628.zip
Log decoding stats on disconnect
Can be helpful to see what encodings were actually used during a connection, and how they performed.
-rw-r--r--common/rfb/DecodeManager.cxx55
-rw-r--r--common/rfb/DecodeManager.h11
2 files changed, 66 insertions, 0 deletions
diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx
index 720aabed..b05683bb 100644
--- a/common/rfb/DecodeManager.cxx
+++ b/common/rfb/DecodeManager.cxx
@@ -43,6 +43,8 @@ DecodeManager::DecodeManager(CConnection *conn) :
memset(decoders, 0, sizeof(decoders));
+ memset(stats, 0, sizeof(stats));
+
queueMutex = new os::Mutex();
producerCond = new os::Condition(queueMutex);
consumerCond = new os::Condition(queueMutex);
@@ -73,6 +75,8 @@ DecodeManager::DecodeManager(CConnection *conn) :
DecodeManager::~DecodeManager()
{
+ logStats();
+
while (!threads.empty()) {
delete threads.back();
threads.pop_back();
@@ -98,6 +102,7 @@ bool DecodeManager::decodeRect(const Rect& r, int encoding,
{
Decoder *decoder;
rdr::MemOutStream *bufferStream;
+ int equiv;
QueueEntry *entry;
@@ -143,6 +148,12 @@ bool DecodeManager::decodeRect(const Rect& r, int encoding,
throw Exception("Error reading rect: %s", e.str());
}
+ stats[encoding].rects++;
+ stats[encoding].bytes += 12 + bufferStream->length();
+ stats[encoding].pixels += r.area();
+ equiv = 12 + r.area() * (conn->server.pf().bpp/8);
+ stats[encoding].equivalent += equiv;
+
// Then try to put it on the queue
entry = new QueueEntry;
@@ -187,6 +198,50 @@ void DecodeManager::flush()
throwThreadException();
}
+void DecodeManager::logStats()
+{
+ size_t i;
+
+ unsigned rects;
+ unsigned long long pixels, bytes, equivalent;
+
+ double ratio;
+
+ char a[1024], b[1024];
+
+ rects = 0;
+ pixels = bytes = equivalent = 0;
+
+ for (i = 0;i < (sizeof(stats)/sizeof(stats[0]));i++) {
+ // Did this class do anything at all?
+ if (stats[i].rects == 0)
+ continue;
+
+ rects += stats[i].rects;
+ pixels += stats[i].pixels;
+ bytes += stats[i].bytes;
+ equivalent += stats[i].equivalent;
+
+ ratio = (double)stats[i].equivalent / stats[i].bytes;
+
+ siPrefix(stats[i].rects, "rects", a, sizeof(a));
+ siPrefix(stats[i].pixels, "pixels", b, sizeof(b));
+ vlog.info(" %s: %s, %s", encodingName(i), a, b);
+ iecPrefix(stats[i].bytes, "B", a, sizeof(a));
+ vlog.info(" %*s %s (1:%g ratio)",
+ (int)strlen(encodingName(i)), "",
+ a, ratio);
+ }
+
+ ratio = (double)equivalent / bytes;
+
+ siPrefix(rects, "rects", a, sizeof(a));
+ siPrefix(pixels, "pixels", b, sizeof(b));
+ vlog.info(" Total: %s, %s", a, b);
+ iecPrefix(bytes, "B", a, sizeof(a));
+ vlog.info(" %s (1:%g ratio)", a, ratio);
+}
+
void DecodeManager::setThreadException(const rdr::Exception& e)
{
os::AutoMutex a(queueMutex);
diff --git a/common/rfb/DecodeManager.h b/common/rfb/DecodeManager.h
index 289686b5..a8e0cac9 100644
--- a/common/rfb/DecodeManager.h
+++ b/common/rfb/DecodeManager.h
@@ -53,6 +53,8 @@ namespace rfb {
void flush();
private:
+ void logStats();
+
void setThreadException(const rdr::Exception& e);
void throwThreadException();
@@ -60,6 +62,15 @@ namespace rfb {
CConnection *conn;
Decoder *decoders[encodingMax+1];
+ struct DecoderStats {
+ unsigned rects;
+ unsigned long long bytes;
+ unsigned long long pixels;
+ unsigned long long equivalent;
+ };
+
+ DecoderStats stats[encodingMax+1];
+
struct QueueEntry {
bool active;
Rect rect;