| 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 |
| 11 #include "webrtc/modules/desktop_capture/screen_capturer.h" | 11 #include "webrtc/modules/desktop_capture/screen_capturer.h" |
| 12 | 12 |
| 13 #include <stddef.h> | 13 #include <stddef.h> |
| 14 | 14 |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <set> | 16 #include <set> |
| 17 #include <utility> | 17 #include <utility> |
| 18 | 18 |
| 19 #include <ApplicationServices/ApplicationServices.h> | 19 #include <ApplicationServices/ApplicationServices.h> |
| 20 #include <Cocoa/Cocoa.h> | 20 #include <Cocoa/Cocoa.h> |
| 21 #include <CoreGraphics/CoreGraphics.h> | |
| 22 #include <dlfcn.h> | 21 #include <dlfcn.h> |
| 23 #include <OpenGL/CGLMacro.h> | 22 #include <OpenGL/CGLMacro.h> |
| 24 #include <OpenGL/OpenGL.h> | 23 #include <OpenGL/OpenGL.h> |
| 25 | 24 |
| 26 #include "webrtc/base/checks.h" | 25 #include "webrtc/base/checks.h" |
| 27 #include "webrtc/base/constructormagic.h" | 26 #include "webrtc/base/constructormagic.h" |
| 28 #include "webrtc/base/macutils.h" | 27 #include "webrtc/base/macutils.h" |
| 29 #include "webrtc/base/timeutils.h" | 28 #include "webrtc/base/timeutils.h" |
| 30 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 29 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
| 31 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 30 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
| 32 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | 31 #include "webrtc/modules/desktop_capture/desktop_geometry.h" |
| 33 #include "webrtc/modules/desktop_capture/desktop_region.h" | 32 #include "webrtc/modules/desktop_capture/desktop_region.h" |
| 34 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" | 33 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" |
| 35 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" | 34 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" |
| 36 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" | 35 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" |
| 37 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" | 36 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" |
| 38 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" | 37 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" |
| 39 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" | 38 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" |
| 40 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" | 39 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" |
| 41 #include "webrtc/system_wrappers/include/logging.h" | 40 #include "webrtc/system_wrappers/include/logging.h" |
| 42 | 41 |
| 43 namespace webrtc { | 42 namespace webrtc { |
| 44 | 43 |
| 45 namespace { | 44 namespace { |
| 46 | 45 |
| 47 // CGDisplayStreamRefs need to be destroyed asynchronously after receiving a | |
| 48 // kCGDisplayStreamFrameStatusStopped callback from CoreGraphics. This may | |
| 49 // happen after the ScreenCapturerMac has been destroyed. DisplayStreamManager | |
| 50 // is responsible for destroying all extant CGDisplayStreamRefs, and will | |
| 51 // destroy itself once it's done. | |
| 52 class DisplayStreamManager { | |
| 53 public: | |
| 54 int GetUniqueId() { return ++unique_id_generator_; } | |
| 55 void DestroyStream(int unique_id) { | |
| 56 auto it = display_stream_wrappers_.find(unique_id); | |
| 57 RTC_CHECK(it != display_stream_wrappers_.end()); | |
| 58 RTC_CHECK(!it->second.active); | |
| 59 CFRelease(it->second.stream); | |
| 60 display_stream_wrappers_.erase(it); | |
| 61 | |
| 62 if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) | |
| 63 delete this; | |
| 64 } | |
| 65 | |
| 66 void SaveStream(int unique_id, CGDisplayStreamRef stream) { | |
| 67 RTC_CHECK(unique_id <= unique_id_generator_); | |
| 68 DisplayStreamWrapper wrapper; | |
| 69 wrapper.stream = stream; | |
| 70 display_stream_wrappers_[unique_id] = wrapper; | |
| 71 } | |
| 72 | |
| 73 void UnregisterActiveStreams() { | |
| 74 for (auto& pair : display_stream_wrappers_) { | |
| 75 DisplayStreamWrapper& wrapper = pair.second; | |
| 76 if (wrapper.active) { | |
| 77 wrapper.active = false; | |
| 78 // CGDisplayStream* functions are only available in 10.8+. Chrome only supports | |
| 79 // 10.9+, but we can't remove these warning suppressions until the deployment | |
| 80 // target is updated. https://crbug.com/579255 | |
| 81 #pragma clang diagnostic push | |
| 82 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 83 CGDisplayStreamStop(wrapper.stream); | |
| 84 #pragma clang diagnostic pop | |
| 85 } | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 void PrepareForSelfDestruction() { | |
| 90 ready_for_self_destruction_ = true; | |
| 91 | |
| 92 if (display_stream_wrappers_.empty()) | |
| 93 delete this; | |
| 94 } | |
| 95 | |
| 96 // Once the DisplayStreamManager is ready for destruction, the | |
| 97 // ScreenCapturerMac is no longer present. Any updates should be ignored. | |
| 98 bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; } | |
| 99 | |
| 100 private: | |
| 101 struct DisplayStreamWrapper { | |
| 102 // The registered CGDisplayStreamRef. | |
| 103 CGDisplayStreamRef stream = nullptr; | |
| 104 | |
| 105 // Set to false when the stream has been stopped. An asynchronous callback | |
| 106 // from CoreGraphics will let us destroy the CGDisplayStreamRef. | |
| 107 bool active = true; | |
| 108 }; | |
| 109 | |
| 110 std::map<int, DisplayStreamWrapper> display_stream_wrappers_; | |
| 111 int unique_id_generator_ = 0; | |
| 112 bool ready_for_self_destruction_ = false; | |
| 113 }; | |
| 114 | |
| 115 // Definitions used to dynamic-link to deprecated OS 10.6 functions. | 46 // Definitions used to dynamic-link to deprecated OS 10.6 functions. |
| 116 const char* kApplicationServicesLibraryName = | 47 const char* kApplicationServicesLibraryName = |
| 117 "/System/Library/Frameworks/ApplicationServices.framework/" | 48 "/System/Library/Frameworks/ApplicationServices.framework/" |
| 118 "ApplicationServices"; | 49 "ApplicationServices"; |
| 119 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); | 50 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); |
| 120 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); | 51 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); |
| 121 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); | 52 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); |
| 122 const char* kOpenGlLibraryName = | 53 const char* kOpenGlLibraryName = |
| 123 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; | 54 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; |
| 124 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); | 55 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 bool CgBlitPostLion(const DesktopFrame& frame, | 211 bool CgBlitPostLion(const DesktopFrame& frame, |
| 281 const DesktopRegion& region); | 212 const DesktopRegion& region); |
| 282 | 213 |
| 283 // Called when the screen configuration is changed. | 214 // Called when the screen configuration is changed. |
| 284 void ScreenConfigurationChanged(); | 215 void ScreenConfigurationChanged(); |
| 285 | 216 |
| 286 bool RegisterRefreshAndMoveHandlers(); | 217 bool RegisterRefreshAndMoveHandlers(); |
| 287 void UnregisterRefreshAndMoveHandlers(); | 218 void UnregisterRefreshAndMoveHandlers(); |
| 288 | 219 |
| 289 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); | 220 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); |
| 290 void ScreenUpdateMove(CGFloat delta_x, | 221 void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, |
| 291 CGFloat delta_y, | |
| 292 size_t count, | 222 size_t count, |
| 293 const CGRect* rect_array); | 223 const CGRect *rect_array); |
| 294 void ScreenRefreshCallback(CGRectCount count, const CGRect* rect_array); | 224 static void ScreenRefreshCallback(CGRectCount count, |
| 225 const CGRect *rect_array, |
| 226 void *user_parameter); |
| 227 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, |
| 228 size_t count, |
| 229 const CGRect *rect_array, |
| 230 void *user_parameter); |
| 295 void ReleaseBuffers(); | 231 void ReleaseBuffers(); |
| 296 | 232 |
| 297 std::unique_ptr<DesktopFrame> CreateFrame(); | 233 std::unique_ptr<DesktopFrame> CreateFrame(); |
| 298 | 234 |
| 299 Callback* callback_ = nullptr; | 235 Callback* callback_ = nullptr; |
| 300 | 236 |
| 301 CGLContextObj cgl_context_ = nullptr; | 237 CGLContextObj cgl_context_ = nullptr; |
| 302 ScopedPixelBufferObject pixel_buffer_object_; | 238 ScopedPixelBufferObject pixel_buffer_object_; |
| 303 | 239 |
| 304 // Queue of the frames buffers. | 240 // Queue of the frames buffers. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 330 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. | 266 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. |
| 331 void* app_services_library_ = nullptr; | 267 void* app_services_library_ = nullptr; |
| 332 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; | 268 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; |
| 333 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; | 269 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; |
| 334 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; | 270 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; |
| 335 void* opengl_library_ = nullptr; | 271 void* opengl_library_ = nullptr; |
| 336 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; | 272 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; |
| 337 | 273 |
| 338 CGWindowID excluded_window_ = 0; | 274 CGWindowID excluded_window_ = 0; |
| 339 | 275 |
| 340 // A self-owned object that will destroy itself after ScreenCapturerMac and | |
| 341 // all display streams have been destroyed.. | |
| 342 DisplayStreamManager* display_stream_manager_; | |
| 343 | |
| 344 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); | 276 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); |
| 345 }; | 277 }; |
| 346 | 278 |
| 347 // DesktopFrame wrapper that flips wrapped frame upside down by inverting | 279 // DesktopFrame wrapper that flips wrapped frame upside down by inverting |
| 348 // stride. | 280 // stride. |
| 349 class InvertedDesktopFrame : public DesktopFrame { | 281 class InvertedDesktopFrame : public DesktopFrame { |
| 350 public: | 282 public: |
| 351 InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame) | 283 InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame) |
| 352 : DesktopFrame( | 284 : DesktopFrame( |
| 353 frame->size(), | 285 frame->size(), |
| 354 -frame->stride(), | 286 -frame->stride(), |
| 355 frame->data() + (frame->size().height() - 1) * frame->stride(), | 287 frame->data() + (frame->size().height() - 1) * frame->stride(), |
| 356 frame->shared_memory()) { | 288 frame->shared_memory()) { |
| 357 original_frame_ = std::move(frame); | 289 original_frame_ = std::move(frame); |
| 358 set_dpi(original_frame_->dpi()); | 290 set_dpi(original_frame_->dpi()); |
| 359 set_capture_time_ms(original_frame_->capture_time_ms()); | 291 set_capture_time_ms(original_frame_->capture_time_ms()); |
| 360 mutable_updated_region()->Swap(original_frame_->mutable_updated_region()); | 292 mutable_updated_region()->Swap(original_frame_->mutable_updated_region()); |
| 361 } | 293 } |
| 362 virtual ~InvertedDesktopFrame() {} | 294 virtual ~InvertedDesktopFrame() {} |
| 363 | 295 |
| 364 private: | 296 private: |
| 365 std::unique_ptr<DesktopFrame> original_frame_; | 297 std::unique_ptr<DesktopFrame> original_frame_; |
| 366 | 298 |
| 367 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); | 299 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); |
| 368 }; | 300 }; |
| 369 | 301 |
| 370 ScreenCapturerMac::ScreenCapturerMac( | 302 ScreenCapturerMac::ScreenCapturerMac( |
| 371 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) | 303 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) |
| 372 : desktop_config_monitor_(desktop_config_monitor) { | 304 : desktop_config_monitor_(desktop_config_monitor) {} |
| 373 display_stream_manager_ = new DisplayStreamManager; | |
| 374 } | |
| 375 | 305 |
| 376 ScreenCapturerMac::~ScreenCapturerMac() { | 306 ScreenCapturerMac::~ScreenCapturerMac() { |
| 377 ReleaseBuffers(); | 307 ReleaseBuffers(); |
| 378 display_stream_manager_->PrepareForSelfDestruction(); | |
| 379 UnregisterRefreshAndMoveHandlers(); | 308 UnregisterRefreshAndMoveHandlers(); |
| 380 dlclose(app_services_library_); | 309 dlclose(app_services_library_); |
| 381 dlclose(opengl_library_); | 310 dlclose(opengl_library_); |
| 382 } | 311 } |
| 383 | 312 |
| 384 bool ScreenCapturerMac::Init() { | 313 bool ScreenCapturerMac::Init() { |
| 314 if (!RegisterRefreshAndMoveHandlers()) { |
| 315 return false; |
| 316 } |
| 385 desktop_config_monitor_->Lock(); | 317 desktop_config_monitor_->Lock(); |
| 386 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | 318 desktop_config_ = desktop_config_monitor_->desktop_configuration(); |
| 387 desktop_config_monitor_->Unlock(); | 319 desktop_config_monitor_->Unlock(); |
| 388 if (!RegisterRefreshAndMoveHandlers()) { | |
| 389 return false; | |
| 390 } | |
| 391 ScreenConfigurationChanged(); | 320 ScreenConfigurationChanged(); |
| 392 return true; | 321 return true; |
| 393 } | 322 } |
| 394 | 323 |
| 395 void ScreenCapturerMac::ReleaseBuffers() { | 324 void ScreenCapturerMac::ReleaseBuffers() { |
| 396 if (cgl_context_) { | 325 if (cgl_context_) { |
| 397 pixel_buffer_object_.Release(); | 326 pixel_buffer_object_.Release(); |
| 398 CGLDestroyContext(cgl_context_); | 327 CGLDestroyContext(cgl_context_); |
| 399 cgl_context_ = nullptr; | 328 cgl_context_ = nullptr; |
| 400 } | 329 } |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 (*cgl_set_full_screen_)(cgl_context_); | 841 (*cgl_set_full_screen_)(cgl_context_); |
| 913 CGLSetCurrentContext(cgl_context_); | 842 CGLSetCurrentContext(cgl_context_); |
| 914 | 843 |
| 915 size_t buffer_size = screen_pixel_bounds_.width() * | 844 size_t buffer_size = screen_pixel_bounds_.width() * |
| 916 screen_pixel_bounds_.height() * | 845 screen_pixel_bounds_.height() * |
| 917 sizeof(uint32_t); | 846 sizeof(uint32_t); |
| 918 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 847 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
| 919 } | 848 } |
| 920 | 849 |
| 921 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { | 850 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { |
| 922 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | 851 CGError err = CGRegisterScreenRefreshCallback( |
| 923 for (const auto& config : desktop_config_.displays) { | 852 ScreenCapturerMac::ScreenRefreshCallback, this); |
| 924 size_t pixel_width = config.pixel_bounds.width(); | 853 if (err != kCGErrorSuccess) { |
| 925 size_t pixel_height = config.pixel_bounds.height(); | 854 LOG(LS_ERROR) << "CGRegisterScreenRefreshCallback " << err; |
| 926 if (pixel_width == 0 || pixel_height == 0) | 855 return false; |
| 927 continue; | 856 } |
| 928 int unique_id = display_stream_manager_->GetUniqueId(); | |
| 929 CGDirectDisplayID display_id = config.id; | |
| 930 CGDisplayStreamFrameAvailableHandler handler = | |
| 931 ^(CGDisplayStreamFrameStatus status, uint64_t display_time, | |
| 932 IOSurfaceRef frame_surface, CGDisplayStreamUpdateRef updateRef) { | |
| 933 if (status == kCGDisplayStreamFrameStatusStopped) { | |
| 934 display_stream_manager_->DestroyStream(unique_id); | |
| 935 return; | |
| 936 } | |
| 937 | 857 |
| 938 if (display_stream_manager_->ShouldIgnoreUpdates()) | 858 err = CGScreenRegisterMoveCallback( |
| 939 return; | 859 ScreenCapturerMac::ScreenUpdateMoveCallback, this); |
| 940 | 860 if (err != kCGErrorSuccess) { |
| 941 // Only pay attention to frame updates. | 861 LOG(LS_ERROR) << "CGScreenRegisterMoveCallback " << err; |
| 942 if (status != kCGDisplayStreamFrameStatusFrameComplete) | 862 return false; |
| 943 return; | |
| 944 | |
| 945 size_t count = 0; | |
| 946 #pragma clang diagnostic push | |
| 947 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 948 // TODO(erikchen): Use kCGDisplayStreamUpdateDirtyRects. | |
| 949 const CGRect* rects = CGDisplayStreamUpdateGetRects( | |
| 950 updateRef, kCGDisplayStreamUpdateMovedRects, &count); | |
| 951 #pragma clang diagnostic pop | |
| 952 if (count != 0) { | |
| 953 CGFloat dx = 0; | |
| 954 CGFloat dy = 0; | |
| 955 #pragma clang diagnostic push | |
| 956 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 957 CGDisplayStreamUpdateGetMovedRectsDelta(updateRef, &dx, &dy); | |
| 958 #pragma clang diagnostic pop | |
| 959 ScreenUpdateMove(dx, dy, count, rects); | |
| 960 } | |
| 961 | |
| 962 count = 0; | |
| 963 #pragma clang diagnostic push | |
| 964 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 965 rects = CGDisplayStreamUpdateGetRects( | |
| 966 updateRef, kCGDisplayStreamUpdateRefreshedRects, &count); | |
| 967 #pragma clang diagnostic pop | |
| 968 if (count != 0) { | |
| 969 // According to CGDisplayStream.h, it's safe to call | |
| 970 // CGDisplayStreamStop() from within the callback. | |
| 971 ScreenRefreshCallback(count, rects); | |
| 972 } | |
| 973 }; | |
| 974 #pragma clang diagnostic push | |
| 975 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 976 CGDisplayStreamRef display_stream = CGDisplayStreamCreate( | |
| 977 display_id, pixel_width, pixel_height, 'BGRA', nullptr, handler); | |
| 978 #pragma clang diagnostic pop | |
| 979 if (display_stream) { | |
| 980 display_stream_manager_->SaveStream(unique_id, display_stream); | |
| 981 #pragma clang diagnostic push | |
| 982 #pragma clang diagnostic ignored "-Wunguarded-availability" | |
| 983 CGDisplayStreamStart(display_stream); | |
| 984 #pragma clang diagnostic pop | |
| 985 } | |
| 986 } | 863 } |
| 987 | 864 |
| 988 return true; | 865 return true; |
| 989 } | 866 } |
| 990 | 867 |
| 991 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { | 868 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { |
| 992 display_stream_manager_->UnregisterActiveStreams(); | 869 CGUnregisterScreenRefreshCallback( |
| 870 ScreenCapturerMac::ScreenRefreshCallback, this); |
| 871 CGScreenUnregisterMoveCallback( |
| 872 ScreenCapturerMac::ScreenUpdateMoveCallback, this); |
| 993 } | 873 } |
| 994 | 874 |
| 995 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, | 875 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, |
| 996 const CGRect* rect_array) { | 876 const CGRect* rect_array) { |
| 997 if (screen_pixel_bounds_.is_empty()) | 877 if (screen_pixel_bounds_.is_empty()) |
| 998 return; | 878 return; |
| 999 | 879 |
| 1000 DesktopRegion region; | 880 DesktopRegion region; |
| 1001 DesktopVector translate_vector = | 881 DesktopVector translate_vector = |
| 1002 DesktopVector().subtract(screen_pixel_bounds_.top_left()); | 882 DesktopVector().subtract(screen_pixel_bounds_.top_left()); |
| 1003 for (CGRectCount i = 0; i < count; ++i) { | 883 for (CGRectCount i = 0; i < count; ++i) { |
| 1004 // Convert from Density-Independent Pixel to physical pixel coordinates. | 884 // Convert from Density-Independent Pixel to physical pixel coordinates. |
| 1005 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); | 885 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); |
| 1006 // Translate from local desktop to capturer framebuffer coordinates. | 886 // Translate from local desktop to capturer framebuffer coordinates. |
| 1007 rect.Translate(translate_vector); | 887 rect.Translate(translate_vector); |
| 1008 region.AddRect(rect); | 888 region.AddRect(rect); |
| 1009 } | 889 } |
| 1010 | 890 |
| 1011 helper_.InvalidateRegion(region); | 891 helper_.InvalidateRegion(region); |
| 1012 } | 892 } |
| 1013 | 893 |
| 1014 void ScreenCapturerMac::ScreenUpdateMove(CGFloat delta_x, | 894 void ScreenCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, |
| 1015 CGFloat delta_y, | |
| 1016 size_t count, | 895 size_t count, |
| 1017 const CGRect* rect_array) { | 896 const CGRect* rect_array) { |
| 1018 // Translate |rect_array| to identify the move's destination. | 897 // Translate |rect_array| to identify the move's destination. |
| 1019 CGRect refresh_rects[count]; | 898 CGRect refresh_rects[count]; |
| 1020 for (CGRectCount i = 0; i < count; ++i) { | 899 for (CGRectCount i = 0; i < count; ++i) { |
| 1021 refresh_rects[i] = CGRectOffset(rect_array[i], delta_x, delta_y); | 900 refresh_rects[i] = CGRectOffset(rect_array[i], delta.dX, delta.dY); |
| 1022 } | 901 } |
| 1023 | 902 |
| 1024 // Currently we just treat move events the same as refreshes. | 903 // Currently we just treat move events the same as refreshes. |
| 1025 ScreenRefresh(count, refresh_rects); | 904 ScreenRefresh(count, refresh_rects); |
| 1026 } | 905 } |
| 1027 | 906 |
| 1028 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, | 907 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, |
| 1029 const CGRect* rect_array) { | 908 const CGRect* rect_array, |
| 1030 if (screen_pixel_bounds_.is_empty()) | 909 void* user_parameter) { |
| 1031 ScreenConfigurationChanged(); | 910 ScreenCapturerMac* capturer = |
| 1032 ScreenRefresh(count, rect_array); | 911 reinterpret_cast<ScreenCapturerMac*>(user_parameter); |
| 912 if (capturer->screen_pixel_bounds_.is_empty()) |
| 913 capturer->ScreenConfigurationChanged(); |
| 914 capturer->ScreenRefresh(count, rect_array); |
| 915 } |
| 916 |
| 917 void ScreenCapturerMac::ScreenUpdateMoveCallback( |
| 918 CGScreenUpdateMoveDelta delta, |
| 919 size_t count, |
| 920 const CGRect* rect_array, |
| 921 void* user_parameter) { |
| 922 ScreenCapturerMac* capturer = |
| 923 reinterpret_cast<ScreenCapturerMac*>(user_parameter); |
| 924 capturer->ScreenUpdateMove(delta, count, rect_array); |
| 1033 } | 925 } |
| 1034 | 926 |
| 1035 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { | 927 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { |
| 1036 std::unique_ptr<DesktopFrame> frame( | 928 std::unique_ptr<DesktopFrame> frame( |
| 1037 new BasicDesktopFrame(screen_pixel_bounds_.size())); | 929 new BasicDesktopFrame(screen_pixel_bounds_.size())); |
| 1038 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, | 930 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, |
| 1039 kStandardDPI * dip_to_pixel_scale_)); | 931 kStandardDPI * dip_to_pixel_scale_)); |
| 1040 return frame; | 932 return frame; |
| 1041 } | 933 } |
| 1042 | 934 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1054 } | 946 } |
| 1055 | 947 |
| 1056 if (options.detect_updated_region()) { | 948 if (options.detect_updated_region()) { |
| 1057 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); | 949 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); |
| 1058 } | 950 } |
| 1059 | 951 |
| 1060 return capturer.release(); | 952 return capturer.release(); |
| 1061 } | 953 } |
| 1062 | 954 |
| 1063 } // namespace webrtc | 955 } // namespace webrtc |
| OLD | NEW |