Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: remoting/host/capturer_win.cc

Issue 7491070: Switch over to using SkRegions to calculate dirty areas. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clean up comments Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/capturer.h" 5 #include "remoting/host/capturer.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "remoting/host/capturer_helper.h" 10 #include "remoting/host/capturer_helper.h"
11 #include "remoting/host/differ.h" 11 #include "remoting/host/differ.h"
12 #include "ui/gfx/rect.h"
13 12
14 namespace remoting { 13 namespace remoting {
15 14
16 namespace { 15 namespace {
17 16
18 // CapturerGdi captures 32bit RGB using GDI. 17 // CapturerGdi captures 32bit RGB using GDI.
19 // 18 //
20 // CapturerGdi is double-buffered as required by Capturer. See 19 // CapturerGdi is double-buffered as required by Capturer. See
21 // remoting/host/capturer.h. 20 // remoting/host/capturer.h.
22 class CapturerGdi : public Capturer { 21 class CapturerGdi : public Capturer {
23 public: 22 public:
24 CapturerGdi(); 23 CapturerGdi();
25 virtual ~CapturerGdi(); 24 virtual ~CapturerGdi();
26 25
27 // Capturer interface. 26 // Capturer interface.
28 virtual void ScreenConfigurationChanged() OVERRIDE; 27 virtual void ScreenConfigurationChanged() OVERRIDE;
29 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; 28 virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
30 virtual void ClearInvalidRects() OVERRIDE; 29 virtual void ClearInvalidRegion() OVERRIDE;
31 virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE; 30 virtual void InvalidateRegion(const SkRegion& inval_region) OVERRIDE;
32 virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; 31 virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
33 virtual void InvalidateFullScreen() OVERRIDE; 32 virtual void InvalidateFullScreen() OVERRIDE;
34 virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE; 33 virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback)
34 OVERRIDE;
35 virtual const gfx::Size& size_most_recent() const OVERRIDE; 35 virtual const gfx::Size& size_most_recent() const OVERRIDE;
36 36
37 private: 37 private:
38 struct VideoFrameBuffer { 38 struct VideoFrameBuffer {
39 VideoFrameBuffer(void* data, const gfx::Size& size, int bytes_per_pixel, 39 VideoFrameBuffer(void* data, const gfx::Size& size, int bytes_per_pixel,
40 int bytes_per_row) 40 int bytes_per_row)
41 : data(data), size(size), bytes_per_pixel(bytes_per_pixel), 41 : data(data), size(size), bytes_per_pixel(bytes_per_pixel),
42 bytes_per_row(bytes_per_row) { 42 bytes_per_row(bytes_per_row) {
43 } 43 }
44 VideoFrameBuffer() { 44 VideoFrameBuffer() {
45 data = 0; 45 data = 0;
46 size = gfx::Size(0, 0); 46 size = gfx::Size(0, 0);
47 bytes_per_pixel = 0; 47 bytes_per_pixel = 0;
48 bytes_per_row = 0; 48 bytes_per_row = 0;
49 } 49 }
50 void* data; 50 void* data;
51 gfx::Size size; 51 gfx::Size size;
52 int bytes_per_pixel; 52 int bytes_per_pixel;
53 int bytes_per_row; 53 int bytes_per_row;
54 }; 54 };
55 55
56 // Make sure that the current buffer has the same size as the screen. 56 // Make sure that the current buffer has the same size as the screen.
57 void UpdateBufferCapture(const gfx::Size& size); 57 void UpdateBufferCapture(const gfx::Size& size);
58 58
59 // Allocate memory for a buffer of a given size, freeing any memory previously 59 // Allocate memory for a buffer of a given size, freeing any memory previously
60 // allocated for that buffer. 60 // allocated for that buffer.
61 void ReallocateBuffer(int buffer_index, const gfx::Size& size); 61 void ReallocateBuffer(int buffer_index, const gfx::Size& size);
62 62
63 void CalculateInvalidRects(); 63 void CalculateInvalidRegion();
64 void CaptureRects(const InvalidRects& rects, 64 void CaptureRegion(const SkRegion& region,
65 CaptureCompletedCallback* callback); 65 CaptureCompletedCallback* callback);
66 66
67 void ReleaseBuffers(); 67 void ReleaseBuffers();
68 // Generates an image in the current buffer. 68 // Generates an image in the current buffer.
69 void CaptureImage(); 69 void CaptureImage();
70 70
71 // Gets the current screen size and calls ScreenConfigurationChanged 71 // Gets the current screen size and calls ScreenConfigurationChanged
72 // if the screen size has changed. 72 // if the screen size has changed.
73 void MaybeChangeScreenConfiguration(); 73 void MaybeChangeScreenConfiguration();
74 74
75 // Gets the screen size. 75 // Gets the screen size.
76 gfx::Size GetScreenSize(); 76 gfx::Size GetScreenSize();
77 77
78 // A thread-safe list of invalid rectangles, and the size of the most 78 // A thread-safe list of invalid rectangles, and the size of the most
79 // recently captured screen. 79 // recently captured screen.
80 CapturerHelper helper; 80 CapturerHelper helper_;
81 81
82 // There are two buffers for the screen images, as required by Capturer. 82 // There are two buffers for the screen images, as required by Capturer.
83 static const int kNumBuffers = 2; 83 static const int kNumBuffers = 2;
84 VideoFrameBuffer buffers_[kNumBuffers]; 84 VideoFrameBuffer buffers_[kNumBuffers];
85 85
86 // Gdi specific information about screen. 86 // Gdi specific information about screen.
87 HDC desktop_dc_; 87 HDC desktop_dc_;
88 HDC memory_dc_; 88 HDC memory_dc_;
89 HBITMAP target_bitmap_[kNumBuffers]; 89 HBITMAP target_bitmap_[kNumBuffers];
90 90
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 125 }
126 126
127 CapturerGdi::~CapturerGdi() { 127 CapturerGdi::~CapturerGdi() {
128 ReleaseBuffers(); 128 ReleaseBuffers();
129 } 129 }
130 130
131 media::VideoFrame::Format CapturerGdi::pixel_format() const { 131 media::VideoFrame::Format CapturerGdi::pixel_format() const {
132 return pixel_format_; 132 return pixel_format_;
133 } 133 }
134 134
135 void CapturerGdi::ClearInvalidRects() { 135 void CapturerGdi::ClearInvalidRegion() {
136 helper.ClearInvalidRects(); 136 helper_.ClearInvalidRegion();
137 } 137 }
138 138
139 void CapturerGdi::InvalidateRects(const InvalidRects& inval_rects) { 139 void CapturerGdi::InvalidateRegion(const SkRegion& inval_region) {
140 helper.InvalidateRects(inval_rects); 140 helper_.InvalidateRegion(inval_region);
141 } 141 }
142 142
143 void CapturerGdi::InvalidateScreen(const gfx::Size& size) { 143 void CapturerGdi::InvalidateScreen(const gfx::Size& size) {
144 helper.InvalidateScreen(size); 144 helper_.InvalidateScreen(size);
145 } 145 }
146 146
147 void CapturerGdi::InvalidateFullScreen() { 147 void CapturerGdi::InvalidateFullScreen() {
148 helper.InvalidateFullScreen(); 148 helper_.InvalidateFullScreen();
149 } 149 }
150 150
151 void CapturerGdi::CaptureInvalidRects(CaptureCompletedCallback* callback) { 151 void CapturerGdi::CaptureInvalidRegion(CaptureCompletedCallback* callback) {
152 CalculateInvalidRects(); 152 CalculateInvalidRegion();
153 InvalidRects inval_rects; 153 SkRegion inval_region;
154 helper.SwapInvalidRects(inval_rects); 154 helper_.SwapInvalidRegion(inval_region);
155 CaptureRects(inval_rects, callback); 155 CaptureRegion(inval_region, callback);
156 } 156 }
157 157
158 const gfx::Size& CapturerGdi::size_most_recent() const { 158 const gfx::Size& CapturerGdi::size_most_recent() const {
159 return helper.size_most_recent(); 159 return helper_.size_most_recent();
160 } 160 }
161 161
162 void CapturerGdi::ReleaseBuffers() { 162 void CapturerGdi::ReleaseBuffers() {
163 for (int i = kNumBuffers - 1; i >= 0; i--) { 163 for (int i = kNumBuffers - 1; i >= 0; i--) {
164 if (target_bitmap_[i]) { 164 if (target_bitmap_[i]) {
165 DeleteObject(target_bitmap_[i]); 165 DeleteObject(target_bitmap_[i]);
166 target_bitmap_[i] = NULL; 166 target_bitmap_[i] = NULL;
167 } 167 }
168 if (buffers_[i].data) { 168 if (buffers_[i].data) {
169 DeleteObject(buffers_[i].data); 169 DeleteObject(buffers_[i].data);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS, 236 CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
237 static_cast<void**>(&buffers_[buffer_index].data), 237 static_cast<void**>(&buffers_[buffer_index].data),
238 NULL, 0); 238 NULL, 0);
239 buffers_[buffer_index].size = gfx::Size(bmi.bmiHeader.biWidth, 239 buffers_[buffer_index].size = gfx::Size(bmi.bmiHeader.biWidth,
240 std::abs(bmi.bmiHeader.biHeight)); 240 std::abs(bmi.bmiHeader.biHeight));
241 buffers_[buffer_index].bytes_per_pixel = bmi.bmiHeader.biBitCount / 8; 241 buffers_[buffer_index].bytes_per_pixel = bmi.bmiHeader.biBitCount / 8;
242 buffers_[buffer_index].bytes_per_row = 242 buffers_[buffer_index].bytes_per_row =
243 bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight); 243 bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight);
244 } 244 }
245 245
246 void CapturerGdi::CalculateInvalidRects() { 246 void CapturerGdi::CalculateInvalidRegion() {
247 CaptureImage(); 247 CaptureImage();
248 248
249 const VideoFrameBuffer& current = buffers_[current_buffer_]; 249 const VideoFrameBuffer& current = buffers_[current_buffer_];
250 if (helper.IsCaptureFullScreen(current.size)) 250 if (helper_.IsCaptureFullScreen(current.size))
251 capture_fullscreen_ = true; 251 capture_fullscreen_ = true;
252 252
253 if (capture_fullscreen_) { 253 if (capture_fullscreen_) {
254 InvalidateScreen(current.size); 254 InvalidateScreen(current.size);
255 capture_fullscreen_ = false; 255 capture_fullscreen_ = false;
256 return; 256 return;
257 } 257 }
258 258
259 // Find the previous and current screens. 259 // Find the previous and current screens.
260 int prev_buffer_id = current_buffer_ - 1; 260 int prev_buffer_id = current_buffer_ - 1;
(...skipping 14 matching lines...) Expand all
275 // current screens. 275 // current screens.
276 if (!differ_.get() || 276 if (!differ_.get() ||
277 (differ_->width() != current.size.width()) || 277 (differ_->width() != current.size.width()) ||
278 (differ_->height() != current.size.height()) || 278 (differ_->height() != current.size.height()) ||
279 (differ_->bytes_per_pixel() != current.bytes_per_pixel) || 279 (differ_->bytes_per_pixel() != current.bytes_per_pixel) ||
280 (differ_->bytes_per_row() != current.bytes_per_row)) { 280 (differ_->bytes_per_row() != current.bytes_per_row)) {
281 differ_.reset(new Differ(current.size.width(), current.size.height(), 281 differ_.reset(new Differ(current.size.width(), current.size.height(),
282 current.bytes_per_pixel, current.bytes_per_row)); 282 current.bytes_per_pixel, current.bytes_per_row));
283 } 283 }
284 284
285 InvalidRects rects; 285 SkRegion region;
286 differ_->CalcDirtyRects(prev.data, current.data, &rects); 286 differ_->CalcDirtyRegion(prev.data, current.data, &region);
287 287
288 InvalidateRects(rects); 288 InvalidateRegion(region);
289 } 289 }
290 290
291 void CapturerGdi::CaptureRects(const InvalidRects& rects, 291 void CapturerGdi::CaptureRegion(const SkRegion& region,
292 CaptureCompletedCallback* callback) { 292 CaptureCompletedCallback* callback) {
293 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); 293 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
294 294
295 const VideoFrameBuffer& buffer = buffers_[current_buffer_]; 295 const VideoFrameBuffer& buffer = buffers_[current_buffer_];
296 current_buffer_ = (current_buffer_ + 1) % kNumBuffers; 296 current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
297 297
298 DataPlanes planes; 298 DataPlanes planes;
299 planes.data[0] = static_cast<uint8*>(buffer.data); 299 planes.data[0] = static_cast<uint8*>(buffer.data);
300 planes.strides[0] = buffer.bytes_per_row; 300 planes.strides[0] = buffer.bytes_per_row;
301 301
302 scoped_refptr<CaptureData> data(new CaptureData(planes, 302 scoped_refptr<CaptureData> data(new CaptureData(planes,
303 buffer.size, 303 buffer.size,
304 pixel_format_)); 304 pixel_format_));
305 data->mutable_dirty_rects() = rects; 305 data->mutable_dirty_region() = region;
306 306
307 helper.set_size_most_recent(data->size()); 307 helper_.set_size_most_recent(data->size());
308 308
309 callback->Run(data); 309 callback->Run(data);
310 } 310 }
311 311
312 void CapturerGdi::CaptureImage() { 312 void CapturerGdi::CaptureImage() {
313 // Make sure the structures we use to capture the image have the correct size. 313 // Make sure the structures we use to capture the image have the correct size.
314 UpdateBufferCapture(GetScreenSize()); 314 UpdateBufferCapture(GetScreenSize());
315 315
316 // Select the target bitmap into the memory dc. 316 // Select the target bitmap into the memory dc.
317 SelectObject(memory_dc_, target_bitmap_[current_buffer_]); 317 SelectObject(memory_dc_, target_bitmap_[current_buffer_]);
(...skipping 10 matching lines...) Expand all
328 } 328 }
329 329
330 } // namespace 330 } // namespace
331 331
332 // static 332 // static
333 Capturer* Capturer::Create() { 333 Capturer* Capturer::Create() {
334 return new CapturerGdi(); 334 return new CapturerGdi();
335 } 335 }
336 336
337 } // namespace remoting 337 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698