1 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
2  * Copyright 2014 Pierre Ossman for Cendio AB
3  *
4  * This is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This software is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this software; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17  * USA.
18  */
19 
20 // -=- PixelBuffer.h
21 //
22 // The PixelBuffer class encapsulates the PixelFormat and dimensions
23 // of a block of pixel data.
24 
25 #ifndef __RFB_PIXEL_BUFFER_H__
26 #define __RFB_PIXEL_BUFFER_H__
27 
28 #include <rfb/PixelFormat.h>
29 #include <rfb/Rect.h>
30 #include <rfb/Pixel.h>
31 #include <rfb/util.h>
32 
33 namespace rfb {
34 
35   class Region;
36 
37   class PixelBuffer {
38   public:
39     PixelBuffer(const PixelFormat& pf, int width, int height);
40     virtual ~PixelBuffer();
41 
42     ///////////////////////////////////////////////
43     // Format / Layout
44     //
45 
46   public:
47     // Get pixel format
getPF()48     const PixelFormat &getPF() const { return format; }
49 
50     // Get width, height and number of pixels
width()51     int width()  const { return width_; }
height()52     int height() const { return height_; }
area()53     int area() const { return width_ * height_; }
54 
55     // Get rectangle encompassing this buffer
56     //   Top-left of rectangle is either at (0,0), or the specified point.
getRect()57     Rect getRect() const { return Rect(0, 0, width_, height_); }
getRect(const Point & pos)58     Rect getRect(const Point& pos) const {
59       return Rect(pos, pos.translate(Point(width_, height_)));
60     }
61 
62     ///////////////////////////////////////////////
63     // Access to pixel data
64     //
65 
66     // Get a pointer into the buffer
67     //   The pointer is to the top-left pixel of the specified Rect.
68     //   The buffer stride (in pixels) is returned.
69     virtual const rdr::U8* getBuffer(const Rect& r, int* stride) const = 0;
70 
71     // Get pixel data for a given part of the buffer
72     //   Data is copied into the supplied buffer, with the specified
73     //   stride. Try to avoid using this though as getBuffer() will in
74     //   most cases avoid the extra memory copy.
75     void getImage(void* imageBuf, const Rect& r, int stride=0) const;
76     // Get pixel data in a given format
77     //   Works just the same as getImage(), but guaranteed to be in a
78     //   specific format.
79     void getImage(const PixelFormat& pf, void* imageBuf,
80                   const Rect& r, int stride=0) const;
81 
82     ///////////////////////////////////////////////
83     // Framebuffer update methods
84     //
85 
86     // Ensure that the specified rectangle of buffer is up to date.
87     //   Overridden by derived classes implementing framebuffer access
88     //   to copy the required display data into place.
grabRegion(const Region & __unused_attr region)89     virtual void grabRegion(const Region& __unused_attr region) {}
90 
91   protected:
92     PixelBuffer();
93     virtual void setSize(int width, int height);
94 
95   protected:
96     PixelFormat format;
97 
98   private:
99     int width_, height_;
100   };
101 
102   // ModifiablePixelBuffer
103   class ModifiablePixelBuffer : public PixelBuffer {
104   public:
105     ModifiablePixelBuffer(const PixelFormat& pf, int width, int height);
106     virtual ~ModifiablePixelBuffer();
107 
108     ///////////////////////////////////////////////
109     // Access to pixel data
110     //
111 
112     // Get a writeable pointer into the buffer
113     //   Like getBuffer(), the pointer is to the top-left pixel of the
114     //   specified Rect and the stride in pixels is returned.
115     virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
116     // Commit the modified contents
117     //   Ensures that the changes to the specified Rect is properly
118     //   stored away and any temporary buffers are freed. The Rect given
119     //   here needs to match the Rect given to the earlier call to
120     //   getBufferRW().
121     virtual void commitBufferRW(const Rect& r) = 0;
122 
123     ///////////////////////////////////////////////
124     // Basic rendering operations
125     // These operations DO NOT clip to the pixelbuffer area, or trap overruns.
126 
127     // Fill a rectangle
128     void fillRect(const Rect &dest, const void* pix);
129 
130     // Copy pixel data to the buffer
131     void imageRect(const Rect &dest, const void* pixels, int stride=0);
132 
133     // Copy pixel data from one PixelBuffer location to another
134     void copyRect(const Rect &dest, const Point& move_by_delta);
135 
136     // Render in a specific format
137     //   Does the exact same thing as the above methods, but the given
138     //   pixel values are defined by the given PixelFormat.
139     void fillRect(const PixelFormat& pf, const Rect &dest, const void* pix);
140     void imageRect(const PixelFormat& pf, const Rect &dest,
141                    const void* pixels, int stride=0);
142 
143   protected:
144     ModifiablePixelBuffer();
145   };
146 
147   // FullFramePixelBuffer
148 
149   class FullFramePixelBuffer : public ModifiablePixelBuffer {
150   public:
151     FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
152                          rdr::U8* data_, int stride);
153     virtual ~FullFramePixelBuffer();
154 
155   public:
156     virtual const rdr::U8* getBuffer(const Rect& r, int* stride) const;
157     virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
158     virtual void commitBufferRW(const Rect& r);
159 
160   protected:
161     FullFramePixelBuffer();
162     virtual void setBuffer(int width, int height, rdr::U8* data, int stride);
163 
164   private:
165     virtual void setSize(int w, int h);
166 
167   private:
168     rdr::U8* data;
169     int stride;
170   };
171 
172   // -=- Managed pixel buffer class
173   // Automatically allocates enough space for the specified format & area
174 
175   class ManagedPixelBuffer : public FullFramePixelBuffer {
176   public:
177     ManagedPixelBuffer();
178     ManagedPixelBuffer(const PixelFormat& pf, int width, int height);
179     virtual ~ManagedPixelBuffer();
180 
181     // Manage the pixel buffer layout
182     virtual void setPF(const PixelFormat &pf);
183     virtual void setSize(int w, int h);
184 
185   private:
186     rdr::U8* data_; // Mirrors FullFramePixelBuffer::data
187     unsigned long datasize;
188   };
189 
190 };
191 
192 #endif // __RFB_PIXEL_BUFFER_H__
193