From 08554668c2c3b9b50c4b06188fc95b75b9e70628 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 4 Nov 2021 09:16:00 +0100 Subject: [PATCH] Log decoding stats on disconnect Can be helpful to see what encodings were actually used during a connection, and how they performed. --- common/rfb/DecodeManager.cxx | 55 ++++++++++++++++++++++++++++++++++++ common/rfb/DecodeManager.h | 11 ++++++++ 2 files changed, 66 insertions(+) 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; -- 2.39.5