| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 src_plane += src_plane_stride; | 89 src_plane += src_plane_stride; |
| 90 dest_plane += dest_plane_stride; | 90 dest_plane += dest_plane_stride; |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 | 93 |
| 94 // Returns an array of CGWindowID for all the on-screen windows except | 94 // Returns an array of CGWindowID for all the on-screen windows except |
| 95 // |window_to_exclude|, or NULL if the window is not found or it fails. The | 95 // |window_to_exclude|, or NULL if the window is not found or it fails. The |
| 96 // caller should release the returned CFArrayRef. | 96 // caller should release the returned CFArrayRef. |
| 97 CFArrayRef CreateWindowListWithExclusion(CGWindowID window_to_exclude) { | 97 CFArrayRef CreateWindowListWithExclusion(CGWindowID window_to_exclude) { |
| 98 if (!window_to_exclude) | 98 if (!window_to_exclude) |
| 99 return NULL; | 99 return nullptr; |
| 100 | 100 |
| 101 CFArrayRef all_windows = CGWindowListCopyWindowInfo( | 101 CFArrayRef all_windows = CGWindowListCopyWindowInfo( |
| 102 kCGWindowListOptionOnScreenOnly, kCGNullWindowID); | 102 kCGWindowListOptionOnScreenOnly, kCGNullWindowID); |
| 103 if (!all_windows) | 103 if (!all_windows) |
| 104 return NULL; | 104 return nullptr; |
| 105 | 105 |
| 106 CFMutableArrayRef returned_array = CFArrayCreateMutable( | 106 CFMutableArrayRef returned_array = |
| 107 NULL, CFArrayGetCount(all_windows), NULL); | 107 CFArrayCreateMutable(nullptr, CFArrayGetCount(all_windows), nullptr); |
| 108 | 108 |
| 109 bool found = false; | 109 bool found = false; |
| 110 for (CFIndex i = 0; i < CFArrayGetCount(all_windows); ++i) { | 110 for (CFIndex i = 0; i < CFArrayGetCount(all_windows); ++i) { |
| 111 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( | 111 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
| 112 CFArrayGetValueAtIndex(all_windows, i)); | 112 CFArrayGetValueAtIndex(all_windows, i)); |
| 113 | 113 |
| 114 CFNumberRef id_ref = reinterpret_cast<CFNumberRef>( | 114 CFNumberRef id_ref = reinterpret_cast<CFNumberRef>( |
| 115 CFDictionaryGetValue(window, kCGWindowNumber)); | 115 CFDictionaryGetValue(window, kCGWindowNumber)); |
| 116 | 116 |
| 117 CGWindowID id; | 117 CGWindowID id; |
| 118 CFNumberGetValue(id_ref, kCFNumberIntType, &id); | 118 CFNumberGetValue(id_ref, kCFNumberIntType, &id); |
| 119 if (id == window_to_exclude) { | 119 if (id == window_to_exclude) { |
| 120 found = true; | 120 found = true; |
| 121 continue; | 121 continue; |
| 122 } | 122 } |
| 123 CFArrayAppendValue(returned_array, reinterpret_cast<void *>(id)); | 123 CFArrayAppendValue(returned_array, reinterpret_cast<void *>(id)); |
| 124 } | 124 } |
| 125 CFRelease(all_windows); | 125 CFRelease(all_windows); |
| 126 | 126 |
| 127 if (!found) { | 127 if (!found) { |
| 128 CFRelease(returned_array); | 128 CFRelease(returned_array); |
| 129 returned_array = NULL; | 129 returned_array = nullptr; |
| 130 } | 130 } |
| 131 return returned_array; | 131 return returned_array; |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Returns the bounds of |window| in physical pixels, enlarged by a small amount | 134 // Returns the bounds of |window| in physical pixels, enlarged by a small amount |
| 135 // on four edges to take account of the border/shadow effects. | 135 // on four edges to take account of the border/shadow effects. |
| 136 DesktopRect GetExcludedWindowPixelBounds(CGWindowID window, | 136 DesktopRect GetExcludedWindowPixelBounds(CGWindowID window, |
| 137 float dip_to_pixel_scale) { | 137 float dip_to_pixel_scale) { |
| 138 // The amount of pixels to add to the actual window bounds to take into | 138 // The amount of pixels to add to the actual window bounds to take into |
| 139 // account of the border/shadow effects. | 139 // account of the border/shadow effects. |
| 140 static const int kBorderEffectSize = 20; | 140 static const int kBorderEffectSize = 20; |
| 141 CGRect rect; | 141 CGRect rect; |
| 142 CGWindowID ids[1]; | 142 CGWindowID ids[1]; |
| 143 ids[0] = window; | 143 ids[0] = window; |
| 144 | 144 |
| 145 CFArrayRef window_id_array = | 145 CFArrayRef window_id_array = |
| 146 CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL); | 146 CFArrayCreate(nullptr, reinterpret_cast<const void **>(&ids), 1, nullptr); |
| 147 CFArrayRef window_array = | 147 CFArrayRef window_array = |
| 148 CGWindowListCreateDescriptionFromArray(window_id_array); | 148 CGWindowListCreateDescriptionFromArray(window_id_array); |
| 149 | 149 |
| 150 if (CFArrayGetCount(window_array) > 0) { | 150 if (CFArrayGetCount(window_array) > 0) { |
| 151 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( | 151 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
| 152 CFArrayGetValueAtIndex(window_array, 0)); | 152 CFArrayGetValueAtIndex(window_array, 0)); |
| 153 CFDictionaryRef bounds_ref = reinterpret_cast<CFDictionaryRef>( | 153 CFDictionaryRef bounds_ref = reinterpret_cast<CFDictionaryRef>( |
| 154 CFDictionaryGetValue(window, kCGWindowBounds)); | 154 CFDictionaryGetValue(window, kCGWindowBounds)); |
| 155 CGRectMakeWithDictionaryRepresentation(bounds_ref, &rect); | 155 CGRectMakeWithDictionaryRepresentation(bounds_ref, &rect); |
| 156 } | 156 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 const CGRect *rect_array); | 222 const CGRect *rect_array); |
| 223 static void ScreenRefreshCallback(CGRectCount count, | 223 static void ScreenRefreshCallback(CGRectCount count, |
| 224 const CGRect *rect_array, | 224 const CGRect *rect_array, |
| 225 void *user_parameter); | 225 void *user_parameter); |
| 226 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, | 226 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, |
| 227 size_t count, | 227 size_t count, |
| 228 const CGRect *rect_array, | 228 const CGRect *rect_array, |
| 229 void *user_parameter); | 229 void *user_parameter); |
| 230 void ReleaseBuffers(); | 230 void ReleaseBuffers(); |
| 231 | 231 |
| 232 DesktopFrame* CreateFrame(); | 232 std::unique_ptr<DesktopFrame> CreateFrame(); |
| 233 | 233 |
| 234 Callback* callback_; | 234 Callback* callback_ = nullptr; |
| 235 | 235 |
| 236 CGLContextObj cgl_context_; | 236 CGLContextObj cgl_context_ = nullptr; |
| 237 ScopedPixelBufferObject pixel_buffer_object_; | 237 ScopedPixelBufferObject pixel_buffer_object_; |
| 238 | 238 |
| 239 // Queue of the frames buffers. | 239 // Queue of the frames buffers. |
| 240 ScreenCaptureFrameQueue<SharedDesktopFrame> queue_; | 240 ScreenCaptureFrameQueue<SharedDesktopFrame> queue_; |
| 241 | 241 |
| 242 // Current display configuration. | 242 // Current display configuration. |
| 243 MacDesktopConfiguration desktop_config_; | 243 MacDesktopConfiguration desktop_config_; |
| 244 | 244 |
| 245 // Currently selected display, or 0 if the full desktop is selected. On OS X | 245 // Currently selected display, or 0 if the full desktop is selected. On OS X |
| 246 // 10.6 and before, this is always 0. | 246 // 10.6 and before, this is always 0. |
| 247 CGDirectDisplayID current_display_; | 247 CGDirectDisplayID current_display_ = 0; |
| 248 | 248 |
| 249 // The physical pixel bounds of the current screen. | 249 // The physical pixel bounds of the current screen. |
| 250 DesktopRect screen_pixel_bounds_; | 250 DesktopRect screen_pixel_bounds_; |
| 251 | 251 |
| 252 // The dip to physical pixel scale of the current screen. | 252 // The dip to physical pixel scale of the current screen. |
| 253 float dip_to_pixel_scale_; | 253 float dip_to_pixel_scale_ = 1.0f; |
| 254 | 254 |
| 255 // A thread-safe list of invalid rectangles, and the size of the most | 255 // A thread-safe list of invalid rectangles, and the size of the most |
| 256 // recently captured screen. | 256 // recently captured screen. |
| 257 ScreenCapturerHelper helper_; | 257 ScreenCapturerHelper helper_; |
| 258 | 258 |
| 259 // Contains an invalid region from the previous capture. | 259 // Contains an invalid region from the previous capture. |
| 260 DesktopRegion last_invalid_region_; | 260 DesktopRegion last_invalid_region_; |
| 261 | 261 |
| 262 // Monitoring display reconfiguration. | 262 // Monitoring display reconfiguration. |
| 263 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_; | 263 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_; |
| 264 | 264 |
| 265 // Power management assertion to prevent the screen from sleeping. | 265 // Power management assertion to prevent the screen from sleeping. |
| 266 IOPMAssertionID power_assertion_id_display_; | 266 IOPMAssertionID power_assertion_id_display_ = kIOPMNullAssertionID; |
| 267 | 267 |
| 268 // Power management assertion to indicate that the user is active. | 268 // Power management assertion to indicate that the user is active. |
| 269 IOPMAssertionID power_assertion_id_user_; | 269 IOPMAssertionID power_assertion_id_user_ = kIOPMNullAssertionID; |
| 270 | 270 |
| 271 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. | 271 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. |
| 272 void* app_services_library_; | 272 void* app_services_library_ = nullptr; |
| 273 CGDisplayBaseAddressFunc cg_display_base_address_; | 273 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; |
| 274 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_; | 274 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; |
| 275 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_; | 275 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; |
| 276 void* opengl_library_; | 276 void* opengl_library_ = nullptr; |
| 277 CGLSetFullScreenFunc cgl_set_full_screen_; | 277 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; |
| 278 | 278 |
| 279 CGWindowID excluded_window_; | 279 CGWindowID excluded_window_ = 0; |
| 280 | 280 |
| 281 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); | 281 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); |
| 282 }; | 282 }; |
| 283 | 283 |
| 284 // DesktopFrame wrapper that flips wrapped frame upside down by inverting | 284 // DesktopFrame wrapper that flips wrapped frame upside down by inverting |
| 285 // stride. | 285 // stride. |
| 286 class InvertedDesktopFrame : public DesktopFrame { | 286 class InvertedDesktopFrame : public DesktopFrame { |
| 287 public: | 287 public: |
| 288 // Takes ownership of |frame|. | 288 // Takes ownership of |frame|. |
| 289 InvertedDesktopFrame(DesktopFrame* frame) | 289 InvertedDesktopFrame(DesktopFrame* frame) |
| 290 : DesktopFrame( | 290 : DesktopFrame( |
| 291 frame->size(), -frame->stride(), | 291 frame->size(), -frame->stride(), |
| 292 frame->data() + (frame->size().height() - 1) * frame->stride(), | 292 frame->data() + (frame->size().height() - 1) * frame->stride(), |
| 293 frame->shared_memory()), | 293 frame->shared_memory()), |
| 294 original_frame_(frame) { | 294 original_frame_(frame) { |
| 295 set_dpi(frame->dpi()); | 295 set_dpi(frame->dpi()); |
| 296 set_capture_time_ms(frame->capture_time_ms()); | 296 set_capture_time_ms(frame->capture_time_ms()); |
| 297 mutable_updated_region()->Swap(frame->mutable_updated_region()); | 297 mutable_updated_region()->Swap(frame->mutable_updated_region()); |
| 298 } | 298 } |
| 299 virtual ~InvertedDesktopFrame() {} | 299 virtual ~InvertedDesktopFrame() {} |
| 300 | 300 |
| 301 private: | 301 private: |
| 302 std::unique_ptr<DesktopFrame> original_frame_; | 302 std::unique_ptr<DesktopFrame> original_frame_; |
| 303 | 303 |
| 304 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); | 304 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); |
| 305 }; | 305 }; |
| 306 | 306 |
| 307 ScreenCapturerMac::ScreenCapturerMac( | 307 ScreenCapturerMac::ScreenCapturerMac( |
| 308 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) | 308 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) |
| 309 : callback_(NULL), | 309 : desktop_config_monitor_(desktop_config_monitor) {} |
| 310 cgl_context_(NULL), | |
| 311 current_display_(0), | |
| 312 dip_to_pixel_scale_(1.0f), | |
| 313 desktop_config_monitor_(desktop_config_monitor), | |
| 314 power_assertion_id_display_(kIOPMNullAssertionID), | |
| 315 power_assertion_id_user_(kIOPMNullAssertionID), | |
| 316 app_services_library_(NULL), | |
| 317 cg_display_base_address_(NULL), | |
| 318 cg_display_bytes_per_row_(NULL), | |
| 319 cg_display_bits_per_pixel_(NULL), | |
| 320 opengl_library_(NULL), | |
| 321 cgl_set_full_screen_(NULL), | |
| 322 excluded_window_(0) { | |
| 323 } | |
| 324 | 310 |
| 325 ScreenCapturerMac::~ScreenCapturerMac() { | 311 ScreenCapturerMac::~ScreenCapturerMac() { |
| 326 if (power_assertion_id_display_ != kIOPMNullAssertionID) { | 312 if (power_assertion_id_display_ != kIOPMNullAssertionID) { |
| 327 IOPMAssertionRelease(power_assertion_id_display_); | 313 IOPMAssertionRelease(power_assertion_id_display_); |
| 328 power_assertion_id_display_ = kIOPMNullAssertionID; | 314 power_assertion_id_display_ = kIOPMNullAssertionID; |
| 329 } | 315 } |
| 330 if (power_assertion_id_user_ != kIOPMNullAssertionID) { | 316 if (power_assertion_id_user_ != kIOPMNullAssertionID) { |
| 331 IOPMAssertionRelease(power_assertion_id_user_); | 317 IOPMAssertionRelease(power_assertion_id_user_); |
| 332 power_assertion_id_user_ = kIOPMNullAssertionID; | 318 power_assertion_id_user_ = kIOPMNullAssertionID; |
| 333 } | 319 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 346 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | 332 desktop_config_ = desktop_config_monitor_->desktop_configuration(); |
| 347 desktop_config_monitor_->Unlock(); | 333 desktop_config_monitor_->Unlock(); |
| 348 ScreenConfigurationChanged(); | 334 ScreenConfigurationChanged(); |
| 349 return true; | 335 return true; |
| 350 } | 336 } |
| 351 | 337 |
| 352 void ScreenCapturerMac::ReleaseBuffers() { | 338 void ScreenCapturerMac::ReleaseBuffers() { |
| 353 if (cgl_context_) { | 339 if (cgl_context_) { |
| 354 pixel_buffer_object_.Release(); | 340 pixel_buffer_object_.Release(); |
| 355 CGLDestroyContext(cgl_context_); | 341 CGLDestroyContext(cgl_context_); |
| 356 cgl_context_ = NULL; | 342 cgl_context_ = nullptr; |
| 357 } | 343 } |
| 358 // The buffers might be in use by the encoder, so don't delete them here. | 344 // The buffers might be in use by the encoder, so don't delete them here. |
| 359 // Instead, mark them as "needs update"; next time the buffers are used by | 345 // Instead, mark them as "needs update"; next time the buffers are used by |
| 360 // the capturer, they will be recreated if necessary. | 346 // the capturer, they will be recreated if necessary. |
| 361 queue_.Reset(); | 347 queue_.Reset(); |
| 362 } | 348 } |
| 363 | 349 |
| 364 void ScreenCapturerMac::Start(Callback* callback) { | 350 void ScreenCapturerMac::Start(Callback* callback) { |
| 365 assert(!callback_); | 351 assert(!callback_); |
| 366 assert(callback); | 352 assert(callback); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(CreateFrame())); | 398 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(CreateFrame())); |
| 413 | 399 |
| 414 DesktopFrame* current_frame = queue_.current_frame(); | 400 DesktopFrame* current_frame = queue_.current_frame(); |
| 415 | 401 |
| 416 bool flip = false; // GL capturers need flipping. | 402 bool flip = false; // GL capturers need flipping. |
| 417 if (rtc::GetOSVersionName() >= rtc::kMacOSLion) { | 403 if (rtc::GetOSVersionName() >= rtc::kMacOSLion) { |
| 418 // Lion requires us to use their new APIs for doing screen capture. These | 404 // Lion requires us to use their new APIs for doing screen capture. These |
| 419 // APIS currently crash on 10.6.8 if there is no monitor attached. | 405 // APIS currently crash on 10.6.8 if there is no monitor attached. |
| 420 if (!CgBlitPostLion(*current_frame, region)) { | 406 if (!CgBlitPostLion(*current_frame, region)) { |
| 421 desktop_config_monitor_->Unlock(); | 407 desktop_config_monitor_->Unlock(); |
| 422 callback_->OnCaptureCompleted(NULL); | 408 callback_->OnCaptureCompleted(std::unique_ptr<DesktopFrame>()); |
| 423 return; | 409 return; |
| 424 } | 410 } |
| 425 } else if (cgl_context_) { | 411 } else if (cgl_context_) { |
| 426 flip = true; | 412 flip = true; |
| 427 if (pixel_buffer_object_.get() != 0) { | 413 if (pixel_buffer_object_.get() != 0) { |
| 428 GlBlitFast(*current_frame, region); | 414 GlBlitFast(*current_frame, region); |
| 429 } else { | 415 } else { |
| 430 // See comment in ScopedPixelBufferObject::Init about why the slow | 416 // See comment in ScopedPixelBufferObject::Init about why the slow |
| 431 // path is always used on 10.5. | 417 // path is always used on 10.5. |
| 432 GlBlitSlow(*current_frame); | 418 GlBlitSlow(*current_frame); |
| 433 } | 419 } |
| 434 } else { | 420 } else { |
| 435 CgBlitPreLion(*current_frame, region); | 421 CgBlitPreLion(*current_frame, region); |
| 436 } | 422 } |
| 437 | 423 |
| 438 DesktopFrame* new_frame = queue_.current_frame()->Share(); | 424 std::unique_ptr<DesktopFrame> new_frame = queue_.current_frame()->Share(); |
| 439 *new_frame->mutable_updated_region() = region; | 425 *new_frame->mutable_updated_region() = region; |
| 440 | 426 |
| 441 if (flip) | 427 if (flip) |
| 442 new_frame = new InvertedDesktopFrame(new_frame); | 428 new_frame = new InvertedDesktopFrame(new_frame); |
| 443 | 429 |
| 444 helper_.set_size_most_recent(new_frame->size()); | 430 helper_.set_size_most_recent(new_frame->size()); |
| 445 | 431 |
| 446 // Signal that we are done capturing data from the display framebuffer, | 432 // Signal that we are done capturing data from the display framebuffer, |
| 447 // and accessing display structures. | 433 // and accessing display structures. |
| 448 desktop_config_monitor_->Unlock(); | 434 desktop_config_monitor_->Unlock(); |
| 449 | 435 |
| 450 new_frame->set_capture_time_ms( | 436 new_frame->set_capture_time_ms( |
| 451 (rtc::TimeNanos() - capture_start_time_nanos) / | 437 (rtc::TimeNanos() - capture_start_time_nanos) / |
| 452 rtc::kNumNanosecsPerMillisec); | 438 rtc::kNumNanosecsPerMillisec); |
| 453 callback_->OnCaptureCompleted(new_frame); | 439 callback_->OnCaptureCompleted(std::move(new_frame)); |
| 454 } | 440 } |
| 455 | 441 |
| 456 void ScreenCapturerMac::SetExcludedWindow(WindowId window) { | 442 void ScreenCapturerMac::SetExcludedWindow(WindowId window) { |
| 457 excluded_window_ = window; | 443 excluded_window_ = window; |
| 458 } | 444 } |
| 459 | 445 |
| 460 bool ScreenCapturerMac::GetScreenList(ScreenList* screens) { | 446 bool ScreenCapturerMac::GetScreenList(ScreenList* screens) { |
| 461 assert(screens->size() == 0); | 447 assert(screens->size() == 0); |
| 462 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { | 448 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { |
| 463 // Single monitor cast is not supported on pre OS X 10.7. | 449 // Single monitor cast is not supported on pre OS X 10.7. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 513 } |
| 528 } | 514 } |
| 529 last_invalid_region_ = region; | 515 last_invalid_region_ = region; |
| 530 | 516 |
| 531 CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; | 517 CGLContextObj CGL_MACRO_CONTEXT = cgl_context_; |
| 532 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get()); | 518 glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get()); |
| 533 glReadPixels(0, 0, frame.size().width(), frame.size().height(), GL_BGRA, | 519 glReadPixels(0, 0, frame.size().width(), frame.size().height(), GL_BGRA, |
| 534 GL_UNSIGNED_BYTE, 0); | 520 GL_UNSIGNED_BYTE, 0); |
| 535 GLubyte* ptr = static_cast<GLubyte*>( | 521 GLubyte* ptr = static_cast<GLubyte*>( |
| 536 glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB)); | 522 glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB)); |
| 537 if (ptr == NULL) { | 523 if (!ptr) { |
| 538 // If the buffer can't be mapped, assume that it's no longer valid and | 524 // If the buffer can't be mapped, assume that it's no longer valid and |
| 539 // release it. | 525 // release it. |
| 540 pixel_buffer_object_.Release(); | 526 pixel_buffer_object_.Release(); |
| 541 } else { | 527 } else { |
| 542 // Copy only from the dirty rects. Since the image obtained from OpenGL is | 528 // Copy only from the dirty rects. Since the image obtained from OpenGL is |
| 543 // upside-down we need to do some magic here to copy the correct rectangle. | 529 // upside-down we need to do some magic here to copy the correct rectangle. |
| 544 const int y_offset = (frame.size().height() - 1) * frame.stride(); | 530 const int y_offset = (frame.size().height() - 1) * frame.stride(); |
| 545 for (DesktopRegion::Iterator i(region); | 531 for (DesktopRegion::Iterator i(region); |
| 546 !i.IsAtEnd(); i.Advance()) { | 532 !i.IsAtEnd(); i.Advance()) { |
| 547 DesktopRect copy_rect = i.rect(); | 533 DesktopRect copy_rect = i.rect(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 } | 621 } |
| 636 } | 622 } |
| 637 } | 623 } |
| 638 | 624 |
| 639 bool ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame, | 625 bool ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame, |
| 640 const DesktopRegion& region) { | 626 const DesktopRegion& region) { |
| 641 // Copy the entire contents of the previous capture buffer, to capture over. | 627 // Copy the entire contents of the previous capture buffer, to capture over. |
| 642 // TODO(wez): Get rid of this as per crbug.com/145064, or implement | 628 // TODO(wez): Get rid of this as per crbug.com/145064, or implement |
| 643 // crbug.com/92354. | 629 // crbug.com/92354. |
| 644 if (queue_.previous_frame()) { | 630 if (queue_.previous_frame()) { |
| 645 memcpy(frame.data(), | 631 memcpy(frame.data(), queue_.previous_frame()->data(), |
| 646 queue_.previous_frame()->data(), | |
| 647 frame.stride() * frame.size().height()); | 632 frame.stride() * frame.size().height()); |
| 648 } | 633 } |
| 649 | 634 |
| 650 MacDisplayConfigurations displays_to_capture; | 635 MacDisplayConfigurations displays_to_capture; |
| 651 if (current_display_) { | 636 if (current_display_) { |
| 652 // Capturing a single screen. Note that the screen id may change when | 637 // Capturing a single screen. Note that the screen id may change when |
| 653 // screens are added or removed. | 638 // screens are added or removed. |
| 654 const MacDisplayConfiguration* config = | 639 const MacDisplayConfiguration* config = |
| 655 desktop_config_.FindDisplayConfigurationById(current_display_); | 640 desktop_config_.FindDisplayConfigurationById(current_display_); |
| 656 if (config) { | 641 if (config) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 685 // Determine which parts of the blit region, if any, lay within the monitor. | 670 // Determine which parts of the blit region, if any, lay within the monitor. |
| 686 DesktopRegion copy_region = region; | 671 DesktopRegion copy_region = region; |
| 687 copy_region.IntersectWith(display_bounds); | 672 copy_region.IntersectWith(display_bounds); |
| 688 if (copy_region.is_empty()) | 673 if (copy_region.is_empty()) |
| 689 continue; | 674 continue; |
| 690 | 675 |
| 691 // Translate the region to be copied into display-relative coordinates. | 676 // Translate the region to be copied into display-relative coordinates. |
| 692 copy_region.Translate(-display_bounds.left(), -display_bounds.top()); | 677 copy_region.Translate(-display_bounds.left(), -display_bounds.top()); |
| 693 | 678 |
| 694 DesktopRect excluded_window_bounds; | 679 DesktopRect excluded_window_bounds; |
| 695 CGImageRef excluded_image = NULL; | 680 CGImageRef excluded_image = nullptr; |
| 696 if (excluded_window_ && window_list) { | 681 if (excluded_window_ && window_list) { |
| 697 // Get the region of the excluded window relative the primary display. | 682 // Get the region of the excluded window relative the primary display. |
| 698 excluded_window_bounds = GetExcludedWindowPixelBounds( | 683 excluded_window_bounds = GetExcludedWindowPixelBounds( |
| 699 excluded_window_, display_config.dip_to_pixel_scale); | 684 excluded_window_, display_config.dip_to_pixel_scale); |
| 700 excluded_window_bounds.IntersectWith(display_config.pixel_bounds); | 685 excluded_window_bounds.IntersectWith(display_config.pixel_bounds); |
| 701 | 686 |
| 702 // Create the image under the excluded window first, because it's faster | 687 // Create the image under the excluded window first, because it's faster |
| 703 // than captuing the whole display. | 688 // than captuing the whole display. |
| 704 if (!excluded_window_bounds.is_empty()) { | 689 if (!excluded_window_bounds.is_empty()) { |
| 705 excluded_image = CreateExcludedWindowRegionImage( | 690 excluded_image = CreateExcludedWindowRegionImage( |
| 706 excluded_window_bounds, display_config.dip_to_pixel_scale, | 691 excluded_window_bounds, display_config.dip_to_pixel_scale, |
| 707 window_list); | 692 window_list); |
| 708 } | 693 } |
| 709 } | 694 } |
| 710 | 695 |
| 711 // Create an image containing a snapshot of the display. | 696 // Create an image containing a snapshot of the display. |
| 712 CGImageRef image = CGDisplayCreateImage(display_config.id); | 697 CGImageRef image = CGDisplayCreateImage(display_config.id); |
| 713 if (image == NULL) { | 698 if (!image) { |
| 714 if (excluded_image) | 699 if (excluded_image) |
| 715 CFRelease(excluded_image); | 700 CFRelease(excluded_image); |
| 716 continue; | 701 continue; |
| 717 } | 702 } |
| 718 | 703 |
| 719 // Verify that the image has 32-bit depth. | 704 // Verify that the image has 32-bit depth. |
| 720 int bits_per_pixel = CGImageGetBitsPerPixel(image); | 705 int bits_per_pixel = CGImageGetBitsPerPixel(image); |
| 721 if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) { | 706 if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) { |
| 722 LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " | 707 LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " |
| 723 << bits_per_pixel | 708 << bits_per_pixel |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 // deprecated in 10.6 -- it's still functional there, and it's not used on | 852 // deprecated in 10.6 -- it's still functional there, and it's not used on |
| 868 // newer OS X versions. | 853 // newer OS X versions. |
| 869 #pragma clang diagnostic push | 854 #pragma clang diagnostic push |
| 870 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 855 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| 871 kCGLPFAFullScreen, | 856 kCGLPFAFullScreen, |
| 872 #pragma clang diagnostic pop | 857 #pragma clang diagnostic pop |
| 873 kCGLPFADisplayMask, | 858 kCGLPFADisplayMask, |
| 874 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), | 859 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), |
| 875 (CGLPixelFormatAttribute)0 | 860 (CGLPixelFormatAttribute)0 |
| 876 }; | 861 }; |
| 877 CGLPixelFormatObj pixel_format = NULL; | 862 CGLPixelFormatObj pixel_format = nullptr; |
| 878 GLint matching_pixel_format_count = 0; | 863 GLint matching_pixel_format_count = 0; |
| 879 CGLError err = CGLChoosePixelFormat(attributes, | 864 CGLError err = CGLChoosePixelFormat(attributes, |
| 880 &pixel_format, | 865 &pixel_format, |
| 881 &matching_pixel_format_count); | 866 &matching_pixel_format_count); |
| 882 assert(err == kCGLNoError); | 867 assert(err == kCGLNoError); |
| 883 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); | 868 err = CGLCreateContext(pixel_format, nullptr, &cgl_context_); |
| 884 assert(err == kCGLNoError); | 869 assert(err == kCGLNoError); |
| 885 CGLDestroyPixelFormat(pixel_format); | 870 CGLDestroyPixelFormat(pixel_format); |
| 886 (*cgl_set_full_screen_)(cgl_context_); | 871 (*cgl_set_full_screen_)(cgl_context_); |
| 887 CGLSetCurrentContext(cgl_context_); | 872 CGLSetCurrentContext(cgl_context_); |
| 888 | 873 |
| 889 size_t buffer_size = screen_pixel_bounds_.width() * | 874 size_t buffer_size = screen_pixel_bounds_.width() * |
| 890 screen_pixel_bounds_.height() * | 875 screen_pixel_bounds_.height() * |
| 891 sizeof(uint32_t); | 876 sizeof(uint32_t); |
| 892 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 877 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
| 893 } | 878 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 void ScreenCapturerMac::ScreenUpdateMoveCallback( | 947 void ScreenCapturerMac::ScreenUpdateMoveCallback( |
| 963 CGScreenUpdateMoveDelta delta, | 948 CGScreenUpdateMoveDelta delta, |
| 964 size_t count, | 949 size_t count, |
| 965 const CGRect* rect_array, | 950 const CGRect* rect_array, |
| 966 void* user_parameter) { | 951 void* user_parameter) { |
| 967 ScreenCapturerMac* capturer = | 952 ScreenCapturerMac* capturer = |
| 968 reinterpret_cast<ScreenCapturerMac*>(user_parameter); | 953 reinterpret_cast<ScreenCapturerMac*>(user_parameter); |
| 969 capturer->ScreenUpdateMove(delta, count, rect_array); | 954 capturer->ScreenUpdateMove(delta, count, rect_array); |
| 970 } | 955 } |
| 971 | 956 |
| 972 DesktopFrame* ScreenCapturerMac::CreateFrame() { | 957 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { |
| 973 std::unique_ptr<DesktopFrame> frame( | 958 std::unique_ptr<DesktopFrame> frame( |
| 974 new BasicDesktopFrame(screen_pixel_bounds_.size())); | 959 new BasicDesktopFrame(screen_pixel_bounds_.size())); |
| 975 | |
| 976 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, | 960 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, |
| 977 kStandardDPI * dip_to_pixel_scale_)); | 961 kStandardDPI * dip_to_pixel_scale_)); |
| 978 return frame.release(); | 962 return frame; |
| 979 } | 963 } |
| 980 | 964 |
| 981 } // namespace | 965 } // namespace |
| 982 | 966 |
| 983 // static | 967 // static |
| 984 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { | 968 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { |
| 985 if (!options.configuration_monitor()) | 969 if (!options.configuration_monitor()) |
| 986 return NULL; | 970 return nullptr; |
| 987 | 971 |
| 988 std::unique_ptr<ScreenCapturerMac> capturer( | 972 std::unique_ptr<ScreenCapturerMac> capturer( |
| 989 new ScreenCapturerMac(options.configuration_monitor())); | 973 new ScreenCapturerMac(options.configuration_monitor())); |
| 990 if (!capturer->Init()) | 974 if (!capturer->Init()) |
| 991 capturer.reset(); | 975 capturer.reset(); |
| 992 return capturer.release(); | 976 return capturer.release(); |
| 993 } | 977 } |
| 994 | 978 |
| 995 } // namespace webrtc | 979 } // namespace webrtc |
| OLD | NEW |