blob: 28e916d55e9908394d84b1a711626566a9879c4a [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- rfbUpdateTracker.cpp
20//
21// Tracks updated regions and a region-copy event, too
22//
23
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000024#include <rfb/UpdateTracker.h>
25#include <rfb/LogWriter.h>
26
27using namespace rfb;
28
29static LogWriter vlog("UpdateTracker");
30
31
32// -=- ClippingUpdateTracker
33
34void ClippingUpdateTracker::add_changed(const Region &region) {
35 ut->add_changed(region.intersect(clipRect));
36}
37
38void ClippingUpdateTracker::add_copied(const Region &dest, const Point &delta) {
39 // Clip the destination to the display area
40 Region clipdest = dest.intersect(clipRect);
41 if (clipdest.is_empty()) return;
42
43 // Clip the source to the screen
44 Region tmp = clipdest;
45 tmp.translate(delta.negate());
46 tmp.assign_intersect(clipRect);
47 if (!tmp.is_empty()) {
48 // Translate the source back to a destination region
49 tmp.translate(delta);
50
51 // Pass the copy region to the child tracker
52 ut->add_copied(tmp, delta);
53 }
54
55 // And add any bits that we had to remove to the changed region
56 tmp = clipdest.subtract(tmp);
57 if (!tmp.is_empty())
58 ut->add_changed(tmp);
59}
60
61// SimpleUpdateTracker
62
Pierre Ossmana114c342018-06-18 16:29:55 +020063SimpleUpdateTracker::SimpleUpdateTracker() {
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000064}
65
66SimpleUpdateTracker::~SimpleUpdateTracker() {
67}
68
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000069void SimpleUpdateTracker::add_changed(const Region &region) {
70 changed.assign_union(region);
71}
72
73void SimpleUpdateTracker::add_copied(const Region &dest, const Point &delta) {
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000074 // Is there anything to do?
75 if (dest.is_empty()) return;
76
77 // Calculate whether any of this copy can be treated as a continuation
78 // of an earlier one
79 Region src = dest;
80 src.translate(delta.negate());
81 Region overlap = src.intersect(copied);
82
83 if (overlap.is_empty()) {
84 // There is no overlap
85
86 Rect newbr = dest.get_bounding_rect();
87 Rect oldbr = copied.get_bounding_rect();
88 if (oldbr.area() > newbr.area()) {
89 // Old copyrect is (probably) bigger - use it
90 changed.assign_union(dest);
91 } else {
92 // New copyrect is probably bigger
93 // Use the new one
94 // But be careful not to copy stuff that still needs
95 // to be updated.
96 Region invalid_src = src.intersect(changed);
97 invalid_src.translate(delta);
98 changed.assign_union(invalid_src);
99 changed.assign_union(copied);
100 copied = dest;
101 copy_delta = delta;
102 }
103 return;
104 }
105
106 Region invalid_src = overlap.intersect(changed);
107 invalid_src.translate(delta);
108 changed.assign_union(invalid_src);
109
110 overlap.translate(delta);
111
112 Region nonoverlapped_copied = dest.union_(copied).subtract(overlap);
113 changed.assign_union(nonoverlapped_copied);
114
115 copied = overlap;
116 copy_delta = copy_delta.translate(delta);
117
118 return;
119}
120
121void SimpleUpdateTracker::subtract(const Region& region) {
122 copied.assign_subtract(region);
123 changed.assign_subtract(region);
124}
125
126void SimpleUpdateTracker::getUpdateInfo(UpdateInfo* info, const Region& clip)
127{
Pierre Ossman02e43d72009-03-05 11:57:11 +0000128 copied.assign_subtract(changed);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000129 info->changed = changed.intersect(clip);
130 info->copied = copied.intersect(clip);
131 info->copy_delta = copy_delta;
132}
133
134void SimpleUpdateTracker::copyTo(UpdateTracker* to) const {
135 if (!copied.is_empty())
136 to->add_copied(copied, copy_delta);
137 if (!changed.is_empty())
138 to->add_changed(changed);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000139}