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

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

Issue 7491070: Switch over to using SkRegions to calculate dirty areas. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleaned 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 <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h> 8 #include <X11/Xutil.h>
9 #include <X11/extensions/Xdamage.h> 9 #include <X11/extensions/Xdamage.h>
10 10
11 #include <set> 11 #include <set>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "remoting/base/types.h"
17 #include "remoting/host/capturer_helper.h" 16 #include "remoting/host/capturer_helper.h"
18 #include "remoting/host/differ.h" 17 #include "remoting/host/differ.h"
19 #include "remoting/host/x_server_pixel_buffer.h" 18 #include "remoting/host/x_server_pixel_buffer.h"
20 19
21 namespace remoting { 20 namespace remoting {
22 21
23 namespace { 22 namespace {
24 23
25 static const int kBytesPerPixel = 4; 24 static const int kBytesPerPixel = 4;
26 25
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // A class to perform capturing for Linux. 67 // A class to perform capturing for Linux.
69 class CapturerLinux : public Capturer { 68 class CapturerLinux : public Capturer {
70 public: 69 public:
71 CapturerLinux(); 70 CapturerLinux();
72 virtual ~CapturerLinux(); 71 virtual ~CapturerLinux();
73 72
74 73
75 // Capturer interface. 74 // Capturer interface.
76 virtual void ScreenConfigurationChanged() OVERRIDE; 75 virtual void ScreenConfigurationChanged() OVERRIDE;
77 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; 76 virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
78 virtual void ClearInvalidRects() OVERRIDE; 77 virtual void ClearInvalidRegion() OVERRIDE;
79 virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE; 78 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
80 virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE; 79 virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
81 virtual void InvalidateFullScreen() OVERRIDE; 80 virtual void InvalidateFullScreen() OVERRIDE;
82 virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE; 81 virtual void CaptureInvalidRegion(CaptureCompletedCallback* callback)
82 OVERRIDE;
83 virtual const gfx::Size& size_most_recent() const OVERRIDE; 83 virtual const gfx::Size& size_most_recent() const OVERRIDE;
84 84
85 private: 85 private:
86 bool Init(); // TODO(ajwong): Do we really want this to be synchronous? 86 bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
87 87
88 void InitXDamage(); 88 void InitXDamage();
89 89
90 // Read and handle all currently-pending XEvents. 90 // Read and handle all currently-pending XEvents.
91 // In the DAMAGE case, process the XDamage events and store the resulting 91 // In the DAMAGE case, process the XDamage events and store the resulting
92 // damage rectangles in the CapturerHelper. 92 // damage rectangles in the CapturerHelper.
(...skipping 14 matching lines...) Expand all
107 // the area of |last_invalid_rects|. 107 // the area of |last_invalid_rects|.
108 // Note this only works on the assumption that kNumBuffers == 2, as 108 // Note this only works on the assumption that kNumBuffers == 2, as
109 // |last_invalid_rects| holds the differences from the previous buffer and 109 // |last_invalid_rects| holds the differences from the previous buffer and
110 // the one prior to that (which will then be the current buffer). 110 // the one prior to that (which will then be the current buffer).
111 void SynchronizeFrame(); 111 void SynchronizeFrame();
112 112
113 void DeinitXlib(); 113 void DeinitXlib();
114 114
115 // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into 115 // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into
116 // |capture_data|. 116 // |capture_data|.
117 void CaptureRect(const gfx::Rect& rect, CaptureData* capture_data); 117 void CaptureRect(const SkIRect& rect, CaptureData* capture_data);
118 118
119 // We expose two forms of blitting to handle variations in the pixel format. 119 // We expose two forms of blitting to handle variations in the pixel format.
120 // In FastBlit, the operation is effectively a memcpy. 120 // In FastBlit, the operation is effectively a memcpy.
121 void FastBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); 121 void FastBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data);
122 void SlowBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); 122 void SlowBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data);
123 123
124 // X11 graphics context. 124 // X11 graphics context.
125 Display* display_; 125 Display* display_;
126 GC gc_; 126 GC gc_;
127 Window root_window_; 127 Window root_window_;
128 128
129 // XDamage information. 129 // XDamage information.
130 bool use_damage_; 130 bool use_damage_;
131 Damage damage_handle_; 131 Damage damage_handle_;
132 int damage_event_base_; 132 int damage_event_base_;
133 int damage_error_base_; 133 int damage_error_base_;
134 134
135 // Access to the X Server's pixel buffer. 135 // Access to the X Server's pixel buffer.
136 XServerPixelBuffer x_server_pixel_buffer_; 136 XServerPixelBuffer x_server_pixel_buffer_;
137 137
138 // A thread-safe list of invalid rectangles, and the size of the most 138 // A thread-safe list of invalid rectangles, and the size of the most
139 // recently captured screen. 139 // recently captured screen.
140 CapturerHelper helper_; 140 CapturerHelper helper_;
141 141
142 // Capture state. 142 // Capture state.
143 static const int kNumBuffers = 2; 143 static const int kNumBuffers = 2;
144 VideoFrameBuffer buffers_[kNumBuffers]; 144 VideoFrameBuffer buffers_[kNumBuffers];
145 int current_buffer_; 145 int current_buffer_;
146 146
147 // Format of pixels returned in buffer. 147 // Format of pixels returned in buffer.
148 media::VideoFrame::Format pixel_format_; 148 media::VideoFrame::Format pixel_format_;
149 149
150 // Invalid rects in the last capture. This is used to synchronize current with 150 // Invalid region from the last capture. This is used to synchronize the
151 // the previous buffer used. 151 // current with the last buffer used.
Wez 2011/08/10 22:05:43 nit: Previous.
152 InvalidRects last_invalid_rects_; 152 SkRegion last_invalid_region_;
Wez 2011/08/10 22:05:43 nit: |previous_invalid_region_|
153 153
154 // Last capture buffer used. 154 // Last capture buffer used.
155 uint8* last_buffer_; 155 uint8* last_buffer_;
156 156
157 // |Differ| for use when polling for changes. 157 // |Differ| for use when polling for changes.
158 scoped_ptr<Differ> differ_; 158 scoped_ptr<Differ> differ_;
159 159
160 DISALLOW_COPY_AND_ASSIGN(CapturerLinux); 160 DISALLOW_COPY_AND_ASSIGN(CapturerLinux);
161 }; 161 };
162 162
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } else { 233 } else {
234 LOG(INFO) << "Server does not support XDamage."; 234 LOG(INFO) << "Server does not support XDamage.";
235 } 235 }
236 } 236 }
237 237
238 void CapturerLinux::ScreenConfigurationChanged() { 238 void CapturerLinux::ScreenConfigurationChanged() {
239 last_buffer_ = NULL; 239 last_buffer_ = NULL;
240 for (int i = 0; i < kNumBuffers; ++i) { 240 for (int i = 0; i < kNumBuffers; ++i) {
241 buffers_[i].set_needs_update(); 241 buffers_[i].set_needs_update();
242 } 242 }
243 InvalidRects rects; 243 helper_.ClearInvalidRegion();
244 helper_.SwapInvalidRects(rects);
245 x_server_pixel_buffer_.Init(display_); 244 x_server_pixel_buffer_.Init(display_);
246 } 245 }
247 246
248 media::VideoFrame::Format CapturerLinux::pixel_format() const { 247 media::VideoFrame::Format CapturerLinux::pixel_format() const {
249 return pixel_format_; 248 return pixel_format_;
250 } 249 }
251 250
252 void CapturerLinux::ClearInvalidRects() { 251 void CapturerLinux::ClearInvalidRegion() {
253 helper_.ClearInvalidRects(); 252 helper_.ClearInvalidRegion();
254 } 253 }
255 254
256 void CapturerLinux::InvalidateRects(const InvalidRects& inval_rects) { 255 void CapturerLinux::InvalidateRegion(const SkRegion& invalid_region) {
257 helper_.InvalidateRects(inval_rects); 256 helper_.InvalidateRegion(invalid_region);
258 } 257 }
259 258
260 void CapturerLinux::InvalidateScreen(const gfx::Size& size) { 259 void CapturerLinux::InvalidateScreen(const gfx::Size& size) {
261 helper_.InvalidateScreen(size); 260 helper_.InvalidateScreen(size);
262 } 261 }
263 262
264 void CapturerLinux::InvalidateFullScreen() { 263 void CapturerLinux::InvalidateFullScreen() {
265 helper_.InvalidateFullScreen(); 264 helper_.InvalidateFullScreen();
266 last_buffer_ = NULL; 265 last_buffer_ = NULL;
267 } 266 }
268 267
269 void CapturerLinux::CaptureInvalidRects( 268 void CapturerLinux::CaptureInvalidRegion(
270 CaptureCompletedCallback* callback) { 269 CaptureCompletedCallback* callback) {
271 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); 270 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
272 271
273 // TODO(lambroslambrou): In the non-DAMAGE case, there should be no need 272 // TODO(lambroslambrou): In the non-DAMAGE case, there should be no need
274 // for any X event processing in this class. 273 // for any X event processing in this class.
275 ProcessPendingXEvents(); 274 ProcessPendingXEvents();
276 275
277 // Resize the current buffer if there was a recent change of 276 // Resize the current buffer if there was a recent change of
278 // screen-resolution. 277 // screen-resolution.
279 VideoFrameBuffer &current = buffers_[current_buffer_]; 278 VideoFrameBuffer &current = buffers_[current_buffer_];
(...skipping 10 matching lines...) Expand all
290 helper_.set_size_most_recent(capture_data->size()); 289 helper_.set_size_most_recent(capture_data->size());
291 290
292 callback->Run(capture_data); 291 callback->Run(capture_data);
293 } 292 }
294 293
295 void CapturerLinux::ProcessPendingXEvents() { 294 void CapturerLinux::ProcessPendingXEvents() {
296 // Find the number of events that are outstanding "now." We don't just loop 295 // Find the number of events that are outstanding "now." We don't just loop
297 // on XPending because we want to guarantee this terminates. 296 // on XPending because we want to guarantee this terminates.
298 int events_to_process = XPending(display_); 297 int events_to_process = XPending(display_);
299 XEvent e; 298 XEvent e;
300 InvalidRects invalid_rects; 299 SkRegion invalid_region;
301 300
302 for (int i = 0; i < events_to_process; i++) { 301 for (int i = 0; i < events_to_process; i++) {
303 XNextEvent(display_, &e); 302 XNextEvent(display_, &e);
304 if (use_damage_ && (e.type == damage_event_base_ + XDamageNotify)) { 303 if (use_damage_ && (e.type == damage_event_base_ + XDamageNotify)) {
305 XDamageNotifyEvent *event = reinterpret_cast<XDamageNotifyEvent*>(&e); 304 XDamageNotifyEvent *event = reinterpret_cast<XDamageNotifyEvent*>(&e);
306 305
307 // TODO(hclam): Perform more checks on the rect. 306 // TODO(hclam): Perform more checks on the rect.
308 if (event->area.width <= 0 || event->area.height <= 0) 307 if (event->area.width <= 0 || event->area.height <= 0)
309 continue; 308 continue;
310 309
311 gfx::Rect damage_rect(event->area.x, event->area.y, event->area.width, 310 SkIRect damage_rect = SkIRect::MakeXYWH(event->area.x,
312 event->area.height); 311 event->area.y,
313 invalid_rects.insert(damage_rect); 312 event->area.width,
314 VLOG(3) << "Damage received for rect at (" 313 event->area.height);
315 << damage_rect.x() << "," << damage_rect.y() << ") size (" 314 invalid_region.op(damage_rect, SkRegion::kUnion_Op);
316 << damage_rect.width() << "," << damage_rect.height() << ")"; 315 DVLOG(3) << "Damage received for rect at ("
316 << damage_rect.fLeft << "," << damage_rect.fTop << ") size ("
317 << damage_rect.width() << "," << damage_rect.height() << ")";
317 } else if (e.type == ConfigureNotify) { 318 } else if (e.type == ConfigureNotify) {
318 ScreenConfigurationChanged(); 319 ScreenConfigurationChanged();
319 invalid_rects.clear(); 320 invalid_region.setEmpty();
320 } else { 321 } else {
321 LOG(WARNING) << "Got unknown event type: " << e.type; 322 LOG(WARNING) << "Got unknown event type: " << e.type;
322 } 323 }
323 } 324 }
324 325
325 helper_.InvalidateRects(invalid_rects); 326 helper_.InvalidateRegion(invalid_region);
326 } 327 }
327 328
328 CaptureData* CapturerLinux::CaptureFrame() { 329 CaptureData* CapturerLinux::CaptureFrame() {
329 VideoFrameBuffer& buffer = buffers_[current_buffer_]; 330 VideoFrameBuffer& buffer = buffers_[current_buffer_];
330 DataPlanes planes; 331 DataPlanes planes;
331 planes.data[0] = buffer.ptr(); 332 planes.data[0] = buffer.ptr();
332 planes.strides[0] = buffer.bytes_per_row(); 333 planes.strides[0] = buffer.bytes_per_row();
333 334
334 CaptureData* capture_data = new CaptureData(planes, buffer.size(), 335 CaptureData* capture_data = new CaptureData(planes, buffer.size(),
335 media::VideoFrame::RGB32); 336 media::VideoFrame::RGB32);
336 337
337 // In the DAMAGE case, ensure the frame is up-to-date with the previous frame 338 // In the DAMAGE case, ensure the frame is up-to-date with the previous frame
338 // if any. If there isn't a previous frame, that means a screen-resolution 339 // if any. If there isn't a previous frame, that means a screen-resolution
339 // change occurred, and |invalid_rects| will be updated to include the whole 340 // change occurred, and |invalid_rects| will be updated to include the whole
340 // screen. 341 // screen.
341 if (use_damage_ && last_buffer_) 342 if (use_damage_ && last_buffer_)
342 SynchronizeFrame(); 343 SynchronizeFrame();
343 344
344 InvalidRects invalid_rects; 345 SkRegion invalid_region;
345 346
346 x_server_pixel_buffer_.Synchronize(); 347 x_server_pixel_buffer_.Synchronize();
347 if (use_damage_ && last_buffer_) { 348 if (use_damage_ && last_buffer_) {
348 helper_.SwapInvalidRects(invalid_rects); 349 helper_.SwapInvalidRegion(&invalid_region);
349 for (InvalidRects::const_iterator it = invalid_rects.begin(); 350 for (SkRegion::Iterator it(invalid_region); !it.done(); it.next()) {
350 it != invalid_rects.end(); 351 CaptureRect(it.rect(), capture_data);
351 ++it) {
352 CaptureRect(*it, capture_data);
353 } 352 }
354 // TODO(ajwong): We should only repair the rects that were copied! 353 // TODO(ajwong): We should only repair the rects that were copied!
355 XDamageSubtract(display_, damage_handle_, None, None); 354 XDamageSubtract(display_, damage_handle_, None, None);
356 } else { 355 } else {
357 // Doing full-screen polling, or this is the first capture after a 356 // Doing full-screen polling, or this is the first capture after a
358 // screen-resolution change. In either case, need a full-screen capture. 357 // screen-resolution change. In either case, need a full-screen capture.
359 gfx::Rect screen_rect(buffer.size()); 358 SkIRect screen_rect = SkIRect::MakeWH(buffer.size().width(),
359 buffer.size().height());
360 CaptureRect(screen_rect, capture_data); 360 CaptureRect(screen_rect, capture_data);
361 361
362 if (last_buffer_) { 362 if (last_buffer_) {
363 // Full-screen polling, so calculate the invalid rects here, based on the 363 // Full-screen polling, so calculate the invalid rects here, based on the
364 // changed pixels between current and previous buffers. 364 // changed pixels between current and previous buffers.
365 DCHECK(differ_ != NULL); 365 DCHECK(differ_ != NULL);
366 differ_->CalcDirtyRects(last_buffer_, buffer.ptr(), &invalid_rects); 366 differ_->CalcDirtyRegion(last_buffer_, buffer.ptr(), &invalid_region);
367 } else { 367 } else {
368 // No previous buffer, so always invalidate the whole screen, whether 368 // No previous buffer, so always invalidate the whole screen, whether
369 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a 369 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a
370 // full-screen notification after a screen-resolution change, so 370 // full-screen notification after a screen-resolution change, so
371 // this is done here. 371 // this is done here.
372 invalid_rects.insert(screen_rect); 372 invalid_region.op(screen_rect, SkRegion::kUnion_Op);
373 } 373 }
374 } 374 }
375 375
376 capture_data->mutable_dirty_rects() = invalid_rects; 376 capture_data->mutable_dirty_region() = invalid_region;
377 last_invalid_rects_ = invalid_rects; 377 last_invalid_region_ = invalid_region;
378 last_buffer_ = buffer.ptr(); 378 last_buffer_ = buffer.ptr();
379 return capture_data; 379 return capture_data;
380 } 380 }
381 381
382 void CapturerLinux::SynchronizeFrame() { 382 void CapturerLinux::SynchronizeFrame() {
383 // Synchronize the current buffer with the last one since we do not capture 383 // Synchronize the current buffer with the last one since we do not capture
384 // the entire desktop. Note that encoder may be reading from the previous 384 // the entire desktop. Note that encoder may be reading from the previous
385 // buffer at this time so thread access complaints are false positives. 385 // buffer at this time so thread access complaints are false positives.
386 386
387 // TODO(hclam): We can reduce the amount of copying here by subtracting 387 // TODO(hclam): We can reduce the amount of copying here by subtracting
388 // |rects| from |last_invalid_rects_|. 388 // |capturer_helper_|s region from |last_invalid_region_|.
389 // http://crbug.com/92354
389 DCHECK(last_buffer_); 390 DCHECK(last_buffer_);
390 VideoFrameBuffer& buffer = buffers_[current_buffer_]; 391 VideoFrameBuffer& buffer = buffers_[current_buffer_];
391 for (InvalidRects::const_iterator it = last_invalid_rects_.begin(); 392 for (SkRegion::Iterator it(last_invalid_region_); !it.done(); it.next()) {
392 it != last_invalid_rects_.end(); 393 const SkIRect& r = it.rect();
393 ++it) { 394 int offset = r.fTop * buffer.bytes_per_row() + r.fLeft * kBytesPerPixel;
394 int offset = it->y() * buffer.bytes_per_row() + it->x() * kBytesPerPixel; 395 for (int i = 0; i < r.height(); ++i) {
395 for (int i = 0; i < it->height(); ++i) {
396 memcpy(buffer.ptr() + offset, last_buffer_ + offset, 396 memcpy(buffer.ptr() + offset, last_buffer_ + offset,
397 it->width() * kBytesPerPixel); 397 r.width() * kBytesPerPixel);
398 offset += buffer.size().width() * kBytesPerPixel; 398 offset += buffer.size().width() * kBytesPerPixel;
399 } 399 }
400 } 400 }
401 } 401 }
402 402
403 void CapturerLinux::DeinitXlib() { 403 void CapturerLinux::DeinitXlib() {
404 if (gc_) { 404 if (gc_) {
405 XFreeGC(display_, gc_); 405 XFreeGC(display_, gc_);
406 gc_ = NULL; 406 gc_ = NULL;
407 } 407 }
408 408
409 if (display_) { 409 if (display_) {
410 XCloseDisplay(display_); 410 XCloseDisplay(display_);
411 display_ = NULL; 411 display_ = NULL;
412 } 412 }
413 } 413 }
414 414
415 void CapturerLinux::CaptureRect(const gfx::Rect& rect, 415 void CapturerLinux::CaptureRect(const SkIRect& rect,
416 CaptureData* capture_data) { 416 CaptureData* capture_data) {
417 uint8* image = x_server_pixel_buffer_.CaptureRect(rect); 417 uint8* image = x_server_pixel_buffer_.CaptureRect(rect);
418 int depth = x_server_pixel_buffer_.GetDepth(); 418 int depth = x_server_pixel_buffer_.GetDepth();
419 int bpp = x_server_pixel_buffer_.GetBitsPerPixel(); 419 int bpp = x_server_pixel_buffer_.GetBitsPerPixel();
420 bool is_rgb = x_server_pixel_buffer_.IsRgb(); 420 bool is_rgb = x_server_pixel_buffer_.IsRgb();
421 if ((depth == 24 || depth == 32) && bpp == 32 && is_rgb) { 421 if ((depth == 24 || depth == 32) && bpp == 32 && is_rgb) {
422 VLOG(3) << "Fast blitting"; 422 DVLOG(3) << "Fast blitting";
423 FastBlit(image, rect, capture_data); 423 FastBlit(image, rect, capture_data);
424 } else { 424 } else {
425 VLOG(3) << "Slow blitting"; 425 DVLOG(3) << "Slow blitting";
426 SlowBlit(image, rect, capture_data); 426 SlowBlit(image, rect, capture_data);
427 } 427 }
428 } 428 }
429 429
430 void CapturerLinux::FastBlit(uint8* image, const gfx::Rect& rect, 430 void CapturerLinux::FastBlit(uint8* image, const SkIRect& rect,
431 CaptureData* capture_data) { 431 CaptureData* capture_data) {
432 uint8* src_pos = image; 432 uint8* src_pos = image;
433 int src_stride = x_server_pixel_buffer_.GetStride(); 433 int src_stride = x_server_pixel_buffer_.GetStride();
434 int dst_x = rect.x(), dst_y = rect.y(); 434 int dst_x = rect.fLeft, dst_y = rect.fTop;
435 435
436 DataPlanes planes = capture_data->data_planes(); 436 DataPlanes planes = capture_data->data_planes();
437 uint8* dst_buffer = planes.data[0]; 437 uint8* dst_buffer = planes.data[0];
438 438
439 const int dst_stride = planes.strides[0]; 439 const int dst_stride = planes.strides[0];
440 440
441 uint8* dst_pos = dst_buffer + dst_stride * dst_y; 441 uint8* dst_pos = dst_buffer + dst_stride * dst_y;
442 dst_pos += dst_x * kBytesPerPixel; 442 dst_pos += dst_x * kBytesPerPixel;
443 443
444 int height = rect.height(), row_bytes = rect.width() * kBytesPerPixel; 444 int height = rect.height(), row_bytes = rect.width() * kBytesPerPixel;
445 for (int y = 0; y < height; ++y) { 445 for (int y = 0; y < height; ++y) {
446 memcpy(dst_pos, src_pos, row_bytes); 446 memcpy(dst_pos, src_pos, row_bytes);
447 src_pos += src_stride; 447 src_pos += src_stride;
448 dst_pos += dst_stride; 448 dst_pos += dst_stride;
449 } 449 }
450 } 450 }
451 451
452 void CapturerLinux::SlowBlit(uint8* image, const gfx::Rect& rect, 452 void CapturerLinux::SlowBlit(uint8* image, const SkIRect& rect,
453 CaptureData* capture_data) { 453 CaptureData* capture_data) {
454 DataPlanes planes = capture_data->data_planes(); 454 DataPlanes planes = capture_data->data_planes();
455 uint8* dst_buffer = planes.data[0]; 455 uint8* dst_buffer = planes.data[0];
456 const int dst_stride = planes.strides[0]; 456 const int dst_stride = planes.strides[0];
457 int src_stride = x_server_pixel_buffer_.GetStride(); 457 int src_stride = x_server_pixel_buffer_.GetStride();
458 int dst_x = rect.x(), dst_y = rect.y(); 458 int dst_x = rect.fLeft, dst_y = rect.fTop;
459 int width = rect.width(), height = rect.height(); 459 int width = rect.width(), height = rect.height();
460 460
461 unsigned int red_mask = x_server_pixel_buffer_.GetRedMask(); 461 unsigned int red_mask = x_server_pixel_buffer_.GetRedMask();
462 unsigned int blue_mask = x_server_pixel_buffer_.GetBlueMask(); 462 unsigned int blue_mask = x_server_pixel_buffer_.GetBlueMask();
463 unsigned int green_mask = x_server_pixel_buffer_.GetGreenMask(); 463 unsigned int green_mask = x_server_pixel_buffer_.GetGreenMask();
464 unsigned int red_shift = x_server_pixel_buffer_.GetRedShift(); 464 unsigned int red_shift = x_server_pixel_buffer_.GetRedShift();
465 unsigned int blue_shift = x_server_pixel_buffer_.GetBlueShift(); 465 unsigned int blue_shift = x_server_pixel_buffer_.GetBlueShift();
466 unsigned int green_shift = x_server_pixel_buffer_.GetGreenShift(); 466 unsigned int green_shift = x_server_pixel_buffer_.GetGreenShift();
467 467
468 unsigned int max_red = red_mask >> red_shift; 468 unsigned int max_red = red_mask >> red_shift;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 } 505 }
506 506
507 } // namespace 507 } // namespace
508 508
509 // static 509 // static
510 Capturer* Capturer::Create() { 510 Capturer* Capturer::Create() {
511 return new CapturerLinux(); 511 return new CapturerLinux();
512 } 512 }
513 513
514 } // namespace remoting 514 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698