From 0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 9 Jul 2014 16:44:11 +0200 Subject: [PATCH] Use PixelBuffer objects as the interface for encoders and decoders This avoid a lot of unnecessary middle men. This also pushes the responsibility for pixel format conversion into the encoders and decoders. The new bufferFromBuffer() is used for direct conversion, rather than PixelTransformer/TransImageGetter. --- common/rfb/CMsgHandler.h | 9 --- common/rfb/CopyRectDecoder.cxx | 5 +- common/rfb/CopyRectDecoder.h | 2 +- common/rfb/Decoder.h | 10 ++- common/rfb/Encoder.h | 11 +-- common/rfb/HextileDecoder.cxx | 13 ++-- common/rfb/HextileDecoder.h | 2 +- common/rfb/HextileEncoder.cxx | 20 +++--- common/rfb/HextileEncoder.h | 2 +- common/rfb/RREDecoder.cxx | 13 ++-- common/rfb/RREDecoder.h | 2 +- common/rfb/RREEncoder.cxx | 9 +-- common/rfb/RREEncoder.h | 2 +- common/rfb/RawDecoder.cxx | 9 +-- common/rfb/RawDecoder.h | 2 +- common/rfb/RawEncoder.cxx | 24 ++----- common/rfb/RawEncoder.h | 2 +- common/rfb/TightDecoder.cxx | 10 +-- common/rfb/TightDecoder.h | 4 +- common/rfb/TightEncoder.cxx | 13 ++-- common/rfb/TightEncoder.h | 6 +- common/rfb/VNCSConnectionST.cxx | 30 ++++---- common/rfb/VNCSConnectionST.h | 2 - common/rfb/VNCServerST.cxx | 1 - common/rfb/VNCServerST.h | 9 +-- common/rfb/ZRLEDecoder.cxx | 19 +++-- common/rfb/ZRLEDecoder.h | 2 +- common/rfb/ZRLEEncoder.cxx | 19 +++-- common/rfb/ZRLEEncoder.h | 2 +- common/rfb/hextileDecode.h | 6 +- common/rfb/hextileEncode.h | 7 +- common/rfb/hextileEncodeBetter.h | 5 +- common/rfb/rreDecode.h | 7 +- common/rfb/tightDecode.h | 12 ++-- common/rfb/tightEncode.h | 21 +++--- common/rfb/zrleDecode.h | 6 +- common/rfb/zrleEncode.h | 5 +- vncviewer/CConn.cxx | 27 +------ vncviewer/CConn.h | 10 --- vncviewer/DesktopWindow.cxx | 27 +------ vncviewer/DesktopWindow.h | 16 ++--- vncviewer/PlatformPixelBuffer.cxx | 16 +++++ vncviewer/PlatformPixelBuffer.h | 6 ++ vncviewer/Viewport.cxx | 114 +++--------------------------- vncviewer/Viewport.h | 24 ++----- 45 files changed, 200 insertions(+), 363 deletions(-) diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h index 8b58e0e5..8e3c84ed 100644 --- a/common/rfb/CMsgHandler.h +++ b/common/rfb/CMsgHandler.h @@ -66,15 +66,6 @@ namespace rfb { virtual void bell() = 0; virtual void serverCutText(const char* str, rdr::U32 len) = 0; - virtual void fillRect(const Rect& r, Pixel pix) = 0; - virtual void imageRect(const Rect& r, void* pixels) = 0; - virtual void copyRect(const Rect& r, int srcX, int srcY) = 0; - - virtual rdr::U8* getRawBufferRW(const Rect& r, int* stride) = 0; - virtual void releaseRawBuffer(const Rect& r) = 0; - - virtual const PixelFormat &getPreferredPF(void) = 0; - ConnParams cp; }; } diff --git a/common/rfb/CopyRectDecoder.cxx b/common/rfb/CopyRectDecoder.cxx index bb3084fd..4b104189 100644 --- a/common/rfb/CopyRectDecoder.cxx +++ b/common/rfb/CopyRectDecoder.cxx @@ -17,7 +17,6 @@ */ #include #include -#include #include #include @@ -31,9 +30,9 @@ CopyRectDecoder::~CopyRectDecoder() { } -void CopyRectDecoder::readRect(const Rect& r, CMsgHandler* handler) +void CopyRectDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { int srcX = conn->getInStream()->readU16(); int srcY = conn->getInStream()->readU16(); - handler->copyRect(r, srcX, srcY); + pb->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY)); } diff --git a/common/rfb/CopyRectDecoder.h b/common/rfb/CopyRectDecoder.h index 5932066b..d14bf926 100644 --- a/common/rfb/CopyRectDecoder.h +++ b/common/rfb/CopyRectDecoder.h @@ -26,7 +26,7 @@ namespace rfb { public: CopyRectDecoder(CConnection* conn); virtual ~CopyRectDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); }; } #endif diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h index 870fa80e..ff67f578 100644 --- a/common/rfb/Decoder.h +++ b/common/rfb/Decoder.h @@ -23,13 +23,19 @@ namespace rfb { class CConnection; - class CMsgHandler; + class ModifiablePixelBuffer; class Decoder { public: Decoder(CConnection* conn); virtual ~Decoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler)=0; + + // readRect() is the main interface that decodes the given rectangle + // with data from the CConnection, given at decoder creation, onto + // the ModifiablePixelBuffer. The PixelFormat of the PixelBuffer might + // not match the ConnParams and it is up to the decoder to do + // any necessary conversion. + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb)=0; static bool supported(int encoding); static Decoder* createDecoder(int encoding, CConnection* conn); diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h index 2897f9f8..aeeb5c34 100644 --- a/common/rfb/Encoder.h +++ b/common/rfb/Encoder.h @@ -21,11 +21,10 @@ #define __RFB_ENCODER_H__ #include -#include namespace rfb { class SConnection; - class TransImageGetter; + class PixelBuffer; class Encoder { public: @@ -38,9 +37,11 @@ namespace rfb { virtual int getNumRects(const Rect &r) { return 1; } // writeRect() is the main interface that encodes the given rectangle - // with data from the ImageGetter onto the SMsgWriter given at - // encoder creation. - virtual void writeRect(const Rect& r, TransImageGetter* ig)=0; + // with data from the PixelBuffer onto the SConnection given at + // encoder creation. The PixelFormat of the PixelBuffer might not + // match the ConnParams and it is up ot the encoder to do + // any necessary conversion. + virtual void writeRect(const Rect& r, PixelBuffer* pb)=0; static bool supported(int encoding); static Encoder* createEncoder(int encoding, SConnection* conn); diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx index 9b335fe9..8b18b7bf 100644 --- a/common/rfb/HextileDecoder.cxx +++ b/common/rfb/HextileDecoder.cxx @@ -17,7 +17,7 @@ */ #include #include -#include +#include #include using namespace rfb; @@ -40,13 +40,14 @@ HextileDecoder::~HextileDecoder() { } -void HextileDecoder::readRect(const Rect& r, CMsgHandler* handler) +void HextileDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { rdr::InStream* is = conn->getInStream(); rdr::U8* buf = conn->reader()->getImageBuf(16 * 16 * 4); - switch (conn->cp.pf().bpp) { - case 8: hextileDecode8 (r, is, (rdr::U8*) buf, handler); break; - case 16: hextileDecode16(r, is, (rdr::U16*)buf, handler); break; - case 32: hextileDecode32(r, is, (rdr::U32*)buf, handler); break; + const PixelFormat& pf = conn->cp.pf(); + switch (pf.bpp) { + case 8: hextileDecode8 (r, is, (rdr::U8*) buf, pf, pb); break; + case 16: hextileDecode16(r, is, (rdr::U16*)buf, pf, pb); break; + case 32: hextileDecode32(r, is, (rdr::U32*)buf, pf, pb); break; } } diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h index 67dc791a..ffc495e4 100644 --- a/common/rfb/HextileDecoder.h +++ b/common/rfb/HextileDecoder.h @@ -26,7 +26,7 @@ namespace rfb { public: HextileDecoder(CConnection* conn); virtual ~HextileDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); }; } #endif diff --git a/common/rfb/HextileEncoder.cxx b/common/rfb/HextileEncoder.cxx index aa1b218a..58cf7414 100644 --- a/common/rfb/HextileEncoder.cxx +++ b/common/rfb/HextileEncoder.cxx @@ -16,11 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ -#include #include #include #include #include +#include +#include #include using namespace rfb; @@ -52,30 +53,31 @@ HextileEncoder::~HextileEncoder() { } -void HextileEncoder::writeRect(const Rect& r, TransImageGetter* ig) +void HextileEncoder::writeRect(const Rect& r, PixelBuffer* pb) { conn->writer()->startRect(r, encodingHextile); rdr::OutStream* os = conn->getOutStream(); - switch (conn->cp.pf().bpp) { + const PixelFormat& pf = conn->cp.pf(); + switch (pf.bpp) { case 8: if (improvedHextile) { - hextileEncodeBetter8(r, os, ig); + hextileEncodeBetter8(r, os, pf, pb); } else { - hextileEncode8(r, os, ig); + hextileEncode8(r, os, pf, pb); } break; case 16: if (improvedHextile) { - hextileEncodeBetter16(r, os, ig); + hextileEncodeBetter16(r, os, pf, pb); } else { - hextileEncode16(r, os, ig); + hextileEncode16(r, os, pf, pb); } break; case 32: if (improvedHextile) { - hextileEncodeBetter32(r, os, ig); + hextileEncodeBetter32(r, os, pf, pb); } else { - hextileEncode32(r, os, ig); + hextileEncode32(r, os, pf, pb); } break; } diff --git a/common/rfb/HextileEncoder.h b/common/rfb/HextileEncoder.h index 723f5391..82fa2ec7 100644 --- a/common/rfb/HextileEncoder.h +++ b/common/rfb/HextileEncoder.h @@ -26,7 +26,7 @@ namespace rfb { public: HextileEncoder(SConnection* conn); virtual ~HextileEncoder(); - virtual void writeRect(const Rect& r, TransImageGetter* ig); + virtual void writeRect(const Rect& r, PixelBuffer* pb); }; } #endif diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx index ecc97136..8dc391a8 100644 --- a/common/rfb/RREDecoder.cxx +++ b/common/rfb/RREDecoder.cxx @@ -17,7 +17,7 @@ */ #include #include -#include +#include #include using namespace rfb; @@ -40,12 +40,13 @@ RREDecoder::~RREDecoder() { } -void RREDecoder::readRect(const Rect& r, CMsgHandler* handler) +void RREDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { rdr::InStream* is = conn->getInStream(); - switch (conn->cp.pf().bpp) { - case 8: rreDecode8 (r, is, handler); break; - case 16: rreDecode16(r, is, handler); break; - case 32: rreDecode32(r, is, handler); break; + const PixelFormat& pf = conn->cp.pf(); + switch (pf.bpp) { + case 8: rreDecode8 (r, is, pf, pb); break; + case 16: rreDecode16(r, is, pf, pb); break; + case 32: rreDecode32(r, is, pf, pb); break; } } diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h index 7b6cc458..b33bc551 100644 --- a/common/rfb/RREDecoder.h +++ b/common/rfb/RREDecoder.h @@ -26,7 +26,7 @@ namespace rfb { public: RREDecoder(CConnection* conn); virtual ~RREDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); }; } #endif diff --git a/common/rfb/RREEncoder.cxx b/common/rfb/RREEncoder.cxx index a7af25db..6e23ad33 100644 --- a/common/rfb/RREEncoder.cxx +++ b/common/rfb/RREEncoder.cxx @@ -16,10 +16,11 @@ * USA. */ #include -#include #include #include #include +#include +#include #include using namespace rfb; @@ -42,12 +43,12 @@ RREEncoder::~RREEncoder() { } -void RREEncoder::writeRect(const Rect& r, TransImageGetter* ig) +void RREEncoder::writeRect(const Rect& r, PixelBuffer* pb) { int w = r.width(); int h = r.height(); rdr::U8* imageBuf = conn->writer()->getImageBuf(w*h); - ig->getImage(imageBuf, r); + pb->getImage(conn->cp.pf(), imageBuf, r); mos.clear(); @@ -59,7 +60,7 @@ void RREEncoder::writeRect(const Rect& r, TransImageGetter* ig) } if (nSubrects < 0) { - RawEncoder::writeRect(r, ig); + RawEncoder::writeRect(r, pb); return; } diff --git a/common/rfb/RREEncoder.h b/common/rfb/RREEncoder.h index 487344f2..57c15840 100644 --- a/common/rfb/RREEncoder.h +++ b/common/rfb/RREEncoder.h @@ -27,7 +27,7 @@ namespace rfb { public: RREEncoder(SConnection* conn); virtual ~RREEncoder(); - virtual void writeRect(const Rect& r, TransImageGetter* ig); + virtual void writeRect(const Rect& r, PixelBuffer* pb); private: rdr::MemOutStream mos; }; diff --git a/common/rfb/RawDecoder.cxx b/common/rfb/RawDecoder.cxx index 6ca02026..d2b3d06d 100644 --- a/common/rfb/RawDecoder.cxx +++ b/common/rfb/RawDecoder.cxx @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include using namespace rfb; @@ -31,7 +31,7 @@ RawDecoder::~RawDecoder() { } -void RawDecoder::readRect(const Rect& r, CMsgHandler* handler) +void RawDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { int x = r.tl.x; int y = r.tl.y; @@ -39,12 +39,13 @@ void RawDecoder::readRect(const Rect& r, CMsgHandler* handler) int h = r.height(); int nPixels; rdr::U8* imageBuf = conn->reader()->getImageBuf(w, w*h, &nPixels); - int bytesPerRow = w * (conn->cp.pf().bpp / 8); + const PixelFormat& pf = conn->cp.pf(); + int bytesPerRow = w * (pf.bpp / 8); while (h > 0) { int nRows = nPixels / w; if (nRows > h) nRows = h; conn->getInStream()->readBytes(imageBuf, nRows * bytesPerRow); - handler->imageRect(Rect(x, y, x+w, y+nRows), imageBuf); + pb->imageRect(pf, Rect(x, y, x+w, y+nRows), imageBuf); h -= nRows; y += nRows; } diff --git a/common/rfb/RawDecoder.h b/common/rfb/RawDecoder.h index ca7c4017..7a784c64 100644 --- a/common/rfb/RawDecoder.h +++ b/common/rfb/RawDecoder.h @@ -26,7 +26,7 @@ namespace rfb { public: RawDecoder(CConnection* conn); virtual ~RawDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); }; } #endif diff --git a/common/rfb/RawEncoder.cxx b/common/rfb/RawEncoder.cxx index f7a4f3b8..e50ebc70 100644 --- a/common/rfb/RawEncoder.cxx +++ b/common/rfb/RawEncoder.cxx @@ -16,10 +16,10 @@ * USA. */ #include -#include #include #include #include +#include #include using namespace rfb; @@ -32,23 +32,13 @@ RawEncoder::~RawEncoder() { } -void RawEncoder::writeRect(const Rect& r, TransImageGetter* ig) +void RawEncoder::writeRect(const Rect& r, PixelBuffer* pb) { - int x = r.tl.x; - int y = r.tl.y; - int w = r.width(); - int h = r.height(); - int nPixels; - rdr::U8* imageBuf = conn->writer()->getImageBuf(w, w*h, &nPixels); - int bytesPerRow = w * (conn->cp.pf().bpp / 8); + rdr::U8* buf = conn->writer()->getImageBuf(r.area()); + + pb->getImage(conn->cp.pf(), buf, r); + conn->writer()->startRect(r, encodingRaw); - while (h > 0) { - int nRows = nPixels / w; - if (nRows > h) nRows = h; - ig->getImage(imageBuf, Rect(x, y, x+w, y+nRows)); - conn->getOutStream()->writeBytes(imageBuf, nRows * bytesPerRow); - h -= nRows; - y += nRows; - } + conn->getOutStream()->writeBytes(buf, r.area() * conn->cp.pf().bpp/8); conn->writer()->endRect(); } diff --git a/common/rfb/RawEncoder.h b/common/rfb/RawEncoder.h index 59e3a6de..c2d9f250 100644 --- a/common/rfb/RawEncoder.h +++ b/common/rfb/RawEncoder.h @@ -26,7 +26,7 @@ namespace rfb { public: RawEncoder(SConnection* conn); virtual ~RawEncoder(); - virtual void writeRect(const Rect& r, TransImageGetter* ig); + virtual void writeRect(const Rect& r, PixelBuffer* pb); }; } #endif diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx index bfc3352b..5f4142b4 100644 --- a/common/rfb/TightDecoder.cxx +++ b/common/rfb/TightDecoder.cxx @@ -19,7 +19,7 @@ */ #include #include -#include +#include #include using namespace rfb; @@ -44,12 +44,12 @@ TightDecoder::~TightDecoder() { } -void TightDecoder::readRect(const Rect& r, CMsgHandler* handler) +void TightDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { is = conn->getInStream(); - this->handler = handler; - clientpf = handler->getPreferredPF(); - serverpf = handler->cp.pf(); + this->pb = pb; + clientpf = pb->getPF(); + serverpf = conn->cp.pf(); if (clientpf.equal(serverpf)) { /* Decode directly into the framebuffer (fast path) */ diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h index 2ca4ecd6..66fa9a0c 100644 --- a/common/rfb/TightDecoder.h +++ b/common/rfb/TightDecoder.h @@ -30,7 +30,7 @@ namespace rfb { public: TightDecoder(CConnection* conn); virtual ~TightDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); private: rdr::U32 readCompact(rdr::InStream* is); @@ -56,7 +56,7 @@ namespace rfb { void directFillRect16(const Rect& r, Pixel pix); void directFillRect32(const Rect& r, Pixel pix); - CMsgHandler* handler; + ModifiablePixelBuffer* pb; rdr::InStream* is; rdr::ZlibInStream zis[4]; JpegDecompressor jd; diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx index c3f87dab..cdc23c4e 100644 --- a/common/rfb/TightEncoder.cxx +++ b/common/rfb/TightEncoder.cxx @@ -17,7 +17,6 @@ * USA. */ #include -#include #include #include #include @@ -287,10 +286,10 @@ void TightEncoder::sendRectSimple(const Rect& r) } } -void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig) +void TightEncoder::writeRect(const Rect& _r, PixelBuffer* _pb) { - ig = _ig; - serverpf = ig->getPixelBuffer()->getPF(); + pb = _pb; + serverpf = pb->getPF(); ConnParams* cp = &conn->cp; clientpf = cp->pf(); @@ -366,7 +365,7 @@ void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig) } if (bestr.tl.x != x) { sr.setXYWH(x, bestr.tl.y, bestr.tl.x - x, bestr.height()); - writeRect(sr, _ig); + writeRect(sr, _pb); } // Send solid-color rectangle. @@ -376,11 +375,11 @@ void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig) if (bestr.br.x != r.br.x) { sr.setXYWH(bestr.br.x, bestr.tl.y, r.br.x - bestr.br.x, bestr.height()); - writeRect(sr, _ig); + writeRect(sr, _pb); } if (bestr.br.y != r.br.y) { sr.setXYWH(x, bestr.br.y, w, r.br.y - bestr.br.y); - writeRect(sr, _ig); + writeRect(sr, _pb); } return; diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h index 8a58985e..89d096b2 100644 --- a/common/rfb/TightEncoder.h +++ b/common/rfb/TightEncoder.h @@ -33,7 +33,7 @@ extern "C" { namespace rfb { - class TransImageGetter; + class PixelBuffer; struct TIGHT_CONF { unsigned int maxRectSize, maxRectWidth; @@ -65,7 +65,7 @@ namespace rfb { virtual void setQualityLevel(int level); virtual void setFineQualityLevel(int quality, int subsampling); virtual int getNumRects(const Rect &r); - virtual void writeRect(const Rect& r, TransImageGetter* ig); + virtual void writeRect(const Rect& r, PixelBuffer* pb); private: bool checkSolidTile(Rect& r, rdr::U32* colorPtr, bool needSameColor); @@ -123,7 +123,7 @@ namespace rfb { rdr::MemOutStream mos; rdr::ZlibOutStream zos[4]; JpegCompressor jc; - TransImageGetter *ig; + PixelBuffer *pb; PixelFormat serverpf, clientpf; bool pack24; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index e7123000..e1424b72 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -71,8 +71,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, fenceDataLen(0), fenceData(NULL), baseRTT(-1), minRTT(-1), seenCongestion(false), pingCounter(0), ackedOffset(0), sentOffset(0), congWindow(0), congestionTimer(this), - server(server_), - updates(false), image_getter(server->useEconomicTranslate), + server(server_), updates(false), drawRenderedCursor(false), removeRenderedCursor(false), continuousUpdates(false), updateTimer(this), pointerEventTime(0), @@ -233,8 +232,6 @@ void VNCSConnectionST::pixelBufferChange() // work out what's actually changed. updates.clear(); updates.add_changed(server->pb->getRect()); - vlog.debug("pixel buffer changed - re-initialising image getter"); - image_getter.init(server->pb, cp.pf(), writer()); writeFramebufferUpdate(); } catch(rdr::Exception &e) { close(e.str()); @@ -404,7 +401,6 @@ void VNCSConnectionST::authSuccess() char buffer[256]; cp.pf().print(buffer, 256); vlog.info("Server default pixel format %s", buffer); - image_getter.init(server->pb, cp.pf(), 0); // - Mark the entire display as "dirty" updates.add_changed(server->pb->getRect()); @@ -478,7 +474,6 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf) char buffer[256]; pf.print(buffer, 256); vlog.info("Client pixel format %s", buffer); - image_getter.init(server->pb, pf, writer()); setCursor(); } @@ -1036,16 +1031,20 @@ void VNCSConnectionST::writeFramebufferUpdate() std::vector::const_iterator i; int encoding; + Encoder* encoder; + PixelBuffer* pb; + // Make sure the encoder has the latest settings encoding = cp.currentEncoding(); if (!encoders[encoding]) encoders[encoding] = Encoder::createEncoder(encoding, this); - encoders[encoding]->setCompressLevel(cp.compressLevel); - encoders[encoding]->setQualityLevel(cp.qualityLevel); - encoders[encoding]->setFineQualityLevel(cp.fineQualityLevel, - cp.subsampling); + encoder = encoders[encoding]; + + encoder->setCompressLevel(cp.compressLevel); + encoder->setQualityLevel(cp.qualityLevel); + encoder->setFineQualityLevel(cp.fineQualityLevel, cp.subsampling); // Compute the number of rectangles. Tight encoder makes the things more // complicated as compared to the original VNC4. @@ -1055,7 +1054,7 @@ void VNCSConnectionST::writeFramebufferUpdate() ui.changed.get_rects(&rects); for (i = rects.begin(); i != rects.end(); i++) { if (i->width() && i->height()) { - int nUpdateRects = encoders[encoding]->getNumRects(*i); + int nUpdateRects = encoder->getNumRects(*i); if (nUpdateRects == 0 && cp.currentEncoding() == encodingTight) { // With Tight encoding and LastRect support, the client does not // care about the number of rectangles in the update - it will @@ -1077,14 +1076,15 @@ void VNCSConnectionST::writeFramebufferUpdate() writer()->writeCopyRect(*i, i->tl.x - ui.copy_delta.x, i->tl.y - ui.copy_delta.y); + pb = server->getPixelBuffer(); + ui.changed.get_rects(&rects); for (i = rects.begin(); i != rects.end(); i++) - encoders[encoding]->writeRect(*i, &image_getter); + encoder->writeRect(*i, pb); if (drawRenderedCursor) { - image_getter.setPixelBuffer(&server->renderedCursor); - encoders[encoding]->writeRect(renderedCursorRect, &image_getter); - image_getter.setPixelBuffer(server->pb); + renderedCursorRect = server->renderedCursor.getEffectiveRect(); + encoder->writeRect(renderedCursorRect, &server->renderedCursor); drawRenderedCursor = false; } diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index c918c599..6adeac27 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -193,7 +192,6 @@ namespace rfb { VNCServerST* server; SimpleUpdateTracker updates; - TransImageGetter image_getter; Region requested; bool drawRenderedCursor, removeRenderedCursor; Rect renderedCursorRect; diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 27eb605a..51cb86cf 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -84,7 +84,6 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_) name(strDup(name_)), pointerClient(0), comparer(0), renderedCursorInvalid(false), queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance), - useEconomicTranslate(false), lastConnectionTime(0), disableclients(false), deferTimer(this), deferPending(false) { diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index ede52236..1e055dd9 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -177,12 +177,6 @@ namespace rfb { // Blacklist to be shared by multiple VNCServerST instances. void setBlacklist(Blacklist* bl) {blHosts = bl ? bl : &blacklist;} - // setEconomicTranslate() determines (for new connections) whether pixels - // should be translated for <=16bpp clients using a large lookup table - // (fast) or separate, smaller R, G and B tables (slower). If set to true, - // small tables are used, to save memory. - void setEconomicTranslate(bool et) { useEconomicTranslate = et; } - // setKeyRemapper() replaces the VNCServerST's default key remapper. // NB: A null pointer is valid here. void setKeyRemapper(KeyRemapper* kr) { keyRemapper = kr; } @@ -242,8 +236,7 @@ namespace rfb { QueryConnectionHandler* queryConnectionHandler; KeyRemapper* keyRemapper; - bool useEconomicTranslate; - + time_t lastUserInputTime; time_t lastDisconnectTime; time_t lastConnectionTime; diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx index 7e933a8f..60e5dd14 100644 --- a/common/rfb/ZRLEDecoder.cxx +++ b/common/rfb/ZRLEDecoder.cxx @@ -17,7 +17,7 @@ */ #include #include -#include +#include #include using namespace rfb; @@ -66,17 +66,16 @@ ZRLEDecoder::~ZRLEDecoder() { } -void ZRLEDecoder::readRect(const Rect& r, CMsgHandler* handler) +void ZRLEDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb) { rdr::InStream* is = conn->getInStream(); rdr::U8* buf = conn->reader()->getImageBuf(64 * 64 * 4); - switch (conn->cp.pf().bpp) { - case 8: zrleDecode8 (r, is, &zis, (rdr::U8*) buf, handler); break; - case 16: zrleDecode16(r, is, &zis, (rdr::U16*)buf, handler); break; + const rfb::PixelFormat& pf = conn->cp.pf(); + switch (pf.bpp) { + case 8: zrleDecode8 (r, is, &zis, (rdr::U8*) buf, pf, pb); break; + case 16: zrleDecode16(r, is, &zis, (rdr::U16*)buf, pf, pb); break; case 32: { - const rfb::PixelFormat& pf = handler->cp.pf(); - Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1); bool fitsInLS3Bytes = maxPixel < (1<<24); bool fitsInMS3Bytes = (maxPixel & 0xff) == 0; @@ -84,16 +83,16 @@ void ZRLEDecoder::readRect(const Rect& r, CMsgHandler* handler) if ((fitsInLS3Bytes && pf.isLittleEndian()) || (fitsInMS3Bytes && pf.isBigEndian())) { - zrleDecode24A(r, is, &zis, (rdr::U32*)buf, handler); + zrleDecode24A(r, is, &zis, (rdr::U32*)buf, pf, pb); } else if ((fitsInLS3Bytes && pf.isBigEndian()) || (fitsInMS3Bytes && pf.isLittleEndian())) { - zrleDecode24B(r, is, &zis, (rdr::U32*)buf, handler); + zrleDecode24B(r, is, &zis, (rdr::U32*)buf, pf, pb); } else { - zrleDecode32(r, is, &zis, (rdr::U32*)buf, handler); + zrleDecode32(r, is, &zis, (rdr::U32*)buf, pf, pb); } break; } diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h index e7e2b8cb..492597e3 100644 --- a/common/rfb/ZRLEDecoder.h +++ b/common/rfb/ZRLEDecoder.h @@ -27,7 +27,7 @@ namespace rfb { public: ZRLEDecoder(CConnection* conn); virtual ~ZRLEDecoder(); - virtual void readRect(const Rect& r, CMsgHandler* handler); + virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb); private: rdr::ZlibInStream zis; }; diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx index 968edcfb..54613e2d 100644 --- a/common/rfb/ZRLEEncoder.cxx +++ b/common/rfb/ZRLEEncoder.cxx @@ -17,7 +17,6 @@ */ #include #include -#include #include #include #include @@ -69,22 +68,22 @@ ZRLEEncoder::~ZRLEEncoder() { } -void ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig) +void ZRLEEncoder::writeRect(const Rect& r, PixelBuffer* pb) { + const PixelFormat& pf = conn->cp.pf(); + rdr::U8* imageBuf = conn->writer()->getImageBuf(64 * 64 * 4 + 4); mos.clear(); - switch (conn->cp.pf().bpp) { + switch (pf.bpp) { case 8: - zrleEncode8(r, &mos, &zos, imageBuf, ig); + zrleEncode8(r, &mos, &zos, imageBuf, pf, pb); break; case 16: - zrleEncode16(r, &mos, &zos, imageBuf, ig); + zrleEncode16(r, &mos, &zos, imageBuf, pf, pb); break; case 32: { - const PixelFormat& pf = conn->cp.pf(); - Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1); bool fitsInLS3Bytes = maxPixel < (1<<24); bool fitsInMS3Bytes = (maxPixel & 0xff) == 0; @@ -92,16 +91,16 @@ void ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig) if ((fitsInLS3Bytes && pf.isLittleEndian()) || (fitsInMS3Bytes && pf.isBigEndian())) { - zrleEncode24A(r, &mos, &zos, imageBuf, ig); + zrleEncode24A(r, &mos, &zos, imageBuf, pf, pb); } else if ((fitsInLS3Bytes && pf.isBigEndian()) || (fitsInMS3Bytes && pf.isLittleEndian())) { - zrleEncode24B(r, &mos, &zos, imageBuf, ig); + zrleEncode24B(r, &mos, &zos, imageBuf, pf, pb); } else { - zrleEncode32(r, &mos, &zos, imageBuf, ig); + zrleEncode32(r, &mos, &zos, imageBuf, pf, pb); } break; } diff --git a/common/rfb/ZRLEEncoder.h b/common/rfb/ZRLEEncoder.h index d285967e..b006821d 100644 --- a/common/rfb/ZRLEEncoder.h +++ b/common/rfb/ZRLEEncoder.h @@ -28,7 +28,7 @@ namespace rfb { public: ZRLEEncoder(SConnection* conn); virtual ~ZRLEEncoder(); - virtual void writeRect(const Rect& r, TransImageGetter* ig); + virtual void writeRect(const Rect& r, PixelBuffer* pb); private: rdr::ZlibOutStream zos; rdr::MemOutStream mos; diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h index 518a6063..56ba1181 100644 --- a/common/rfb/hextileDecode.h +++ b/common/rfb/hextileDecode.h @@ -38,7 +38,7 @@ namespace rfb { #define HEXTILE_DECODE CONCAT2E(hextileDecode,BPP) void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf, - CMsgHandler* handler) + const PixelFormat& pf, ModifiablePixelBuffer* pb) { Rect t; PIXEL_T bg = 0; @@ -56,7 +56,7 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf, if (tileType & hextileRaw) { is->readBytes(buf, t.area() * (BPP/8)); - handler->imageRect(t, buf); + pb->imageRect(pf, t, buf); continue; } @@ -94,7 +94,7 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf, } } } - handler->imageRect(t, buf); + pb->imageRect(pf, t, buf); } } } diff --git a/common/rfb/hextileEncode.h b/common/rfb/hextileEncode.h index 7e5b2db7..2efd74ee 100644 --- a/common/rfb/hextileEncode.h +++ b/common/rfb/hextileEncode.h @@ -44,7 +44,8 @@ int TEST_TILE_TYPE (PIXEL_T* data, int w, int h, PIXEL_T* bg, PIXEL_T* fg); int HEXTILE_ENCODE_TILE (PIXEL_T* data, int w, int h, int tileType, rdr::U8* encoded, PIXEL_T bg); -void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig) +void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, + const PixelFormat& pf, PixelBuffer* pb) { Rect t; PIXEL_T buf[256]; @@ -61,7 +62,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig) t.br.x = __rfbmin(r.br.x, t.tl.x + 16); - ig->getImage(buf, t); + pb->getImage(pf, buf, t); PIXEL_T bg = 0, fg = 0; int tileType = TEST_TILE_TYPE(buf, t.width(), t.height(), &bg, &fg); @@ -90,7 +91,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig) encoded, bg); if (encodedLen < 0) { - ig->getImage(buf, t); + pb->getImage(pf, buf, t); os->writeU8(hextileRaw); os->writeBytes(buf, t.width() * t.height() * (BPP/8)); oldBgValid = oldFgValid = false; diff --git a/common/rfb/hextileEncodeBetter.h b/common/rfb/hextileEncodeBetter.h index 3a96ab63..efb2d9ca 100644 --- a/common/rfb/hextileEncodeBetter.h +++ b/common/rfb/hextileEncodeBetter.h @@ -275,7 +275,8 @@ void HEXTILE_TILE::encode(rdr::U8 *dst) const // Main encoding function. // -void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig) +void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, + const PixelFormat& pf, PixelBuffer* pb) { Rect t; PIXEL_T buf[256]; @@ -294,7 +295,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig) t.br.x = __rfbmin(r.br.x, t.tl.x + 16); - ig->getImage(buf, t); + pb->getImage(pf, buf, t); tile.newTile(buf, t.width(), t.height()); int tileType = tile.getFlags(); diff --git a/common/rfb/rreDecode.h b/common/rfb/rreDecode.h index d37461f9..9dc04703 100644 --- a/common/rfb/rreDecode.h +++ b/common/rfb/rreDecode.h @@ -36,11 +36,12 @@ namespace rfb { #define READ_PIXEL CONCAT2E(readOpaque,BPP) #define RRE_DECODE CONCAT2E(rreDecode,BPP) -void RRE_DECODE (const Rect& r, rdr::InStream* is, CMsgHandler* handler) +void RRE_DECODE (const Rect& r, rdr::InStream* is, + const PixelFormat& pf, ModifiablePixelBuffer* pb) { int nSubrects = is->readU32(); PIXEL_T bg = is->READ_PIXEL(); - handler->fillRect(r, bg); + pb->fillRect(pf, r, bg); for (int i = 0; i < nSubrects; i++) { PIXEL_T pix = is->READ_PIXEL(); @@ -48,7 +49,7 @@ void RRE_DECODE (const Rect& r, rdr::InStream* is, CMsgHandler* handler) int y = is->readU16(); int w = is->readU16(); int h = is->readU16(); - handler->fillRect(Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix); + pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix); } } diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h index a5963119..53dbba7e 100644 --- a/common/rfb/tightDecode.h +++ b/common/rfb/tightDecode.h @@ -77,7 +77,7 @@ void TIGHT_DECODE (const Rect& r) } else { pix = is->READ_PIXEL(); } - handler->fillRect(r, pix); + pb->fillRect(serverpf, r, pix); return; } @@ -153,7 +153,7 @@ void TIGHT_DECODE (const Rect& r) PIXEL_T *buf; int stride = r.width(); - if (directDecode) buf = (PIXEL_T *)handler->getRawBufferRW(r, &stride); + if (directDecode) buf = (PIXEL_T *)pb->getBufferRW(r, &stride); else buf = (PIXEL_T *)conn->reader()->getImageBuf(r.area()); if (palSize == 0) { @@ -225,8 +225,8 @@ void TIGHT_DECODE (const Rect& r) } } - if (directDecode) handler->releaseRawBuffer(r); - else handler->imageRect(r, buf); + if (directDecode) pb->commitBufferRW(r); + else pb->imageRect(serverpf, r, buf); delete [] netbuf; @@ -253,9 +253,9 @@ DECOMPRESS_JPEG_RECT(const Rect& r) // We always use direct decoding with JPEG images int stride; - rdr::U8 *buf = handler->getRawBufferRW(r, &stride); + rdr::U8 *buf = pb->getBufferRW(r, &stride); jd.decompress(netbuf, compressedLen, buf, stride, r, clientpf); - handler->releaseRawBuffer(r); + pb->commitBufferRW(r); delete [] netbuf; } diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h index 5d32cce3..1d8acc0e 100644 --- a/common/rfb/tightEncode.h +++ b/common/rfb/tightEncode.h @@ -114,7 +114,7 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid) { int stride; rdr::U32 solidColor; - const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawBufferR(r, &stride); + const PIXEL_T *rawPixels = (const PIXEL_T *)pb->getBuffer(r, &stride); PIXEL_T *pixels = NULL; bool grayScaleJPEG = (jpegSubsampling == subsampleGray && jpegQuality != -1); @@ -126,7 +126,8 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid) if (forceSolid) { // Subrectangle has already been determined to be solid. - ig->translatePixels(rawPixels, &solidColor, 1); + clientpf.bufferFromBuffer((rdr::U8*)&solidColor, serverpf, + (const rdr::U8*)rawPixels, 1); pixels = (PIXEL_T *)&solidColor; palette.clear(); palette.insert(solidColor, 1); @@ -149,14 +150,14 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid) if(palette.size() != 0 || jpegQuality == -1) { pixels = (PIXEL_T *)conn->writer()->getImageBuf(r.area()); stride = r.width(); - ig->getImage(pixels, r); + pb->getImage(clientpf, pixels, r); } } else { // Pixel translation will be required, so create an intermediate buffer, // translate the raw pixels into it, and count its colors. pixels = (PIXEL_T *)conn->writer()->getImageBuf(r.area()); stride = r.width(); - ig->getImage(pixels, r); + pb->getImage(clientpf, pixels, r); if (grayScaleJPEG) palette.clear(); else FILL_PALETTE(pixels, r.area()); @@ -443,7 +444,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r) int w = r.width(), h = r.height(); const PIXEL_T *rowptr, *colptr, *rowptr2, *colptr2, *dataend = &data[stride * h]; - bool willTransform = ig->willTransform(); + bool willTransform = !serverpf.equal(clientpf); serverpf.bufferFromPixel((rdr::U8*)&mask, ~0); @@ -490,8 +491,8 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r) monodone: if (willTransform) { - ig->translatePixels(&c0, &c0t, 1); - ig->translatePixels(&c1, &c1t, 1); + clientpf.bufferFromBuffer((rdr::U8*)&c0t, serverpf, (rdr::U8*)&c0, 1); + clientpf.bufferFromBuffer((rdr::U8*)&c1t, serverpf, (rdr::U8*)&c1, 1); } else { c0t = c0; c1t = c1; @@ -515,7 +516,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r) ni++; } else { if (willTransform) - ig->translatePixels(&ci, &cit, 1); + clientpf.bufferFromBuffer((rdr::U8*)&cit, serverpf, (rdr::U8*)&ci, 1); else cit = ci; if (!palette.insert (cit, ni) || (palette.size() > palMaxColors)) { @@ -529,7 +530,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r) rowptr += stride; colptr = rowptr; } - ig->translatePixels(&ci, &cit, 1); + clientpf.bufferFromBuffer((rdr::U8*)&cit, serverpf, (rdr::U8*)&ci, 1); if (!palette.insert (cit, ni) || (palette.size() > palMaxColors)) palette.clear(); } @@ -543,7 +544,7 @@ bool CHECK_SOLID_TILE(Rect& r, rdr::U32 *colorPtr, bool needSameColor) int w = r.width(), h = r.height(); int stride = w; - buf = (const PIXEL_T *)ig->getRawBufferR(r, &stride); + buf = (const PIXEL_T *)pb->getBuffer(r, &stride); colorValue = *buf; if (needSameColor && (rdr::U32)colorValue != *colorPtr) diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h index 4bcbf1f0..42b28b32 100644 --- a/common/rfb/zrleDecode.h +++ b/common/rfb/zrleDecode.h @@ -48,7 +48,7 @@ namespace rfb { void ZRLE_DECODE (const Rect& r, rdr::InStream* is, rdr::ZlibInStream* zis, PIXEL_T* buf, - CMsgHandler* handler) + const PixelFormat& pf, ModifiablePixelBuffer* pb) { int length = is->readU32(); zis->setUnderlying(is, length); @@ -73,7 +73,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, if (palSize == 1) { PIXEL_T pix = palette[0]; - handler->fillRect(t, pix); + pb->fillRect(pf, t, pix); continue; } @@ -173,7 +173,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n", //t.width(),t.height(),t.tl.x,t.tl.y); - handler->imageRect(t, buf); + pb->imageRect(pf, t, buf); } } diff --git a/common/rfb/zrleEncode.h b/common/rfb/zrleEncode.h index 8767d541..e5467724 100644 --- a/common/rfb/zrleEncode.h +++ b/common/rfb/zrleEncode.h @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace rfb { @@ -66,7 +67,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os); void ZRLE_ENCODE (const Rect& r, rdr::OutStream* os, rdr::ZlibOutStream* zos, void* buf, - TransImageGetter *ig) + const PixelFormat& pf, PixelBuffer* pb) { zos->setUnderlying(os); // RLE overhead is at worst 1 byte per 64x64 (4Kpixel) block @@ -83,7 +84,7 @@ void ZRLE_ENCODE (const Rect& r, rdr::OutStream* os, t.br.x = __rfbmin(r.br.x, t.tl.x + 64); - ig->getImage(buf, t); + pb->getImage(pf, buf, t); ZRLE_ENCODE_TILE((PIXEL_T*)buf, t.width(), t.height(), zos); } diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx index c78bb891..305eddce 100644 --- a/vncviewer/CConn.cxx +++ b/vncviewer/CConn.cxx @@ -263,7 +263,6 @@ void CConn::serverInit() // This initial update request is a bit of a corner case, so we need // to help out setting the correct format here. assert(pendingPFChange); - desktop->setServerPF(pendingPF); cp.setPF(pendingPF); pendingPFChange = false; } @@ -330,7 +329,6 @@ void CConn::framebufferUpdateEnd() // A format change has been scheduled and we are now past the update // with the old format. Time to active the new one. if (pendingPFChange) { - desktop->setServerPF(pendingPF); cp.setPF(pendingPF); pendingPFChange = false; } @@ -405,26 +403,11 @@ void CConn::dataRect(const Rect& r, int encoding) throw Exception("Unknown rect encoding"); } } - decoders[encoding]->readRect(r, this); + decoders[encoding]->readRect(r, desktop->getFramebuffer()); sock->inStream().stopTiming(); } -void CConn::fillRect(const rfb::Rect& r, rfb::Pixel p) -{ - desktop->fillRect(r,p); -} - -void CConn::imageRect(const rfb::Rect& r, void* p) -{ - desktop->imageRect(r,p); -} - -void CConn::copyRect(const rfb::Rect& r, int sx, int sy) -{ - desktop->copyRect(r,sx,sy); -} - void CConn::setCursor(int width, int height, const Point& hotspot, void* data, void* mask) { @@ -461,18 +444,10 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[]) pf.read(&memStream); - desktop->setServerPF(pf); cp.setPF(pf); } } -rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) { - return desktop->getBufferRW(r, stride); -} -void CConn::releaseRawBuffer(const rfb::Rect& r) { - desktop->commitBufferRW(r); -} - ////////////////////// Internal methods ////////////////////// diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h index f7f560bc..709ca2f8 100644 --- a/vncviewer/CConn.h +++ b/vncviewer/CConn.h @@ -64,18 +64,8 @@ public: void framebufferUpdateStart(); void framebufferUpdateEnd(); - void dataRect(const rfb::Rect& r, int encoding); - void fillRect(const rfb::Rect& r, rfb::Pixel p); - void imageRect(const rfb::Rect& r, void* p); - void copyRect(const rfb::Rect& r, int sx, int sy); - - rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride); - void releaseRawBuffer(const rfb::Rect& r); - - const rfb::PixelFormat &getPreferredPF() { return fullColourPF; } - void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index a64f02a2..d57d57ad 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -193,12 +193,6 @@ DesktopWindow::~DesktopWindow() } -void DesktopWindow::setServerPF(const rfb::PixelFormat& pf) -{ - viewport->setServerPF(pf); -} - - const rfb::PixelFormat &DesktopWindow::getPreferredPF() { return viewport->getPreferredPF(); @@ -216,24 +210,9 @@ void DesktopWindow::setName(const char *name) } -void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) { - viewport->fillRect(r, pix); -} - -void DesktopWindow::imageRect(const rfb::Rect& r, void* pixels) { - viewport->imageRect(r, pixels); -} - -void DesktopWindow::copyRect(const rfb::Rect& r, int srcX, int srcY) { - viewport->copyRect(r, srcX, srcY); -} - -rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) { - return viewport->getBufferRW(r, stride); -} - -void DesktopWindow::commitBufferRW(const rfb::Rect& r) { - viewport->commitBufferRW(r); +rfb::ModifiablePixelBuffer* DesktopWindow::getFramebuffer(void) +{ + return viewport->getFramebuffer(); } diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h index 83a8c767..8b91450f 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -27,6 +27,8 @@ #include +namespace rfb { class ModifiablePixelBuffer; } + class CConn; class Viewport; @@ -39,26 +41,22 @@ public: const rfb::PixelFormat& serverPF, CConn* cc_); ~DesktopWindow(); - // PixelFormat of incoming write operations - void setServerPF(const rfb::PixelFormat& pf); // Most efficient format (from DesktopWindow's point of view) const rfb::PixelFormat &getPreferredPF(); // Flush updates to screen void updateWindow(); - // Methods forwarded from CConn + // Updated session title void setName(const char *name); - void fillRect(const rfb::Rect& r, rfb::Pixel pix); - void imageRect(const rfb::Rect& r, void* pixels); - void copyRect(const rfb::Rect& r, int srcX, int srcY); - - rdr::U8* getBufferRW(const rfb::Rect& r, int* stride); - void commitBufferRW(const rfb::Rect& r); + // Return a pointer to the framebuffer for decoders to write into + rfb::ModifiablePixelBuffer* getFramebuffer(void); + // Resize the current framebuffer, but retain the contents void resizeFramebuffer(int new_w, int new_h); + // New image for the locally rendered cursor void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx index ced04467..5bd50d2c 100644 --- a/vncviewer/PlatformPixelBuffer.cxx +++ b/vncviewer/PlatformPixelBuffer.cxx @@ -24,3 +24,19 @@ PlatformPixelBuffer::PlatformPixelBuffer(const rfb::PixelFormat& pf, FullFramePixelBuffer(pf, width, height, data, stride) { } + +void PlatformPixelBuffer::commitBufferRW(const rfb::Rect& r) +{ + FullFramePixelBuffer::commitBufferRW(r); + damage.assign_union(rfb::Region(r)); +} + +rfb::Rect PlatformPixelBuffer::getDamage(void) +{ + rfb::Rect r; + + r = damage.get_bounding_rect(); + damage.clear(); + + return r; +} diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h index 03842ac8..21b93be4 100644 --- a/vncviewer/PlatformPixelBuffer.h +++ b/vncviewer/PlatformPixelBuffer.h @@ -20,14 +20,20 @@ #define __PLATFORMPIXELBUFFER_H__ #include +#include class PlatformPixelBuffer: public rfb::FullFramePixelBuffer { public: PlatformPixelBuffer(const rfb::PixelFormat& pf, int width, int height, rdr::U8* data, int stride); + virtual void commitBufferRW(const rfb::Rect& r); + virtual void draw(int src_x, int src_y, int x, int y, int w, int h) = 0; + rfb::Rect getDamage(void); +protected: + rfb::Region damage; }; #endif diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 70964b76..cd8b1bc3 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -27,7 +27,6 @@ #include #include -#include // FLTK can pull in the X11 headers on some systems #ifndef XK_VoidSymbol @@ -84,7 +83,7 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_RESIZE, ID_REFRESH, ID_OPTIONS, ID_INFO, ID_ABOUT, ID_DISMISS }; Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_) - : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL), + : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), lastPointerPos(0, 0), lastButtonMask(0), cursor(NULL), menuCtrlKey(false), menuAltKey(false) { @@ -101,8 +100,6 @@ Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_) frameBuffer = createFramebuffer(w, h); assert(frameBuffer); - setServerPF(serverPF); - contextMenu = new Fl_Menu_Button(0, 0, 0, 0); // Setting box type to FL_NO_BOX prevents it from trying to draw the // button component (which we don't want) @@ -130,7 +127,6 @@ Viewport::~Viewport() { // Unregister all timeouts in case they get a change tro trigger // again later when this object is already gone. - Fl::remove_timeout(handleUpdateTimeout, this); Fl::remove_timeout(handlePointerTimeout, this); #ifdef HAVE_FLTK_CLIPBOARD @@ -141,9 +137,6 @@ Viewport::~Viewport() delete frameBuffer; - if (pixelTrans) - delete pixelTrans; - if (cursor) { if (!cursor->alloc_array) delete [] cursor->array; @@ -155,40 +148,6 @@ Viewport::~Viewport() } -void Viewport::setServerPF(const rfb::PixelFormat& pf) -{ - if (pixelTrans) - delete pixelTrans; - pixelTrans = NULL; - - if (pf.equal(getPreferredPF())) - return; - - pixelTrans = new PixelTransformer(); - - // FIXME: This is an ugly (temporary) hack to get around a corner - // case during startup. The conversion routines cannot handle - // non-native source formats, and we can sometimes get that - // as the initial format. We will switch to a better format - // before getting any updates, but we need something for now. - // Our old client used something completely bogus and just - // hoped nothing would ever go wrong. We try to at least match - // the pixel size so that we don't get any memory access issues - // should a stray update appear. - static rdr::U32 endianTest = 1; - static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1; - if ((pf.bpp > 8) && (pf.bigEndian != nativeBigEndian)) { - PixelFormat fake_pf(pf.bpp, pf.depth, nativeBigEndian, pf.trueColour, - pf.redMax, pf.greenMax, pf.blueMax, - pf.redShift, pf.greenShift, pf.blueShift); - pixelTrans->init(fake_pf, getPreferredPF()); - return; - } - - pixelTrans->init(pf, getPreferredPF()); -} - - const rfb::PixelFormat &Viewport::getPreferredPF() { return frameBuffer->getPF(); @@ -197,65 +156,21 @@ const rfb::PixelFormat &Viewport::getPreferredPF() // Copy the areas of the framebuffer that have been changed (damaged) // to the displayed window. +// FIXME: Make sure this gets called on slow updates void Viewport::updateWindow() { Rect r; - Fl::remove_timeout(handleUpdateTimeout, this); - - r = damage.get_bounding_rect(); - Fl_Widget::damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height()); - - damage.clear(); -} - -void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) { - if (pixelTrans) { - rfb::Pixel pix2; - pixelTrans->translatePixels(&pix, &pix2, 1); - pix = pix2; - } - - frameBuffer->fillRect(r, pix); - damageRect(r); + r = frameBuffer->getDamage(); + damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height()); } -void Viewport::imageRect(const rfb::Rect& r, void* pixels) { - if (pixelTrans) { - rdr::U8* buffer; - int stride; - buffer = frameBuffer->getBufferRW(r, &stride); - pixelTrans->translateRect(pixels, r.width(), - rfb::Rect(0, 0, r.width(), r.height()), - buffer, stride, rfb::Point(0, 0)); - frameBuffer->commitBufferRW(r); - } else { - frameBuffer->imageRect(r, pixels); - } - damageRect(r); -} - -void Viewport::copyRect(const rfb::Rect& r, int srcX, int srcY) { - frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY)); - damageRect(r); -} - -rdr::U8* Viewport::getBufferRW(const rfb::Rect& r, int* stride) { - return frameBuffer->getBufferRW(r, stride); -} - -void Viewport::commitBufferRW(const rfb::Rect& r) { - frameBuffer->commitBufferRW(r); - damageRect(r); +rfb::ModifiablePixelBuffer* Viewport::getFramebuffer(void) +{ + return frameBuffer; } -void Viewport::damageRect(const rfb::Rect& r) { - damage.assign_union(rfb::Region(r)); - if (!Fl::has_timeout(handleUpdateTimeout, this)) - Fl::add_timeout(0.500, handleUpdateTimeout, this); -}; - #ifdef HAVE_FLTK_CURSOR static const char * dotcursor_xpm[] = { "5 5 2 1", @@ -303,10 +218,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot, const PixelFormat *pf; - if (pixelTrans) - pf = &pixelTrans->getInPF(); - else - pf = &frameBuffer->getPF(); + pf = &cc->cp.pf(); i = (U8*)data; o = buffer; @@ -530,16 +442,6 @@ PlatformPixelBuffer* Viewport::createFramebuffer(int w, int h) } -void Viewport::handleUpdateTimeout(void *data) -{ - Viewport *self = (Viewport *)data; - - assert(self); - - self->updateWindow(); -} - - void Viewport::handleClipboardChange(int source, void *data) { Viewport *self = (Viewport *)data; diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h index e112efda..0523cd14 100644 --- a/vncviewer/Viewport.h +++ b/vncviewer/Viewport.h @@ -22,10 +22,9 @@ #include -#include +namespace rfb { class ModifiablePixelBuffer; } -#include -#include +#include class Fl_Menu_Button; class Fl_RGB_Image; @@ -41,23 +40,16 @@ public: Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_); ~Viewport(); - // PixelFormat of incoming write operations - void setServerPF(const rfb::PixelFormat& pf); // Most efficient format (from Viewport's point of view) const rfb::PixelFormat &getPreferredPF(); // Flush updates to screen void updateWindow(); - // Methods forwarded from CConn - - void fillRect(const rfb::Rect& r, rfb::Pixel pix); - void imageRect(const rfb::Rect& r, void* pixels); - void copyRect(const rfb::Rect& r, int srcX, int srcY); - - rdr::U8* getBufferRW(const rfb::Rect& r, int* stride); - void commitBufferRW(const rfb::Rect& r); + // Return a pointer to the framebuffer for decoders to write into + rfb::ModifiablePixelBuffer* getFramebuffer(void); + // New image for the locally rendered cursor void setCursor(int width, int height, const rfb::Point& hotspot, void* data, void* mask); @@ -71,12 +63,8 @@ public: private: - void damageRect(const rfb::Rect& r); - PlatformPixelBuffer* createFramebuffer(int w, int h); - static void handleUpdateTimeout(void *data); - static void handleClipboardChange(int source, void *data); void handlePointerEvent(const rfb::Point& pos, int buttonMask); @@ -96,8 +84,6 @@ private: CConn* cc; PlatformPixelBuffer* frameBuffer; - rfb::PixelTransformer *pixelTrans; - rfb::Region damage; rfb::Point lastPointerPos; int lastButtonMask; -- 2.39.5