aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-02-06 16:31:10 +0100
committerPierre Ossman <ossman@cendio.se>2014-07-07 14:55:27 +0200
commita32040d7c9972f70272218effbc0242416d417d2 (patch)
treeb6ef6c797262da99af6907154b014a65acb15b60
parent2e5a10608394186fd1324c97b17d7f08e0c0aaf6 (diff)
downloadtigervnc-a32040d7c9972f70272218effbc0242416d417d2.tar.gz
tigervnc-a32040d7c9972f70272218effbc0242416d417d2.zip
Provide a better R/W base PixelBuffer class
Clearly separates the read API from the write API and also from actual implementation.
-rw-r--r--common/rfb/ComparingUpdateTracker.cxx2
-rw-r--r--common/rfb/PixelBuffer.cxx67
-rw-r--r--common/rfb/PixelBuffer.h46
-rw-r--r--vncviewer/CConn.cxx2
-rw-r--r--vncviewer/DesktopWindow.cxx4
-rw-r--r--vncviewer/DesktopWindow.h2
-rw-r--r--vncviewer/Viewport.cxx6
-rw-r--r--vncviewer/Viewport.h5
-rw-r--r--win/rfb_win32/DeviceFrameBuffer.cxx1
9 files changed, 103 insertions, 32 deletions
diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx
index 8d4311a1..1d27f3c4 100644
--- a/common/rfb/ComparingUpdateTracker.cxx
+++ b/common/rfb/ComparingUpdateTracker.cxx
@@ -157,6 +157,8 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
oldData += oldStrideBytes * BLOCK_SIZE;
}
+ oldFb.commitBufferRW(r);
+
if (!changedBlocks.empty()) {
Region temp;
temp.setOrderedRects(changedBlocks);
diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx
index ea19d183..bcffa791 100644
--- a/common/rfb/PixelBuffer.cxx
+++ b/common/rfb/PixelBuffer.cxx
@@ -60,26 +60,24 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) {
}
}
+// -=- Modifiable generic pixel buffer class
-FullFramePixelBuffer::FullFramePixelBuffer(const PixelFormat& pf, int w, int h,
- rdr::U8* data_, int stride_)
- : PixelBuffer(pf, w, h), data(data_), stride(stride_)
+ModifiablePixelBuffer::ModifiablePixelBuffer(const PixelFormat& pf,
+ int w, int h)
+ : PixelBuffer(pf, w, h)
{
}
-FullFramePixelBuffer::FullFramePixelBuffer() : data(0) {}
-
-FullFramePixelBuffer::~FullFramePixelBuffer() {}
-
-
-rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_)
+ModifiablePixelBuffer::ModifiablePixelBuffer()
{
- *stride_ = stride;
- return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8];
}
+ModifiablePixelBuffer::~ModifiablePixelBuffer()
+{
+}
-void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) {
+void ModifiablePixelBuffer::fillRect(const Rect& r, Pixel pix)
+{
int stride;
U8 *buf, pixbuf[4];
int w, h, b;
@@ -99,9 +97,13 @@ void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) {
}
buf += (stride - w) * b;
}
+
+ commitBufferRW(r);
}
-void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcStride) {
+void ModifiablePixelBuffer::imageRect(const Rect& r,
+ const void* pixels, int srcStride)
+{
int bytesPerPixel = getPF().bpp/8;
int destStride;
U8* dest = getBufferRW(r, &destStride);
@@ -116,9 +118,12 @@ void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcS
dest += bytesPerDestRow;
src += bytesPerSrcRow;
}
+ commitBufferRW(r);
}
-void FullFramePixelBuffer::maskRect(const Rect& r, const void* pixels, const void* mask_) {
+void ModifiablePixelBuffer::maskRect(const Rect& r,
+ const void* pixels, const void* mask_)
+{
Rect cr = getRect().intersect(r);
if (cr.is_empty()) return;
int stride;
@@ -154,9 +159,13 @@ void FullFramePixelBuffer::maskRect(const Rect& r, const void* pixels, const voi
}
mask += maskStride;
}
+
+ commitBufferRW(cr);
}
-void FullFramePixelBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask_) {
+void ModifiablePixelBuffer::maskRect(const Rect& r,
+ Pixel pixel, const void* mask_)
+{
Rect cr = getRect().intersect(r);
if (cr.is_empty()) return;
int stride;
@@ -190,9 +199,13 @@ void FullFramePixelBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask
}
mask += maskStride;
}
+
+ commitBufferRW(cr);
}
-void FullFramePixelBuffer::copyRect(const Rect &rect, const Point &move_by_delta) {
+void ModifiablePixelBuffer::copyRect(const Rect &rect,
+ const Point &move_by_delta)
+{
int stride;
U8* data;
unsigned int bytesPerPixel, bytesPerRow, bytesPerMemCpy;
@@ -241,8 +254,30 @@ void FullFramePixelBuffer::copyRect(const Rect &rect, const Point &move_by_delta
src -= bytesPerRow;
}
}
+ commitBufferRW(getRect());
+}
+
+// -=- Simple pixel buffer with a continuous block of memory
+
+FullFramePixelBuffer::FullFramePixelBuffer(const PixelFormat& pf, int w, int h,
+ rdr::U8* data_, int stride_)
+ : ModifiablePixelBuffer(pf, w, h), data(data_), stride(stride_)
+{
}
+FullFramePixelBuffer::FullFramePixelBuffer() : data(0) {}
+
+FullFramePixelBuffer::~FullFramePixelBuffer() {}
+
+rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_)
+{
+ *stride_ = stride;
+ return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8];
+}
+
+void FullFramePixelBuffer::commitBufferRW(const Rect& r)
+{
+}
// -=- Managed pixel buffer class
// Automatically allocates enough space for the specified format & area
diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h
index 59d71c79..e2cc3e92 100644
--- a/common/rfb/PixelBuffer.h
+++ b/common/rfb/PixelBuffer.h
@@ -66,7 +66,6 @@ namespace rfb {
// The pointer is to the top-left pixel of the specified Rect.
// The buffer stride (in pixels) is returned.
virtual const rdr::U8* getBuffer(const Rect& r, int* stride) = 0;
- virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
// Get pixel data for a given part of the buffer
// Data is copied into the supplied buffer, with the specified
@@ -89,20 +88,31 @@ namespace rfb {
int width_, height_;
};
- // FullFramePixelBuffer
-
- class FullFramePixelBuffer : public PixelBuffer {
+ // ModifiablePixelBuffer
+ class ModifiablePixelBuffer : public PixelBuffer {
public:
- FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
- rdr::U8* data, int stride);
- virtual ~FullFramePixelBuffer();
+ ModifiablePixelBuffer(const PixelFormat& pf, int width, int height);
+ virtual ~ModifiablePixelBuffer();
- public:
- // Get a pointer to specified pixel data
+ ///////////////////////////////////////////////
+ // Access to pixel data
+ //
+
+ // Get a writeable pointer into the buffer
+ // Like getBuffer(), the pointer is to the top-left pixel of the
+ // specified Rect and the stride in pixels is returned.
+ virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
+ // Commit the modified contents
+ // Ensures that the changes to the specified Rect is properly
+ // stored away and any temporary buffers are freed. The Rect given
+ // here needs to match the Rect given to the earlier call to
+ // getBufferRW().
+ virtual void commitBufferRW(const Rect& r) = 0;
+
+ // Default trivial handling of read-only access
virtual const rdr::U8* getBuffer(const Rect& r, int* stride) {
return getBufferRW(r, stride);
}
- virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
///////////////////////////////////////////////
// Basic rendering operations
@@ -128,6 +138,22 @@ namespace rfb {
void maskRect(const Rect& r, Pixel pixel, const void* mask_);
protected:
+ ModifiablePixelBuffer();
+ };
+
+ // FullFramePixelBuffer
+
+ class FullFramePixelBuffer : public ModifiablePixelBuffer {
+ public:
+ FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
+ rdr::U8* data_, int stride);
+ virtual ~FullFramePixelBuffer();
+
+ public:
+ virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
+ virtual void commitBufferRW(const Rect& r);
+
+ protected:
FullFramePixelBuffer();
rdr::U8* data;
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index db1a08a5..c78bb891 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -470,7 +470,7 @@ rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) {
return desktop->getBufferRW(r, stride);
}
void CConn::releaseRawBuffer(const rfb::Rect& r) {
- desktop->damageRect(r);
+ desktop->commitBufferRW(r);
}
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 3e9b57e6..a64f02a2 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -232,8 +232,8 @@ rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) {
return viewport->getBufferRW(r, stride);
}
-void DesktopWindow::damageRect(const rfb::Rect& r) {
- viewport->damageRect(r);
+void DesktopWindow::commitBufferRW(const rfb::Rect& r) {
+ viewport->commitBufferRW(r);
}
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 08a66522..83a8c767 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -55,7 +55,7 @@ public:
void copyRect(const rfb::Rect& r, int srcX, int srcY);
rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
- void damageRect(const rfb::Rect& r);
+ void commitBufferRW(const rfb::Rect& r);
void resizeFramebuffer(int new_w, int new_h);
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index d1d51622..70964b76 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -229,6 +229,7 @@ void Viewport::imageRect(const rfb::Rect& r, void* pixels) {
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);
}
@@ -244,6 +245,11 @@ 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);
+}
+
void Viewport::damageRect(const rfb::Rect& r) {
damage.assign_union(rfb::Region(r));
if (!Fl::has_timeout(handleUpdateTimeout, this))
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index bd17655a..e112efda 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -56,8 +56,7 @@ public:
void copyRect(const rfb::Rect& r, int srcX, int srcY);
rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
-
- void damageRect(const rfb::Rect& r);
+ void commitBufferRW(const rfb::Rect& r);
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
@@ -72,6 +71,8 @@ public:
private:
+ void damageRect(const rfb::Rect& r);
+
PlatformPixelBuffer* createFramebuffer(int w, int h);
static void handleUpdateTimeout(void *data);
diff --git a/win/rfb_win32/DeviceFrameBuffer.cxx b/win/rfb_win32/DeviceFrameBuffer.cxx
index 0ad06e9e..d075c259 100644
--- a/win/rfb_win32/DeviceFrameBuffer.cxx
+++ b/win/rfb_win32/DeviceFrameBuffer.cxx
@@ -220,6 +220,7 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
}
}
}
+ cursorBm.commitBufferRW(cursorBm.getRect());
}
// Finally invert the AND mask so it's suitable for RFB and pack it into