| 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 |