1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/capturer_helper.h"
#include <algorithm>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
namespace remoting {
CapturerHelper::CapturerHelper() :
size_most_recent_(SkISize::Make(0, 0)),
log_grid_size_(0) {
}
CapturerHelper::~CapturerHelper() {
}
void CapturerHelper::ClearInvalidRegion() {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
invalid_region_.setEmpty();
}
void CapturerHelper::InvalidateRegion(const SkRegion& invalid_region) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
invalid_region_.op(invalid_region, SkRegion::kUnion_Op);
}
void CapturerHelper::InvalidateScreen(const SkISize& size) {
base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
invalid_region_.op(SkIRect::MakeWH(size.width(), size.height()),
SkRegion::kUnion_Op);
}
void CapturerHelper::InvalidateFullScreen() {
if (!size_most_recent_.isZero())
InvalidateScreen(size_most_recent_);
}
void CapturerHelper::SwapInvalidRegion(SkRegion* invalid_region) {
{
base::AutoLock auto_invalid_region_lock(invalid_region_lock_);
invalid_region->swap(invalid_region_);
}
if (log_grid_size_ > 0) {
scoped_ptr<SkRegion> expanded_region(
ExpandToGrid(*invalid_region, log_grid_size_));
invalid_region->swap(*expanded_region);
invalid_region->op(SkRegion(SkIRect::MakeSize(size_most_recent_)),
SkRegion::kIntersect_Op);
}
}
void CapturerHelper::SetLogGridSize(int log_grid_size) {
log_grid_size_ = log_grid_size;
}
const SkISize& CapturerHelper::size_most_recent() const {
return size_most_recent_;
}
void CapturerHelper::set_size_most_recent(const SkISize& size) {
size_most_recent_ = size;
}
// Returns the largest multiple of |n| that is <= |x|.
// |n| must be a power of 2. |nMask| is ~(|n| - 1).
static int DownToMultiple(int x, int nMask) {
return (x & nMask);
}
// Returns the smallest multiple of |n| that is >= |x|.
// |n| must be a power of 2. |nMask| is ~(|n| - 1).
static int UpToMultiple(int x, int n, int nMask) {
return ((x + n - 1) & nMask);
}
scoped_ptr<SkRegion> CapturerHelper::ExpandToGrid(const SkRegion& region,
int log_grid_size) {
DCHECK(log_grid_size >= 1);
int grid_size = 1 << log_grid_size;
int grid_size_mask = ~(grid_size - 1);
// Count the rects in the region.
int rectNum = 0;
SkRegion::Iterator iter(region);
while (!iter.done()) {
iter.next();
++rectNum;
}
// Expand each rect.
scoped_array<SkIRect> rects(new SkIRect[rectNum]);
iter.rewind();
int rectI = 0;
while (!iter.done()) {
SkIRect rect = iter.rect();
iter.next();
int left = std::min(rect.left(), rect.right());
int right = std::max(rect.left(), rect.right());
int top = std::min(rect.top(), rect.bottom());
int bottom = std::max(rect.top(), rect.bottom());
left = DownToMultiple(left, grid_size_mask);
right = UpToMultiple(right, grid_size, grid_size_mask);
top = DownToMultiple(top, grid_size_mask);
bottom = UpToMultiple(bottom, grid_size, grid_size_mask);
rects[rectI++] = SkIRect::MakeLTRB(left, top, right, bottom);
}
// Make the union of the expanded rects.
scoped_ptr<SkRegion> regionNew(new SkRegion());
regionNew->setRects(rects.get(), rectNum);
return regionNew.Pass();
}
} // namespace remoting
|