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> | |
21 #include <dlfcn.h> | 22 #include <dlfcn.h> |
22 #include <OpenGL/CGLMacro.h> | 23 #include <OpenGL/CGLMacro.h> |
23 #include <OpenGL/OpenGL.h> | 24 #include <OpenGL/OpenGL.h> |
24 | 25 |
25 #include "webrtc/base/checks.h" | 26 #include "webrtc/base/checks.h" |
26 #include "webrtc/base/constructormagic.h" | 27 #include "webrtc/base/constructormagic.h" |
27 #include "webrtc/base/macutils.h" | 28 #include "webrtc/base/macutils.h" |
28 #include "webrtc/base/timeutils.h" | 29 #include "webrtc/base/timeutils.h" |
29 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 30 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
30 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 31 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
31 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | 32 #include "webrtc/modules/desktop_capture/desktop_geometry.h" |
32 #include "webrtc/modules/desktop_capture/desktop_region.h" | 33 #include "webrtc/modules/desktop_capture/desktop_region.h" |
33 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" | 34 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" |
34 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" | 35 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" |
35 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" | 36 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" |
36 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" | 37 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" |
37 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" | 38 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" |
38 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" | 39 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" |
39 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" | 40 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" |
40 #include "webrtc/system_wrappers/include/logging.h" | 41 #include "webrtc/system_wrappers/include/logging.h" |
41 | 42 |
42 namespace webrtc { | 43 namespace webrtc { |
43 | 44 |
44 namespace { | 45 namespace { |
45 | 46 |
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" | |
Nico
2016/10/11 02:05:36
A nicer workaround for this warning is to just red
| |
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 | |
46 // Definitions used to dynamic-link to deprecated OS 10.6 functions. | 115 // Definitions used to dynamic-link to deprecated OS 10.6 functions. |
47 const char* kApplicationServicesLibraryName = | 116 const char* kApplicationServicesLibraryName = |
48 "/System/Library/Frameworks/ApplicationServices.framework/" | 117 "/System/Library/Frameworks/ApplicationServices.framework/" |
49 "ApplicationServices"; | 118 "ApplicationServices"; |
50 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); | 119 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); |
51 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); | 120 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); |
52 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); | 121 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); |
53 const char* kOpenGlLibraryName = | 122 const char* kOpenGlLibraryName = |
54 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; | 123 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; |
55 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); | 124 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 bool CgBlitPostLion(const DesktopFrame& frame, | 280 bool CgBlitPostLion(const DesktopFrame& frame, |
212 const DesktopRegion& region); | 281 const DesktopRegion& region); |
213 | 282 |
214 // Called when the screen configuration is changed. | 283 // Called when the screen configuration is changed. |
215 void ScreenConfigurationChanged(); | 284 void ScreenConfigurationChanged(); |
216 | 285 |
217 bool RegisterRefreshAndMoveHandlers(); | 286 bool RegisterRefreshAndMoveHandlers(); |
218 void UnregisterRefreshAndMoveHandlers(); | 287 void UnregisterRefreshAndMoveHandlers(); |
219 | 288 |
220 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); | 289 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); |
221 void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 290 void ScreenUpdateMove(CGFloat delta_x, |
291 CGFloat delta_y, | |
222 size_t count, | 292 size_t count, |
223 const CGRect *rect_array); | 293 const CGRect* rect_array); |
224 static void ScreenRefreshCallback(CGRectCount count, | 294 void ScreenRefreshCallback(CGRectCount count, const CGRect* rect_array); |
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); | |
231 void ReleaseBuffers(); | 295 void ReleaseBuffers(); |
232 | 296 |
233 std::unique_ptr<DesktopFrame> CreateFrame(); | 297 std::unique_ptr<DesktopFrame> CreateFrame(); |
234 | 298 |
235 Callback* callback_ = nullptr; | 299 Callback* callback_ = nullptr; |
236 | 300 |
237 CGLContextObj cgl_context_ = nullptr; | 301 CGLContextObj cgl_context_ = nullptr; |
238 ScopedPixelBufferObject pixel_buffer_object_; | 302 ScopedPixelBufferObject pixel_buffer_object_; |
239 | 303 |
240 // Queue of the frames buffers. | 304 // Queue of the frames buffers. |
(...skipping 25 matching lines...) Expand all Loading... | |
266 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. | 330 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. |
267 void* app_services_library_ = nullptr; | 331 void* app_services_library_ = nullptr; |
268 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; | 332 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; |
269 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; | 333 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; |
270 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; | 334 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; |
271 void* opengl_library_ = nullptr; | 335 void* opengl_library_ = nullptr; |
272 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; | 336 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; |
273 | 337 |
274 CGWindowID excluded_window_ = 0; | 338 CGWindowID excluded_window_ = 0; |
275 | 339 |
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 | |
276 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); | 344 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); |
277 }; | 345 }; |
278 | 346 |
279 // DesktopFrame wrapper that flips wrapped frame upside down by inverting | 347 // DesktopFrame wrapper that flips wrapped frame upside down by inverting |
280 // stride. | 348 // stride. |
281 class InvertedDesktopFrame : public DesktopFrame { | 349 class InvertedDesktopFrame : public DesktopFrame { |
282 public: | 350 public: |
283 InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame) | 351 InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame) |
284 : DesktopFrame( | 352 : DesktopFrame( |
285 frame->size(), | 353 frame->size(), |
286 -frame->stride(), | 354 -frame->stride(), |
287 frame->data() + (frame->size().height() - 1) * frame->stride(), | 355 frame->data() + (frame->size().height() - 1) * frame->stride(), |
288 frame->shared_memory()) { | 356 frame->shared_memory()) { |
289 original_frame_ = std::move(frame); | 357 original_frame_ = std::move(frame); |
290 set_dpi(original_frame_->dpi()); | 358 set_dpi(original_frame_->dpi()); |
291 set_capture_time_ms(original_frame_->capture_time_ms()); | 359 set_capture_time_ms(original_frame_->capture_time_ms()); |
292 mutable_updated_region()->Swap(original_frame_->mutable_updated_region()); | 360 mutable_updated_region()->Swap(original_frame_->mutable_updated_region()); |
293 } | 361 } |
294 virtual ~InvertedDesktopFrame() {} | 362 virtual ~InvertedDesktopFrame() {} |
295 | 363 |
296 private: | 364 private: |
297 std::unique_ptr<DesktopFrame> original_frame_; | 365 std::unique_ptr<DesktopFrame> original_frame_; |
298 | 366 |
299 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); | 367 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); |
300 }; | 368 }; |
301 | 369 |
302 ScreenCapturerMac::ScreenCapturerMac( | 370 ScreenCapturerMac::ScreenCapturerMac( |
303 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) | 371 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) |
304 : desktop_config_monitor_(desktop_config_monitor) {} | 372 : desktop_config_monitor_(desktop_config_monitor) { |
373 display_stream_manager_ = new DisplayStreamManager; | |
374 } | |
305 | 375 |
306 ScreenCapturerMac::~ScreenCapturerMac() { | 376 ScreenCapturerMac::~ScreenCapturerMac() { |
307 ReleaseBuffers(); | 377 ReleaseBuffers(); |
378 display_stream_manager_->PrepareForSelfDestruction(); | |
308 UnregisterRefreshAndMoveHandlers(); | 379 UnregisterRefreshAndMoveHandlers(); |
309 dlclose(app_services_library_); | 380 dlclose(app_services_library_); |
310 dlclose(opengl_library_); | 381 dlclose(opengl_library_); |
311 } | 382 } |
312 | 383 |
313 bool ScreenCapturerMac::Init() { | 384 bool ScreenCapturerMac::Init() { |
385 desktop_config_monitor_->Lock(); | |
386 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | |
387 desktop_config_monitor_->Unlock(); | |
314 if (!RegisterRefreshAndMoveHandlers()) { | 388 if (!RegisterRefreshAndMoveHandlers()) { |
315 return false; | 389 return false; |
316 } | 390 } |
317 desktop_config_monitor_->Lock(); | |
318 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | |
319 desktop_config_monitor_->Unlock(); | |
320 ScreenConfigurationChanged(); | 391 ScreenConfigurationChanged(); |
321 return true; | 392 return true; |
322 } | 393 } |
323 | 394 |
324 void ScreenCapturerMac::ReleaseBuffers() { | 395 void ScreenCapturerMac::ReleaseBuffers() { |
325 if (cgl_context_) { | 396 if (cgl_context_) { |
326 pixel_buffer_object_.Release(); | 397 pixel_buffer_object_.Release(); |
327 CGLDestroyContext(cgl_context_); | 398 CGLDestroyContext(cgl_context_); |
328 cgl_context_ = nullptr; | 399 cgl_context_ = nullptr; |
329 } | 400 } |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
841 (*cgl_set_full_screen_)(cgl_context_); | 912 (*cgl_set_full_screen_)(cgl_context_); |
842 CGLSetCurrentContext(cgl_context_); | 913 CGLSetCurrentContext(cgl_context_); |
843 | 914 |
844 size_t buffer_size = screen_pixel_bounds_.width() * | 915 size_t buffer_size = screen_pixel_bounds_.width() * |
845 screen_pixel_bounds_.height() * | 916 screen_pixel_bounds_.height() * |
846 sizeof(uint32_t); | 917 sizeof(uint32_t); |
847 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 918 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
848 } | 919 } |
849 | 920 |
850 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { | 921 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { |
851 CGError err = CGRegisterScreenRefreshCallback( | 922 desktop_config_ = desktop_config_monitor_->desktop_configuration(); |
852 ScreenCapturerMac::ScreenRefreshCallback, this); | 923 for (const auto& config : desktop_config_.displays) { |
853 if (err != kCGErrorSuccess) { | 924 size_t pixel_width = config.pixel_bounds.width(); |
854 LOG(LS_ERROR) << "CGRegisterScreenRefreshCallback " << err; | 925 size_t pixel_height = config.pixel_bounds.height(); |
855 return false; | 926 if (pixel_width == 0 || pixel_height == 0) |
856 } | 927 continue; |
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 } | |
857 | 937 |
858 err = CGScreenRegisterMoveCallback( | 938 if (display_stream_manager_->ShouldIgnoreUpdates()) |
859 ScreenCapturerMac::ScreenUpdateMoveCallback, this); | 939 return; |
860 if (err != kCGErrorSuccess) { | 940 |
861 LOG(LS_ERROR) << "CGScreenRegisterMoveCallback " << err; | 941 // Only pay attention to frame updates. |
862 return false; | 942 if (status != kCGDisplayStreamFrameStatusFrameComplete) |
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( | |
Nico
2016/10/11 02:05:36
same for all the stuff below
| |
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 } | |
863 } | 986 } |
864 | 987 |
865 return true; | 988 return true; |
866 } | 989 } |
867 | 990 |
868 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { | 991 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { |
869 CGUnregisterScreenRefreshCallback( | 992 display_stream_manager_->UnregisterActiveStreams(); |
870 ScreenCapturerMac::ScreenRefreshCallback, this); | |
871 CGScreenUnregisterMoveCallback( | |
872 ScreenCapturerMac::ScreenUpdateMoveCallback, this); | |
873 } | 993 } |
874 | 994 |
875 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, | 995 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, |
876 const CGRect* rect_array) { | 996 const CGRect* rect_array) { |
877 if (screen_pixel_bounds_.is_empty()) | 997 if (screen_pixel_bounds_.is_empty()) |
878 return; | 998 return; |
879 | 999 |
880 DesktopRegion region; | 1000 DesktopRegion region; |
881 DesktopVector translate_vector = | 1001 DesktopVector translate_vector = |
882 DesktopVector().subtract(screen_pixel_bounds_.top_left()); | 1002 DesktopVector().subtract(screen_pixel_bounds_.top_left()); |
883 for (CGRectCount i = 0; i < count; ++i) { | 1003 for (CGRectCount i = 0; i < count; ++i) { |
884 // Convert from Density-Independent Pixel to physical pixel coordinates. | 1004 // Convert from Density-Independent Pixel to physical pixel coordinates. |
885 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); | 1005 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); |
886 // Translate from local desktop to capturer framebuffer coordinates. | 1006 // Translate from local desktop to capturer framebuffer coordinates. |
887 rect.Translate(translate_vector); | 1007 rect.Translate(translate_vector); |
888 region.AddRect(rect); | 1008 region.AddRect(rect); |
889 } | 1009 } |
890 | 1010 |
891 helper_.InvalidateRegion(region); | 1011 helper_.InvalidateRegion(region); |
892 } | 1012 } |
893 | 1013 |
894 void ScreenCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 1014 void ScreenCapturerMac::ScreenUpdateMove(CGFloat delta_x, |
1015 CGFloat delta_y, | |
895 size_t count, | 1016 size_t count, |
896 const CGRect* rect_array) { | 1017 const CGRect* rect_array) { |
897 // Translate |rect_array| to identify the move's destination. | 1018 // Translate |rect_array| to identify the move's destination. |
898 CGRect refresh_rects[count]; | 1019 CGRect refresh_rects[count]; |
899 for (CGRectCount i = 0; i < count; ++i) { | 1020 for (CGRectCount i = 0; i < count; ++i) { |
900 refresh_rects[i] = CGRectOffset(rect_array[i], delta.dX, delta.dY); | 1021 refresh_rects[i] = CGRectOffset(rect_array[i], delta_x, delta_y); |
901 } | 1022 } |
902 | 1023 |
903 // Currently we just treat move events the same as refreshes. | 1024 // Currently we just treat move events the same as refreshes. |
904 ScreenRefresh(count, refresh_rects); | 1025 ScreenRefresh(count, refresh_rects); |
905 } | 1026 } |
906 | 1027 |
907 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, | 1028 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, |
908 const CGRect* rect_array, | 1029 const CGRect* rect_array) { |
909 void* user_parameter) { | 1030 if (screen_pixel_bounds_.is_empty()) |
910 ScreenCapturerMac* capturer = | 1031 ScreenConfigurationChanged(); |
911 reinterpret_cast<ScreenCapturerMac*>(user_parameter); | 1032 ScreenRefresh(count, rect_array); |
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); | |
925 } | 1033 } |
926 | 1034 |
927 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { | 1035 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { |
928 std::unique_ptr<DesktopFrame> frame( | 1036 std::unique_ptr<DesktopFrame> frame( |
929 new BasicDesktopFrame(screen_pixel_bounds_.size())); | 1037 new BasicDesktopFrame(screen_pixel_bounds_.size())); |
930 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, | 1038 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, |
931 kStandardDPI * dip_to_pixel_scale_)); | 1039 kStandardDPI * dip_to_pixel_scale_)); |
932 return frame; | 1040 return frame; |
933 } | 1041 } |
934 | 1042 |
(...skipping 11 matching lines...) Expand all Loading... | |
946 } | 1054 } |
947 | 1055 |
948 if (options.detect_updated_region()) { | 1056 if (options.detect_updated_region()) { |
949 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); | 1057 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); |
950 } | 1058 } |
951 | 1059 |
952 return capturer.release(); | 1060 return capturer.release(); |
953 } | 1061 } |
954 | 1062 |
955 } // namespace webrtc | 1063 } // namespace webrtc |
OLD | NEW |