OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_gdi.h" | 5 #include "remoting/host/capturer_gdi.h" |
| 6 #include "remoting/host/differ.h" |
6 | 7 |
7 #include "gfx/rect.h" | 8 #include "gfx/rect.h" |
8 | 9 |
9 namespace remoting { | 10 namespace remoting { |
10 | 11 |
11 // 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors. | 12 // 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors. |
12 static const int kPixelsPerMeter = 3780; | 13 static const int kPixelsPerMeter = 3780; |
13 // 32 bit RGBA is 4 bytes per pixel. | 14 // 32 bit RGBA is 4 bytes per pixel. |
14 static const int kBytesPerPixel = 4; | 15 static const int kBytesPerPixel = 4; |
15 | 16 |
16 CapturerGdi::CapturerGdi() : desktop_dc_(NULL), | 17 CapturerGdi::CapturerGdi() |
17 memory_dc_(NULL) { | 18 : desktop_dc_(NULL), |
| 19 memory_dc_(NULL), |
| 20 capture_fullscreen_(true) { |
18 memset(target_bitmap_, 0, sizeof(target_bitmap_)); | 21 memset(target_bitmap_, 0, sizeof(target_bitmap_)); |
19 memset(buffers_, 0, sizeof(buffers_)); | 22 memset(buffers_, 0, sizeof(buffers_)); |
20 } | 23 } |
21 | 24 |
22 CapturerGdi::~CapturerGdi() { | 25 CapturerGdi::~CapturerGdi() { |
23 ReleaseBuffers(); | 26 ReleaseBuffers(); |
24 } | 27 } |
25 | 28 |
26 void CapturerGdi::ReleaseBuffers() { | 29 void CapturerGdi::ReleaseBuffers() { |
27 for (int i = kNumBuffers - 1; i >= 0; i--) { | 30 for (int i = kNumBuffers - 1; i >= 0; i--) { |
(...skipping 22 matching lines...) Expand all Loading... |
50 | 53 |
51 // Create a bitmap to keep the desktop image. | 54 // Create a bitmap to keep the desktop image. |
52 width_ = GetSystemMetrics(SM_CXSCREEN); | 55 width_ = GetSystemMetrics(SM_CXSCREEN); |
53 height_ = GetSystemMetrics(SM_CYSCREEN); | 56 height_ = GetSystemMetrics(SM_CYSCREEN); |
54 int rounded_width = (width_ + 3) & (~3); | 57 int rounded_width = (width_ + 3) & (~3); |
55 | 58 |
56 // Dimensions of screen. | 59 // Dimensions of screen. |
57 pixel_format_ = PixelFormatRgb32; | 60 pixel_format_ = PixelFormatRgb32; |
58 bytes_per_row_ = rounded_width * kBytesPerPixel; | 61 bytes_per_row_ = rounded_width * kBytesPerPixel; |
59 | 62 |
| 63 // Create a differ for this screen size. |
| 64 differ_.reset(new Differ(width_, height_, 4, bytes_per_row_)); |
| 65 |
60 // Create a device independant bitmap (DIB) that is the same size. | 66 // Create a device independant bitmap (DIB) that is the same size. |
61 BITMAPINFO bmi; | 67 BITMAPINFO bmi; |
62 memset(&bmi, 0, sizeof(bmi)); | 68 memset(&bmi, 0, sizeof(bmi)); |
63 bmi.bmiHeader.biHeight = height_; | 69 bmi.bmiHeader.biHeight = height_; |
64 bmi.bmiHeader.biWidth = width_; | 70 bmi.bmiHeader.biWidth = width_; |
65 bmi.bmiHeader.biPlanes = 1; | 71 bmi.bmiHeader.biPlanes = 1; |
66 bmi.bmiHeader.biBitCount = kBytesPerPixel * 8; | 72 bmi.bmiHeader.biBitCount = kBytesPerPixel * 8; |
67 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); | 73 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); |
68 bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_; | 74 bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_; |
69 bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter; | 75 bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter; |
70 bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter; | 76 bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter; |
71 | 77 |
72 // Create memory for the buffers. | 78 // Create memory for the buffers. |
73 for (int i = 0; i < kNumBuffers; i++) { | 79 for (int i = 0; i < kNumBuffers; i++) { |
74 target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS, | 80 target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS, |
75 static_cast<void**>(&buffers_[i]), | 81 static_cast<void**>(&buffers_[i]), |
76 NULL, 0); | 82 NULL, 0); |
77 } | 83 } |
| 84 |
| 85 capture_fullscreen_ = true; |
78 } | 86 } |
79 | 87 |
80 void CapturerGdi::CaptureRects(const RectVector& rects, | 88 void CapturerGdi::CalculateInvalidRects() { |
| 89 ClearInvalidRects(); |
| 90 CaptureImage(); |
| 91 |
| 92 if (capture_fullscreen_) { |
| 93 InvalidateFullScreen(); |
| 94 } else { |
| 95 // Calculate the difference between the previous and current screen. |
| 96 int prev_buffer_id = current_buffer_ - 1; |
| 97 if (prev_buffer_id < 0) { |
| 98 prev_buffer_id = kNumBuffers - 1; |
| 99 } |
| 100 |
| 101 void* prev_buffer = buffers_[prev_buffer_id]; |
| 102 void* curr_buffer = buffers_[current_buffer_]; |
| 103 |
| 104 InvalidRects rects; |
| 105 differ_->CalcDirtyRects(prev_buffer, curr_buffer, &rects); |
| 106 |
| 107 InvalidateRects(rects); |
| 108 } |
| 109 |
| 110 capture_fullscreen_ = false; |
| 111 } |
| 112 |
| 113 void CapturerGdi::CaptureRects(const InvalidRects& rects, |
81 CaptureCompletedCallback* callback) { | 114 CaptureCompletedCallback* callback) { |
82 DataPlanes planes; | 115 DataPlanes planes; |
83 planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]); | 116 planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]); |
84 planes.strides[0] = bytes_per_row_; | 117 planes.strides[0] = bytes_per_row_; |
85 | 118 |
86 CaptureImage(); | |
87 scoped_refptr<CaptureData> data(new CaptureData(planes, | 119 scoped_refptr<CaptureData> data(new CaptureData(planes, |
88 width(), | 120 width(), |
89 height(), | 121 height(), |
90 pixel_format())); | 122 pixel_format())); |
91 data->mutable_dirty_rects() = rects; | 123 data->mutable_dirty_rects() = rects; |
92 | 124 |
93 FinishCapture(data, callback); | 125 FinishCapture(data, callback); |
94 } | 126 } |
95 | 127 |
96 void CapturerGdi::CaptureImage() { | 128 void CapturerGdi::CaptureImage() { |
97 // Selection the target bitmap into the memory dc. | 129 // Select the target bitmap into the memory dc. |
98 SelectObject(memory_dc_, target_bitmap_[current_buffer_]); | 130 SelectObject(memory_dc_, target_bitmap_[current_buffer_]); |
99 | 131 |
100 // And then copy the rect from desktop to memory. | 132 // And then copy the rect from desktop to memory. |
101 BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0, | 133 BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0, |
102 SRCCOPY | CAPTUREBLT); | 134 SRCCOPY | CAPTUREBLT); |
103 } | 135 } |
104 | 136 |
105 } // namespace remoting | 137 } // namespace remoting |
OLD | NEW |