diff options
author | Pierre Ossman <ossman@cendio.se> | 2015-02-11 17:43:15 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2015-02-13 11:13:53 +0100 |
commit | 20dd2a92de600752a70224836b1c713f962dc475 (patch) | |
tree | 58fa4c9046a7c63fcbe3dddfdb8948fcacd77888 /common | |
parent | a43a3f4e0e1ae9faa389a91ad9a38db4af4c54c8 (diff) | |
download | tigervnc-20dd2a92de600752a70224836b1c713f962dc475.tar.gz tigervnc-20dd2a92de600752a70224836b1c713f962dc475.zip |
Move encoder statistics into EncodeManager from SMsgWriter
It knows more details so it can track things better.
Diffstat (limited to 'common')
-rw-r--r-- | common/rfb/EncodeManager.cxx | 154 | ||||
-rw-r--r-- | common/rfb/EncodeManager.h | 18 | ||||
-rw-r--r-- | common/rfb/SMsgWriter.cxx | 30 | ||||
-rw-r--r-- | common/rfb/SMsgWriter.h | 13 |
4 files changed, 168 insertions, 47 deletions
diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx index ca60da48..cd80df97 100644 --- a/common/rfb/EncodeManager.cxx +++ b/common/rfb/EncodeManager.cxx @@ -23,6 +23,7 @@ #include <rfb/SConnection.h> #include <rfb/SMsgWriter.h> #include <rfb/UpdateTracker.h> +#include <rfb/LogWriter.h> #include <rfb/RawEncoder.h> #include <rfb/RREEncoder.h> @@ -33,6 +34,8 @@ using namespace rfb; +static LogWriter vlog("EncodeManager"); + // Split each rectangle into smaller ones no larger than this area, // and no wider than this width. static const int SubRectMaxArea = 65536; @@ -73,8 +76,50 @@ struct RectInfo { }; +static const char *encoderClassName(EncoderClass klass) +{ + switch (klass) { + case encoderRaw: + return "Raw"; + case encoderRRE: + return "RRE"; + case encoderHextile: + return "Hextile"; + case encoderTight: + return "Tight"; + case encoderTightJPEG: + return "Tight (JPEG)"; + case encoderZRLE: + return "ZRLE"; + } + + return "Unknown Encoder Class"; +} + +static const char *encoderTypeName(EncoderType type) +{ + switch (type) { + case encoderSolid: + return "Solid"; + case encoderBitmap: + return "Bitmap"; + case encoderBitmapRLE: + return "Bitmap RLE"; + case encoderIndexed: + return "Indexed"; + case encoderIndexedRLE: + return "Indexed RLE"; + case encoderFullColour: + return "Full Colour"; + } + + return "Unknown Encoder Type"; +} + EncodeManager::EncodeManager(SConnection* conn_) : conn(conn_) { + StatsVector::iterator iter; + encoders.resize(encoderClassMax, NULL); activeEncoders.resize(encoderTypeMax, encoderRaw); @@ -84,16 +129,78 @@ EncodeManager::EncodeManager(SConnection* conn_) : conn(conn_) encoders[encoderTight] = new TightEncoder(conn); encoders[encoderTightJPEG] = new TightJPEGEncoder(conn); encoders[encoderZRLE] = new ZRLEEncoder(conn); + + updates = 0; + stats.resize(encoderClassMax); + for (iter = stats.begin();iter != stats.end();++iter) { + StatsVector::value_type::iterator iter2; + iter->resize(encoderTypeMax); + for (iter2 = iter->begin();iter2 != iter->end();++iter2) + memset(&*iter2, 0, sizeof(EncoderStats)); + } } EncodeManager::~EncodeManager() { std::vector<Encoder*>::iterator iter; + logStats(); + for (iter = encoders.begin();iter != encoders.end();iter++) delete *iter; } +void EncodeManager::logStats() +{ + int i, j; + + unsigned rects; + unsigned long long pixels, bytes, equivalent; + + double ratio; + + rects = 0; + pixels = bytes = equivalent = 0; + + vlog.info("Framebuffer updates: %u", updates); + + for (i = 0;i < stats.size();i++) { + // Did this class do anything at all? + for (j = 0;j < stats[i].size();j++) { + if (stats[i][j].rects != 0) + break; + } + if (j == stats[i].size()) + continue; + + vlog.info(" %s:", encoderClassName((EncoderClass)i)); + + for (j = 0;j < stats[i].size();j++) { + if (stats[i][j].rects == 0) + continue; + + rects += stats[i][j].rects; + pixels += stats[i][j].pixels; + bytes += stats[i][j].bytes; + equivalent += stats[i][j].equivalent; + + ratio = (double)stats[i][j].equivalent / stats[i][j].bytes; + + vlog.info(" %s: %u rects, %llu pixels", + encoderTypeName((EncoderType)j), + stats[i][j].rects, stats[i][j].pixels); + vlog.info(" %*s %llu bytes (%g ratio)", + strlen(encoderTypeName((EncoderType)j)), "", + stats[i][j].bytes, ratio); + } + } + + ratio = (double)equivalent / bytes; + + vlog.info(" Total: %u rects, %llu pixels", rects, pixels); + vlog.info(" %llu bytes (%g ratio)", bytes, ratio); +} + bool EncodeManager::supported(int encoding) { switch (encoding) { @@ -114,6 +221,8 @@ void EncodeManager::writeUpdate(const UpdateInfo& ui, const PixelBuffer* pb, int nRects; Region changed; + updates++; + prepareEncoders(); if (conn->cp.supportsLastRect) @@ -292,6 +401,40 @@ int EncodeManager::computeNumRects(const Region& changed) return numRects; } +Encoder *EncodeManager::startRect(const Rect& rect, int type) +{ + Encoder *encoder; + int klass, equiv; + + activeType = type; + klass = activeEncoders[activeType]; + + beforeLength = conn->getOutStream()->length(); + + stats[klass][activeType].rects++; + stats[klass][activeType].pixels += rect.area(); + equiv = 12 + rect.area() * conn->cp.pf().bpp/8; + stats[klass][activeType].equivalent += equiv; + + encoder = encoders[klass]; + conn->writer()->startRect(rect, encoder->encoding); + + return encoder; +} + +void EncodeManager::endRect() +{ + int klass; + int length; + + conn->writer()->endRect(); + + length = conn->getOutStream()->length() - beforeLength; + + klass = activeEncoders[activeType]; + stats[klass][activeType].bytes += length; +} + void EncodeManager::writeCopyRects(const UpdateInfo& ui) { std::vector<Rect> rects; @@ -362,8 +505,7 @@ void EncodeManager::writeSolidRects(Region *changed, const PixelBuffer* pb) } // Send solid-color rectangle. - encoder = encoders[activeEncoders[encoderSolid]]; - conn->writer()->startRect(erp, encoder->encoding); + encoder = startRect(erp, encoderSolid); if (encoder->flags & EncoderUseNativePF) { encoder->writeSolidRect(erp.width(), erp.height(), pb->getPF(), colourValue); @@ -377,7 +519,7 @@ void EncodeManager::writeSolidRects(Region *changed, const PixelBuffer* pb) encoder->writeSolidRect(erp.width(), erp.height(), conn->cp.pf(), converted); } - conn->writer()->endRect(); + endRect(); changed->assign_subtract(Region(erp)); @@ -507,14 +649,14 @@ void EncodeManager::writeSubRect(const Rect& rect, const PixelBuffer *pb) type = encoderIndexed; } - encoder = encoders[activeEncoders[type]]; + encoder = startRect(rect, type); if (encoder->flags & EncoderUseNativePF) ppb = preparePixelBuffer(rect, pb, false); - conn->writer()->startRect(rect, encoder->encoding); encoder->writeRect(ppb, info.palette); - conn->writer()->endRect(); + + endRect(); } bool EncodeManager::checkSolidTile(const Rect& r, const rdr::U8* colourValue, diff --git a/common/rfb/EncodeManager.h b/common/rfb/EncodeManager.h index df0275ce..a694e063 100644 --- a/common/rfb/EncodeManager.h +++ b/common/rfb/EncodeManager.h @@ -41,6 +41,8 @@ namespace rfb { EncodeManager(SConnection* conn); ~EncodeManager(); + void logStats(); + // Hack to let ConnParams calculate the client's preferred encoding static bool supported(int encoding); @@ -52,6 +54,9 @@ namespace rfb { int computeNumRects(const Region& changed); + Encoder *startRect(const Rect& rect, int type); + void endRect(); + void writeCopyRects(const UpdateInfo& ui); void writeSolidRects(Region *changed, const PixelBuffer* pb); void writeRects(const Region& changed, const PixelBuffer* pb); @@ -97,6 +102,19 @@ namespace rfb { std::vector<Encoder*> encoders; std::vector<int> activeEncoders; + struct EncoderStats { + unsigned rects; + unsigned long long bytes; + unsigned long long pixels; + unsigned long long equivalent; + }; + typedef std::vector< std::vector<struct EncoderStats> > StatsVector; + + unsigned updates; + StatsVector stats; + int activeType; + int beforeLength; + class OffsetPixelBuffer : public FullFramePixelBuffer { public: OffsetPixelBuffer() {} diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index 0d61292c..9aee96d2 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -33,31 +33,15 @@ using namespace rfb; static LogWriter vlog("SMsgWriter"); SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_) - : cp(cp_), os(os_), currentEncoding(0), + : cp(cp_), os(os_), nRectsInUpdate(0), nRectsInHeader(0), needSetDesktopSize(false), needExtendedDesktopSize(false), - needSetDesktopName(false), needSetCursor(false), needSetXCursor(false), - lenBeforeRect(0), updatesSent(0), rawBytesEquivalent(0) + needSetDesktopName(false), needSetCursor(false), needSetXCursor(false) { - for (int i = 0; i <= encodingMax; i++) { - bytesSent[i] = 0; - rectsSent[i] = 0; - } } SMsgWriter::~SMsgWriter() { - vlog.info("framebuffer updates %d",updatesSent); - int bytes = 0; - for (int i = 0; i <= encodingMax; i++) { - if (i != encodingCopyRect) - bytes += bytesSent[i]; - if (rectsSent[i]) - vlog.info(" %s rects %d, bytes %d", - encodingName(i), rectsSent[i], bytesSent[i]); - } - vlog.info(" raw bytes equivalent %llu, compression ratio %f", - rawBytesEquivalent, (double)rawBytesEquivalent / bytes); } void SMsgWriter::writeServerInit() @@ -276,7 +260,6 @@ void SMsgWriter::writeFramebufferUpdateEnd() os->writeU32(pseudoEncodingLastRect); } - updatesSent++; endMsg(); } @@ -293,11 +276,6 @@ void SMsgWriter::startRect(const Rect& r, int encoding) if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) throw Exception("SMsgWriter::startRect: nRects out of sync"); - currentEncoding = encoding; - lenBeforeRect = os->length(); - if (encoding != encodingCopyRect) - rawBytesEquivalent += 12 + r.width() * r.height() * (cp->pf().bpp/8); - os->writeS16(r.tl.x); os->writeS16(r.tl.y); os->writeU16(r.width()); @@ -307,10 +285,6 @@ void SMsgWriter::startRect(const Rect& r, int encoding) void SMsgWriter::endRect() { - if (currentEncoding <= encodingMax) { - bytesSent[currentEncoding] += os->length() - lenBeforeRect; - rectsSent[currentEncoding]++; - } } void SMsgWriter::startMsg(int type) diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index deddd3cd..917b933c 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -109,11 +109,6 @@ namespace rfb { void startRect(const Rect& r, int enc); void endRect(); - int getUpdatesSent() { return updatesSent; } - int getRectsSent(int encoding) { return rectsSent[encoding]; } - int getBytesSent(int encoding) { return bytesSent[encoding]; } - rdr::U64 getRawBytesEquivalent() { return rawBytesEquivalent; } - protected: void startMsg(int type); void endMsg(); @@ -137,8 +132,6 @@ namespace rfb { ConnParams* cp; rdr::OutStream* os; - int currentEncoding; - int nRectsInUpdate; int nRectsInHeader; @@ -149,12 +142,6 @@ namespace rfb { bool needSetCursor; bool needSetXCursor; - int lenBeforeRect; - int updatesSent; - int bytesSent[encodingMax+1]; - int rectsSent[encodingMax+1]; - rdr::U64 rawBytesEquivalent; - typedef struct { rdr::U16 reason, result; int fb_width, fb_height; |