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_mac.h" | 5 #include "remoting/host/capturer_mac.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <OpenGL/CGLMacro.h> | 9 #include <OpenGL/CGLMacro.h> |
10 | 10 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 CGDirectDisplayID mainDevice = CGMainDisplayID(); | 48 CGDirectDisplayID mainDevice = CGMainDisplayID(); |
49 | 49 |
50 width_ = CGDisplayPixelsWide(mainDevice); | 50 width_ = CGDisplayPixelsWide(mainDevice); |
51 height_ = CGDisplayPixelsHigh(mainDevice); | 51 height_ = CGDisplayPixelsHigh(mainDevice); |
52 pixel_format_ = media::VideoFrame::RGB32; | 52 pixel_format_ = media::VideoFrame::RGB32; |
53 bytes_per_row_ = width_ * sizeof(uint32_t); | 53 bytes_per_row_ = width_ * sizeof(uint32_t); |
54 size_t buffer_size = height() * bytes_per_row_; | 54 size_t buffer_size = height() * bytes_per_row_; |
55 for (int i = 0; i < kNumBuffers; ++i) { | 55 for (int i = 0; i < kNumBuffers; ++i) { |
56 buffers_[i].reset(new uint8[buffer_size]); | 56 buffers_[i].reset(new uint8[buffer_size]); |
57 } | 57 } |
58 flip_buffer_.reset(new uint8[buffer_size]); | |
58 CGLPixelFormatAttribute attributes[] = { | 59 CGLPixelFormatAttribute attributes[] = { |
59 kCGLPFAFullScreen, | 60 kCGLPFAFullScreen, |
60 kCGLPFADisplayMask, | 61 kCGLPFADisplayMask, |
61 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), | 62 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), |
62 (CGLPixelFormatAttribute)0 | 63 (CGLPixelFormatAttribute)0 |
63 }; | 64 }; |
64 CGLPixelFormatObj pixel_format = NULL; | 65 CGLPixelFormatObj pixel_format = NULL; |
65 GLint matching_pixel_format_count = 0; | 66 GLint matching_pixel_format_count = 0; |
66 CGLError err = CGLChoosePixelFormat(attributes, | 67 CGLError err = CGLChoosePixelFormat(attributes, |
67 &pixel_format, | 68 &pixel_format, |
(...skipping 17 matching lines...) Expand all Loading... | |
85 CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; | 86 CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; |
86 glReadBuffer(GL_FRONT); | 87 glReadBuffer(GL_FRONT); |
87 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); | 88 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); |
88 | 89 |
89 glPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment. | 90 glPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment. |
90 glPixelStorei(GL_PACK_ROW_LENGTH, 0); | 91 glPixelStorei(GL_PACK_ROW_LENGTH, 0); |
91 glPixelStorei(GL_PACK_SKIP_ROWS, 0); | 92 glPixelStorei(GL_PACK_SKIP_ROWS, 0); |
92 glPixelStorei(GL_PACK_SKIP_PIXELS, 0); | 93 glPixelStorei(GL_PACK_SKIP_PIXELS, 0); |
93 | 94 |
94 // Read a block of pixels from the frame buffer. | 95 // Read a block of pixels from the frame buffer. |
95 glReadPixels(0, 0, width(), height(), GL_BGRA, GL_UNSIGNED_BYTE, | 96 int h = height(); |
96 buffers_[current_buffer_].get()); | 97 int w = width(); |
98 uint8* flip_buffer = flip_buffer_.get(); | |
99 uint8* current_buffer = buffers_[current_buffer_].get(); | |
100 | |
101 glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, flip_buffer); | |
97 glPopClientAttrib(); | 102 glPopClientAttrib(); |
98 | 103 |
104 // OpenGL reads with a vertical flip, and sadly there is no optimized | |
105 // way to get it flipped automatically. | |
106 DCHECK_EQ(bytes_per_row_ % sizeof(uint32_t), 0U); | |
107 for (int y = 0; y < h; ++y) { | |
108 uint32_t* flip_row = reinterpret_cast<uint32_t*>( | |
109 &(flip_buffer[y * bytes_per_row_])); | |
110 uint32_t* current_row = reinterpret_cast<uint32_t*>( | |
111 &(current_buffer[(h - (y + 1)) * bytes_per_row_])); | |
112 for (int x = 0; x < w; ++x) { | |
Alpha Left Google
2011/03/03 01:43:33
Do a memcpy instead of doing yourself, memcpy is p
| |
113 current_row[x] = flip_row[x]; | |
114 } | |
115 } | |
116 | |
99 DataPlanes planes; | 117 DataPlanes planes; |
100 planes.data[0] = buffers_[current_buffer_].get(); | 118 planes.data[0] = buffers_[current_buffer_].get(); |
101 planes.strides[0] = bytes_per_row_; | 119 planes.strides[0] = bytes_per_row_; |
102 | 120 |
103 scoped_refptr<CaptureData> data(new CaptureData(planes, | 121 scoped_refptr<CaptureData> data( |
104 width(), | 122 new CaptureData(planes, w, h, pixel_format())); |
105 height(), | |
106 pixel_format())); | |
107 data->mutable_dirty_rects() = rects; | 123 data->mutable_dirty_rects() = rects; |
108 FinishCapture(data, callback); | 124 FinishCapture(data, callback); |
109 } | 125 } |
110 | 126 |
111 void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) { | 127 void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) { |
112 InvalidRects rects; | 128 InvalidRects rects; |
113 for (CGRectCount i = 0; i < count; ++i) { | 129 for (CGRectCount i = 0; i < count; ++i) { |
114 CGRect rect = rect_array[i]; | 130 CGRect rect = rect_array[i]; |
115 rect.origin.y = height() - rect.size.height; | 131 rect.origin.y = height() - rect.size.height; |
116 rects.insert(gfx::Rect(rect)); | 132 rects.insert(gfx::Rect(rect)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 capturer->ScreenConfigurationChanged(); | 173 capturer->ScreenConfigurationChanged(); |
158 } | 174 } |
159 } | 175 } |
160 | 176 |
161 // static | 177 // static |
162 Capturer* Capturer::Create(MessageLoop* message_loop) { | 178 Capturer* Capturer::Create(MessageLoop* message_loop) { |
163 return new CapturerMac(message_loop); | 179 return new CapturerMac(message_loop); |
164 } | 180 } |
165 | 181 |
166 } // namespace remoting | 182 } // namespace remoting |
OLD | NEW |