| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/video_frame_capturer.h" | 5 #include "remoting/host/video_frame_capturer.h" |
| 6 | 6 |
| 7 #include <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
| 8 #include <Cocoa/Cocoa.h> | 8 #include <Cocoa/Cocoa.h> |
| 9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
| 10 #include <IOKit/pwr_mgt/IOPMLib.h> | 10 #include <IOKit/pwr_mgt/IOPMLib.h> |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 class VideoFrameCapturerMac : public VideoFrameCapturer { | 155 class VideoFrameCapturerMac : public VideoFrameCapturer { |
| 156 public: | 156 public: |
| 157 VideoFrameCapturerMac(); | 157 VideoFrameCapturerMac(); |
| 158 virtual ~VideoFrameCapturerMac(); | 158 virtual ~VideoFrameCapturerMac(); |
| 159 | 159 |
| 160 bool Init(); | 160 bool Init(); |
| 161 | 161 |
| 162 // Overridden from VideoFrameCapturer: | 162 // Overridden from VideoFrameCapturer: |
| 163 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; | 163 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; |
| 164 virtual void Stop() OVERRIDE; | 164 virtual void Stop() OVERRIDE; |
| 165 virtual void ScreenConfigurationChanged() OVERRIDE; | |
| 166 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; | 165 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; |
| 167 virtual void ClearInvalidRegion() OVERRIDE; | |
| 168 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; | 166 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; |
| 169 virtual void InvalidateScreen(const SkISize& size) OVERRIDE; | |
| 170 virtual void InvalidateFullScreen() OVERRIDE; | |
| 171 virtual void CaptureInvalidRegion( | 167 virtual void CaptureInvalidRegion( |
| 172 const CaptureCompletedCallback& callback) OVERRIDE; | 168 const CaptureCompletedCallback& callback) OVERRIDE; |
| 173 virtual const SkISize& size_most_recent() const OVERRIDE; | 169 virtual const SkISize& size_most_recent() const OVERRIDE; |
| 174 | 170 |
| 175 private: | 171 private: |
| 176 void CaptureCursor(); | 172 void CaptureCursor(); |
| 177 | 173 |
| 178 void GlBlitFast(const VideoFrameBuffer& buffer, const SkRegion& region); | 174 void GlBlitFast(const VideoFrameBuffer& buffer, const SkRegion& region); |
| 179 void GlBlitSlow(const VideoFrameBuffer& buffer); | 175 void GlBlitSlow(const VideoFrameBuffer& buffer); |
| 180 void CgBlitPreLion(const VideoFrameBuffer& buffer, const SkRegion& region); | 176 void CgBlitPreLion(const VideoFrameBuffer& buffer, const SkRegion& region); |
| 181 void CgBlitPostLion(const VideoFrameBuffer& buffer, const SkRegion& region); | 177 void CgBlitPostLion(const VideoFrameBuffer& buffer, const SkRegion& region); |
| 182 void CaptureRegion(const SkRegion& region, | 178 void CaptureRegion(const SkRegion& region, |
| 183 const CaptureCompletedCallback& callback); | 179 const CaptureCompletedCallback& callback); |
| 184 | 180 |
| 181 // Called when the screen configuration is changed. |
| 182 void ScreenConfigurationChanged(); |
| 183 |
| 185 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); | 184 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); |
| 186 void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 185 void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, |
| 187 size_t count, | 186 size_t count, |
| 188 const CGRect *rect_array); | 187 const CGRect *rect_array); |
| 189 void DisplaysReconfigured(CGDirectDisplayID display, | 188 void DisplaysReconfigured(CGDirectDisplayID display, |
| 190 CGDisplayChangeSummaryFlags flags); | 189 CGDisplayChangeSummaryFlags flags); |
| 191 static void ScreenRefreshCallback(CGRectCount count, | 190 static void ScreenRefreshCallback(CGRectCount count, |
| 192 const CGRect *rect_array, | 191 const CGRect *rect_array, |
| 193 void *user_parameter); | 192 void *user_parameter); |
| 194 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, | 193 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 if (power_assertion_id_display_ != kIOPMNullAssertionID) { | 333 if (power_assertion_id_display_ != kIOPMNullAssertionID) { |
| 335 IOPMAssertionRelease(power_assertion_id_display_); | 334 IOPMAssertionRelease(power_assertion_id_display_); |
| 336 power_assertion_id_display_ = kIOPMNullAssertionID; | 335 power_assertion_id_display_ = kIOPMNullAssertionID; |
| 337 } | 336 } |
| 338 if (power_assertion_id_user_ != kIOPMNullAssertionID) { | 337 if (power_assertion_id_user_ != kIOPMNullAssertionID) { |
| 339 IOPMAssertionRelease(power_assertion_id_user_); | 338 IOPMAssertionRelease(power_assertion_id_user_); |
| 340 power_assertion_id_user_ = kIOPMNullAssertionID; | 339 power_assertion_id_user_ = kIOPMNullAssertionID; |
| 341 } | 340 } |
| 342 } | 341 } |
| 343 | 342 |
| 344 void VideoFrameCapturerMac::ScreenConfigurationChanged() { | |
| 345 ReleaseBuffers(); | |
| 346 helper_.ClearInvalidRegion(); | |
| 347 last_buffer_ = NULL; | |
| 348 | |
| 349 CGDirectDisplayID mainDevice = CGMainDisplayID(); | |
| 350 int width = CGDisplayPixelsWide(mainDevice); | |
| 351 int height = CGDisplayPixelsHigh(mainDevice); | |
| 352 InvalidateScreen(SkISize::Make(width, height)); | |
| 353 | |
| 354 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { | |
| 355 VLOG(3) << "OpenGL support not available."; | |
| 356 return; | |
| 357 } | |
| 358 | |
| 359 if (display_create_image_func_ != NULL) { | |
| 360 // No need for any OpenGL support on Lion | |
| 361 return; | |
| 362 } | |
| 363 | |
| 364 CGLPixelFormatAttribute attributes[] = { | |
| 365 kCGLPFAFullScreen, | |
| 366 kCGLPFADisplayMask, | |
| 367 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), | |
| 368 (CGLPixelFormatAttribute)0 | |
| 369 }; | |
| 370 CGLPixelFormatObj pixel_format = NULL; | |
| 371 GLint matching_pixel_format_count = 0; | |
| 372 CGLError err = CGLChoosePixelFormat(attributes, | |
| 373 &pixel_format, | |
| 374 &matching_pixel_format_count); | |
| 375 DCHECK_EQ(err, kCGLNoError); | |
| 376 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); | |
| 377 DCHECK_EQ(err, kCGLNoError); | |
| 378 CGLDestroyPixelFormat(pixel_format); | |
| 379 CGLSetFullScreen(cgl_context_); | |
| 380 CGLSetCurrentContext(cgl_context_); | |
| 381 | |
| 382 size_t buffer_size = width * height * sizeof(uint32_t); | |
| 383 pixel_buffer_object_.Init(cgl_context_, buffer_size); | |
| 384 } | |
| 385 | |
| 386 media::VideoFrame::Format VideoFrameCapturerMac::pixel_format() const { | 343 media::VideoFrame::Format VideoFrameCapturerMac::pixel_format() const { |
| 387 return pixel_format_; | 344 return pixel_format_; |
| 388 } | 345 } |
| 389 | 346 |
| 390 void VideoFrameCapturerMac::ClearInvalidRegion() { | |
| 391 helper_.ClearInvalidRegion(); | |
| 392 } | |
| 393 | |
| 394 void VideoFrameCapturerMac::InvalidateRegion(const SkRegion& invalid_region) { | 347 void VideoFrameCapturerMac::InvalidateRegion(const SkRegion& invalid_region) { |
| 395 helper_.InvalidateRegion(invalid_region); | 348 helper_.InvalidateRegion(invalid_region); |
| 396 } | 349 } |
| 397 | 350 |
| 398 void VideoFrameCapturerMac::InvalidateScreen(const SkISize& size) { | |
| 399 helper_.InvalidateScreen(size); | |
| 400 } | |
| 401 | |
| 402 void VideoFrameCapturerMac::InvalidateFullScreen() { | |
| 403 helper_.InvalidateFullScreen(); | |
| 404 } | |
| 405 | |
| 406 void VideoFrameCapturerMac::CaptureInvalidRegion( | 351 void VideoFrameCapturerMac::CaptureInvalidRegion( |
| 407 const CaptureCompletedCallback& callback) { | 352 const CaptureCompletedCallback& callback) { |
| 408 // Only allow captures when the display configuration is not occurring. | 353 // Only allow captures when the display configuration is not occurring. |
| 409 scoped_refptr<CaptureData> data; | 354 scoped_refptr<CaptureData> data; |
| 410 | 355 |
| 411 // Critical section shared with DisplaysReconfigured(...). | 356 // Critical section shared with DisplaysReconfigured(...). |
| 412 CHECK(display_configuration_capture_event_.TimedWait( | 357 CHECK(display_configuration_capture_event_.TimedWait( |
| 413 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); | 358 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); |
| 414 SkRegion region; | 359 SkRegion region; |
| 415 helper_.SwapInvalidRegion(®ion); | 360 helper_.SwapInvalidRegion(®ion); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 src_bytes_per_pixel, | 635 src_bytes_per_pixel, |
| 691 copy_rect); | 636 copy_rect); |
| 692 } | 637 } |
| 693 } | 638 } |
| 694 } | 639 } |
| 695 | 640 |
| 696 const SkISize& VideoFrameCapturerMac::size_most_recent() const { | 641 const SkISize& VideoFrameCapturerMac::size_most_recent() const { |
| 697 return helper_.size_most_recent(); | 642 return helper_.size_most_recent(); |
| 698 } | 643 } |
| 699 | 644 |
| 645 void VideoFrameCapturerMac::ScreenConfigurationChanged() { |
| 646 ReleaseBuffers(); |
| 647 helper_.ClearInvalidRegion(); |
| 648 last_buffer_ = NULL; |
| 649 |
| 650 CGDirectDisplayID mainDevice = CGMainDisplayID(); |
| 651 int width = CGDisplayPixelsWide(mainDevice); |
| 652 int height = CGDisplayPixelsHigh(mainDevice); |
| 653 helper_.InvalidateScreen(SkISize::Make(width, height)); |
| 654 |
| 655 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { |
| 656 VLOG(3) << "OpenGL support not available."; |
| 657 return; |
| 658 } |
| 659 |
| 660 if (display_create_image_func_ != NULL) { |
| 661 // No need for any OpenGL support on Lion |
| 662 return; |
| 663 } |
| 664 |
| 665 CGLPixelFormatAttribute attributes[] = { |
| 666 kCGLPFAFullScreen, |
| 667 kCGLPFADisplayMask, |
| 668 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), |
| 669 (CGLPixelFormatAttribute)0 |
| 670 }; |
| 671 CGLPixelFormatObj pixel_format = NULL; |
| 672 GLint matching_pixel_format_count = 0; |
| 673 CGLError err = CGLChoosePixelFormat(attributes, |
| 674 &pixel_format, |
| 675 &matching_pixel_format_count); |
| 676 DCHECK_EQ(err, kCGLNoError); |
| 677 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); |
| 678 DCHECK_EQ(err, kCGLNoError); |
| 679 CGLDestroyPixelFormat(pixel_format); |
| 680 CGLSetFullScreen(cgl_context_); |
| 681 CGLSetCurrentContext(cgl_context_); |
| 682 |
| 683 size_t buffer_size = width * height * sizeof(uint32_t); |
| 684 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
| 685 } |
| 686 |
| 700 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, | 687 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, |
| 701 const CGRect* rect_array) { | 688 const CGRect* rect_array) { |
| 702 SkIRect skirect_array[count]; | 689 SkIRect skirect_array[count]; |
| 703 for (CGRectCount i = 0; i < count; ++i) { | 690 for (CGRectCount i = 0; i < count; ++i) { |
| 704 skirect_array[i] = CGRectToSkIRect(rect_array[i]); | 691 skirect_array[i] = CGRectToSkIRect(rect_array[i]); |
| 705 } | 692 } |
| 706 SkRegion region; | 693 SkRegion region; |
| 707 region.setRects(skirect_array, count); | 694 region.setRects(skirect_array, count); |
| 708 InvalidateRegion(region); | 695 InvalidateRegion(region); |
| 709 } | 696 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 VideoFrameCapturer* VideoFrameCapturer::Create() { | 761 VideoFrameCapturer* VideoFrameCapturer::Create() { |
| 775 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); | 762 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); |
| 776 if (!capturer->Init()) { | 763 if (!capturer->Init()) { |
| 777 delete capturer; | 764 delete capturer; |
| 778 capturer = NULL; | 765 capturer = NULL; |
| 779 } | 766 } |
| 780 return capturer; | 767 return capturer; |
| 781 } | 768 } |
| 782 | 769 |
| 783 } // namespace remoting | 770 } // namespace remoting |
| OLD | NEW |