1 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
2  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
3  * Copyright 2014-2018 Pierre Ossman for Cendio AB
4  *
5  * This is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This software is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this software; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18  * USA.
19  */
20 #ifndef __RFB_ENCODEMANAGER_H__
21 #define __RFB_ENCODEMANAGER_H__
22 
23 #include <vector>
24 
25 #include <rdr/types.h>
26 #include <rfb/PixelBuffer.h>
27 #include <rfb/Region.h>
28 #include <rfb/Timer.h>
29 
30 namespace rfb {
31   class SConnection;
32   class Encoder;
33   class UpdateInfo;
34   class PixelBuffer;
35   class RenderedCursor;
36   struct Rect;
37 
38   struct RectInfo;
39 
40   class EncodeManager : public Timer::Callback {
41   public:
42     EncodeManager(SConnection* conn);
43     ~EncodeManager();
44 
45     void logStats();
46 
47     // Hack to let ConnParams calculate the client's preferred encoding
48     static bool supported(int encoding);
49 
50     bool needsLosslessRefresh(const Region& req);
51     int getNextLosslessRefresh(const Region& req);
52 
53     void pruneLosslessRefresh(const Region& limits);
54 
55     void writeUpdate(const UpdateInfo& ui, const PixelBuffer* pb,
56                      const RenderedCursor* renderedCursor);
57 
58     void writeLosslessRefresh(const Region& req, const PixelBuffer* pb,
59                               const RenderedCursor* renderedCursor,
60                               size_t maxUpdateSize);
61 
62   protected:
63     virtual bool handleTimeout(Timer* t);
64 
65     void doUpdate(bool allowLossy, const Region& changed,
66                   const Region& copied, const Point& copy_delta,
67                   const PixelBuffer* pb,
68                   const RenderedCursor* renderedCursor);
69     void prepareEncoders(bool allowLossy);
70 
71     Region getLosslessRefresh(const Region& req, size_t maxUpdateSize);
72 
73     int computeNumRects(const Region& changed);
74 
75     Encoder *startRect(const Rect& rect, int type);
76     void endRect();
77 
78     void writeCopyRects(const Region& copied, const Point& delta);
79     void writeSolidRects(Region *changed, const PixelBuffer* pb);
80     void findSolidRect(const Rect& rect, Region *changed, const PixelBuffer* pb);
81     void writeRects(const Region& changed, const PixelBuffer* pb);
82 
83     void writeSubRect(const Rect& rect, const PixelBuffer *pb);
84 
85     bool checkSolidTile(const Rect& r, const rdr::U8* colourValue,
86                         const PixelBuffer *pb);
87     void extendSolidAreaByBlock(const Rect& r, const rdr::U8* colourValue,
88                                 const PixelBuffer *pb, Rect* er);
89     void extendSolidAreaByPixel(const Rect& r, const Rect& sr,
90                                 const rdr::U8* colourValue,
91                                 const PixelBuffer *pb, Rect* er);
92 
93     PixelBuffer* preparePixelBuffer(const Rect& rect,
94                                     const PixelBuffer *pb, bool convert);
95 
96     bool analyseRect(const PixelBuffer *pb,
97                      struct RectInfo *info, int maxColours);
98 
99   protected:
100     // Preprocessor generated, optimised methods
101     inline bool checkSolidTile(const Rect& r, rdr::U8 colourValue,
102                                const PixelBuffer *pb);
103     inline bool checkSolidTile(const Rect& r, rdr::U16 colourValue,
104                                const PixelBuffer *pb);
105     inline bool checkSolidTile(const Rect& r, rdr::U32 colourValue,
106                                const PixelBuffer *pb);
107 
108     inline bool analyseRect(int width, int height,
109                             const rdr::U8* buffer, int stride,
110                             struct RectInfo *info, int maxColours);
111     inline bool analyseRect(int width, int height,
112                             const rdr::U16* buffer, int stride,
113                             struct RectInfo *info, int maxColours);
114     inline bool analyseRect(int width, int height,
115                             const rdr::U32* buffer, int stride,
116                             struct RectInfo *info, int maxColours);
117 
118   protected:
119     SConnection *conn;
120 
121     std::vector<Encoder*> encoders;
122     std::vector<int> activeEncoders;
123 
124     Region lossyRegion;
125     Region recentlyChangedRegion;
126     Region pendingRefreshRegion;
127 
128     Timer recentChangeTimer;
129 
130     struct EncoderStats {
131       unsigned rects;
132       unsigned long long bytes;
133       unsigned long long pixels;
134       unsigned long long equivalent;
135     };
136     typedef std::vector< std::vector<struct EncoderStats> > StatsVector;
137 
138     unsigned updates;
139     EncoderStats copyStats;
140     StatsVector stats;
141     int activeType;
142     int beforeLength;
143 
144     class OffsetPixelBuffer : public FullFramePixelBuffer {
145     public:
OffsetPixelBuffer()146       OffsetPixelBuffer() {}
~OffsetPixelBuffer()147       virtual ~OffsetPixelBuffer() {}
148 
149       void update(const PixelFormat& pf, int width, int height,
150                   const rdr::U8* data_, int stride);
151 
152     private:
153       virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
154     };
155 
156     OffsetPixelBuffer offsetPixelBuffer;
157     ManagedPixelBuffer convertedPixelBuffer;
158   };
159 }
160 
161 #endif
162