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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 VideoFrameBuffer() : | 47 VideoFrameBuffer() : |
48 size_(SkISize::Make(0, 0)), | 48 size_(SkISize::Make(0, 0)), |
49 dpi_(SkIPoint::Make(0, 0)), | 49 dpi_(SkIPoint::Make(0, 0)), |
50 bytes_per_row_(0), | 50 bytes_per_row_(0), |
51 needs_update_(true) { | 51 needs_update_(true) { |
52 } | 52 } |
53 | 53 |
54 // If the buffer is marked as needing to be updated (for example after the | 54 // If the buffer is marked as needing to be updated (for example after the |
55 // screen mode changes) and is the wrong size, then release the old buffer | 55 // screen mode changes) and is the wrong size, then release the old buffer |
56 // and create a new one. | 56 // and create a new one. |
57 void Update() { | 57 void Update(const SkISize& size) { |
58 if (needs_update_) { | 58 if (needs_update_) { |
59 needs_update_ = false; | 59 needs_update_ = false; |
60 CGDirectDisplayID mainDevice = CGMainDisplayID(); | 60 if (size != size_) { |
61 int width = CGDisplayPixelsWide(mainDevice); | 61 size_ = size; |
62 int height = CGDisplayPixelsHigh(mainDevice); | 62 bytes_per_row_ = size.width() * sizeof(uint32_t); |
63 if (width != size_.width() || height != size_.height()) { | 63 size_t buffer_size = size.width() * size.height() * sizeof(uint32_t); |
64 size_.set(width, height); | |
65 bytes_per_row_ = width * sizeof(uint32_t); | |
66 size_t buffer_size = width * height * sizeof(uint32_t); | |
67 ptr_.reset(new uint8[buffer_size]); | 64 ptr_.reset(new uint8[buffer_size]); |
68 } | 65 } |
66 | |
67 // TODO(wez): Move the ugly DPI code into a helper. | |
Jamie
2012/08/30 20:53:53
Since you mention DPI, does Mac support mixed DPI
Wez
2012/08/31 00:47:42
Not sure, but I suspect they do. My plan is to su
| |
69 NSScreen* screen = [NSScreen mainScreen]; | 68 NSScreen* screen = [NSScreen mainScreen]; |
70 NSDictionary* attr = [screen deviceDescription]; | 69 NSDictionary* attr = [screen deviceDescription]; |
71 NSSize resolution = [[attr objectForKey: NSDeviceResolution] sizeValue]; | 70 NSSize resolution = [[attr objectForKey: NSDeviceResolution] sizeValue]; |
72 dpi_.set(resolution.width, resolution.height); | 71 dpi_.set(resolution.width, resolution.height); |
73 } | 72 } |
74 } | 73 } |
75 | 74 |
76 SkISize size() const { return size_; } | 75 SkISize size() const { return size_; } |
77 SkIPoint dpi() const { return dpi_; } | 76 SkIPoint dpi() const { return dpi_; } |
78 int bytes_per_row() const { return bytes_per_row_; } | 77 int bytes_per_row() const { return bytes_per_row_; } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 CGDisplayChangeSummaryFlags flags, | 136 CGDisplayChangeSummaryFlags flags, |
138 void *user_parameter); | 137 void *user_parameter); |
139 | 138 |
140 void ReleaseBuffers(); | 139 void ReleaseBuffers(); |
141 | 140 |
142 CGLContextObj cgl_context_; | 141 CGLContextObj cgl_context_; |
143 static const int kNumBuffers = 2; | 142 static const int kNumBuffers = 2; |
144 ScopedPixelBufferObject pixel_buffer_object_; | 143 ScopedPixelBufferObject pixel_buffer_object_; |
145 VideoFrameBuffer buffers_[kNumBuffers]; | 144 VideoFrameBuffer buffers_[kNumBuffers]; |
146 | 145 |
146 // Current display configuration. | |
147 std::vector<CGDirectDisplayID> display_ids_; | |
148 SkIRect desktop_bounds_; | |
149 | |
147 // A thread-safe list of invalid rectangles, and the size of the most | 150 // A thread-safe list of invalid rectangles, and the size of the most |
148 // recently captured screen. | 151 // recently captured screen. |
149 VideoFrameCapturerHelper helper_; | 152 VideoFrameCapturerHelper helper_; |
150 | 153 |
151 // Callback notified whenever the cursor shape is changed. | 154 // Callback notified whenever the cursor shape is changed. |
152 CursorShapeChangedCallback cursor_shape_changed_callback_; | 155 CursorShapeChangedCallback cursor_shape_changed_callback_; |
153 | 156 |
154 // Image of the last cursor that we sent to the client. | 157 // Image of the last cursor that we sent to the client. |
155 base::mac::ScopedCFTypeRef<CGImageRef> current_cursor_; | 158 base::mac::ScopedCFTypeRef<CGImageRef> current_cursor_; |
156 | 159 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 const CaptureCompletedCallback& callback) { | 287 const CaptureCompletedCallback& callback) { |
285 // Only allow captures when the display configuration is not occurring. | 288 // Only allow captures when the display configuration is not occurring. |
286 scoped_refptr<CaptureData> data; | 289 scoped_refptr<CaptureData> data; |
287 | 290 |
288 // Critical section shared with DisplaysReconfigured(...). | 291 // Critical section shared with DisplaysReconfigured(...). |
289 CHECK(display_configuration_capture_event_.TimedWait( | 292 CHECK(display_configuration_capture_event_.TimedWait( |
290 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); | 293 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); |
291 SkRegion region; | 294 SkRegion region; |
292 helper_.SwapInvalidRegion(®ion); | 295 helper_.SwapInvalidRegion(®ion); |
293 VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; | 296 VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; |
294 current_buffer.Update(); | 297 current_buffer.Update(SkISize::Make(desktop_bounds_.width(), |
298 desktop_bounds_.height())); | |
295 | 299 |
296 bool flip = false; // GL capturers need flipping. | 300 bool flip = false; // GL capturers need flipping. |
297 if (base::mac::IsOSLionOrLater()) { | 301 if (base::mac::IsOSLionOrLater()) { |
298 // Lion requires us to use their new APIs for doing screen capture. These | 302 // Lion requires us to use their new APIs for doing screen capture. These |
299 // APIS currently crash on 10.6.8 if there is no monitor attached. | 303 // APIS currently crash on 10.6.8 if there is no monitor attached. |
300 CgBlitPostLion(current_buffer, region); | 304 CgBlitPostLion(current_buffer, region); |
301 } else if (cgl_context_) { | 305 } else if (cgl_context_) { |
302 flip = true; | 306 flip = true; |
303 if (pixel_buffer_object_.get() != 0) { | 307 if (pixel_buffer_object_.get() != 0) { |
304 GlBlitFast(current_buffer, region); | 308 GlBlitFast(current_buffer, region); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 glPixelStorei(GL_PACK_SKIP_PIXELS, 0); | 501 glPixelStorei(GL_PACK_SKIP_PIXELS, 0); |
498 // Read a block of pixels from the frame buffer. | 502 // Read a block of pixels from the frame buffer. |
499 glReadPixels(0, 0, buffer.size().width(), buffer.size().height(), | 503 glReadPixels(0, 0, buffer.size().width(), buffer.size().height(), |
500 GL_BGRA, GL_UNSIGNED_BYTE, buffer.ptr()); | 504 GL_BGRA, GL_UNSIGNED_BYTE, buffer.ptr()); |
501 glPopClientAttrib(); | 505 glPopClientAttrib(); |
502 } | 506 } |
503 | 507 |
504 void VideoFrameCapturerMac::CgBlitPreLion(const VideoFrameBuffer& buffer, | 508 void VideoFrameCapturerMac::CgBlitPreLion(const VideoFrameBuffer& buffer, |
505 const SkRegion& region) { | 509 const SkRegion& region) { |
506 const int buffer_height = buffer.size().height(); | 510 const int buffer_height = buffer.size().height(); |
507 const int buffer_width = buffer.size().width(); | |
508 | 511 |
509 // Clip to the size of our current screen. | 512 // Copy the entire contents of the previous capture buffer, to capture over. |
510 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); | 513 // TODO(wez): Get rid of this as per crbug.com/145064, or implement |
511 | 514 // crbug.com/92354. |
512 if (last_buffer_) | 515 if (last_buffer_) |
513 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); | 516 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); |
514 last_buffer_ = buffer.ptr(); | 517 last_buffer_ = buffer.ptr(); |
515 CGDirectDisplayID main_display = CGMainDisplayID(); | 518 |
519 for (unsigned int d = 0; d < display_ids_.size(); ++d) { | |
516 #pragma clang diagnostic push | 520 #pragma clang diagnostic push |
517 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 521 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
518 uint8* display_base_address = | 522 uint8* display_base_address = |
519 reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display)); | 523 reinterpret_cast<uint8*>(CGDisplayBaseAddress(display_ids_[d])); |
520 CHECK(display_base_address); | 524 CHECK(display_base_address); |
521 int src_bytes_per_row = CGDisplayBytesPerRow(main_display); | 525 int src_bytes_per_row = CGDisplayBytesPerRow(display_ids_[d]); |
522 int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8; | 526 int src_bytes_per_pixel = CGDisplayBitsPerPixel(display_ids_[d]) / 8; |
523 #pragma clang diagnostic pop | 527 #pragma clang diagnostic pop |
524 // TODO(hclam): We can reduce the amount of copying here by subtracting | 528 // Determine the position of the display in the buffer. |
525 // |capturer_helper_|s region from |last_invalid_region_|. | 529 SkIRect display_bounds = CGRectToSkIRect(CGDisplayBounds(display_ids_[d])); |
526 // http://crbug.com/92354 | 530 display_bounds.offset(-desktop_bounds_.left(), -desktop_bounds_.top()); |
527 for(SkRegion::Iterator i(region); !i.done(); i.next()) { | 531 |
528 SkIRect copy_rect = i.rect(); | 532 // Determine which parts of the blit region, if any, lay within the monitor. |
529 if (copy_rect.intersect(clip_rect)) { | 533 SkRegion copy_region; |
534 if (!copy_region.op(region, display_bounds, SkRegion::kIntersect_Op)) | |
535 continue; | |
536 | |
537 // Translate the region to be copied into display-relative coordinates. | |
538 copy_region.translate(-display_bounds.left(), -display_bounds.top()); | |
539 | |
540 // Calculate where in the output buffer the display's origin is. | |
541 uint8* out_ptr = buffer.ptr() + | |
542 (display_bounds.left() * src_bytes_per_pixel) + | |
543 (display_bounds.top() * buffer.bytes_per_row()); | |
544 | |
545 // Copy the dirty region from the display buffer into our desktop buffer. | |
546 for(SkRegion::Iterator i(copy_region); !i.done(); i.next()) { | |
530 CopyRect(display_base_address, | 547 CopyRect(display_base_address, |
531 src_bytes_per_row, | 548 src_bytes_per_row, |
532 buffer.ptr(), | 549 out_ptr, |
533 buffer.bytes_per_row(), | 550 buffer.bytes_per_row(), |
534 src_bytes_per_pixel, | 551 src_bytes_per_pixel, |
535 copy_rect); | 552 i.rect()); |
536 } | 553 } |
537 } | 554 } |
538 } | 555 } |
539 | 556 |
540 void VideoFrameCapturerMac::CgBlitPostLion(const VideoFrameBuffer& buffer, | 557 void VideoFrameCapturerMac::CgBlitPostLion(const VideoFrameBuffer& buffer, |
541 const SkRegion& region) { | 558 const SkRegion& region) { |
542 const int buffer_height = buffer.size().height(); | 559 const int buffer_height = buffer.size().height(); |
543 const int buffer_width = buffer.size().width(); | |
544 | 560 |
545 // Clip to the size of our current screen. | 561 // Copy the entire contents of the previous capture buffer, to capture over. |
546 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); | 562 // TODO(wez): Get rid of this as per crbug.com/145064, or implement |
547 | 563 // crbug.com/92354. |
548 if (last_buffer_) | 564 if (last_buffer_) |
549 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); | 565 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); |
550 last_buffer_ = buffer.ptr(); | 566 last_buffer_ = buffer.ptr(); |
551 CGDirectDisplayID display = CGMainDisplayID(); | 567 |
552 base::mac::ScopedCFTypeRef<CGImageRef> image( | 568 for (unsigned int d = 0; d < display_ids_.size(); ++d) { |
553 CGDisplayCreateImage(display)); | 569 // Determine the position of the display in the buffer. |
554 if (image.get() == NULL) | 570 SkIRect display_bounds = CGRectToSkIRect(CGDisplayBounds(display_ids_[d])); |
555 return; | 571 display_bounds.offset(-desktop_bounds_.left(), -desktop_bounds_.top()); |
556 CGDataProviderRef provider = CGImageGetDataProvider(image); | 572 |
557 base::mac::ScopedCFTypeRef<CFDataRef> data(CGDataProviderCopyData(provider)); | 573 // Determine which parts of the blit region, if any, lay within the monitor. |
558 if (data.get() == NULL) | 574 SkRegion copy_region; |
559 return; | 575 if (!copy_region.op(region, display_bounds, SkRegion::kIntersect_Op)) |
560 const uint8* display_base_address = CFDataGetBytePtr(data); | 576 continue; |
561 int src_bytes_per_row = CGImageGetBytesPerRow(image); | 577 |
562 int src_bytes_per_pixel = CGImageGetBitsPerPixel(image) / 8; | 578 // Translate the region to be copied into display-relative coordinates. |
563 // TODO(hclam): We can reduce the amount of copying here by subtracting | 579 copy_region.translate(-display_bounds.left(), -display_bounds.top()); |
Jamie
2012/08/30 20:53:53
Is there any value in factoring out the common cod
Wez
2012/08/31 00:47:42
Yes, but I think it's worth holding off until we'v
| |
564 // |capturer_helper_|s region from |last_invalid_region_|. | 580 |
565 // http://crbug.com/92354 | 581 // Create an image containing a snapshot of the display. |
566 for(SkRegion::Iterator i(region); !i.done(); i.next()) { | 582 base::mac::ScopedCFTypeRef<CGImageRef> image( |
567 SkIRect copy_rect = i.rect(); | 583 CGDisplayCreateImage(display_ids_[d])); |
568 if (copy_rect.intersect(clip_rect)) { | 584 if (image.get() == NULL) |
585 continue; | |
586 | |
587 // Request access to the raw pixel data via the image's DataProvider. | |
588 CGDataProviderRef provider = CGImageGetDataProvider(image); | |
589 base::mac::ScopedCFTypeRef<CFDataRef> data( | |
590 CGDataProviderCopyData(provider)); | |
591 if (data.get() == NULL) | |
592 continue; | |
593 | |
594 const uint8* display_base_address = CFDataGetBytePtr(data); | |
595 int src_bytes_per_row = CGImageGetBytesPerRow(image); | |
596 int src_bytes_per_pixel = CGImageGetBitsPerPixel(image) / 8; | |
597 | |
598 // Calculate where in the output buffer the display's origin is. | |
599 uint8* out_ptr = buffer.ptr() + | |
600 (display_bounds.left() * src_bytes_per_pixel) + | |
601 (display_bounds.top() * buffer.bytes_per_row()); | |
602 | |
603 // Copy the dirty region from the display buffer into our desktop buffer. | |
604 for(SkRegion::Iterator i(copy_region); !i.done(); i.next()) { | |
569 CopyRect(display_base_address, | 605 CopyRect(display_base_address, |
570 src_bytes_per_row, | 606 src_bytes_per_row, |
571 buffer.ptr(), | 607 out_ptr, |
572 buffer.bytes_per_row(), | 608 buffer.bytes_per_row(), |
573 src_bytes_per_pixel, | 609 src_bytes_per_pixel, |
574 copy_rect); | 610 i.rect()); |
575 } | 611 } |
576 } | 612 } |
577 } | 613 } |
578 | 614 |
579 const SkISize& VideoFrameCapturerMac::size_most_recent() const { | 615 const SkISize& VideoFrameCapturerMac::size_most_recent() const { |
580 return helper_.size_most_recent(); | 616 return helper_.size_most_recent(); |
581 } | 617 } |
582 | 618 |
583 void VideoFrameCapturerMac::ScreenConfigurationChanged() { | 619 void VideoFrameCapturerMac::ScreenConfigurationChanged() { |
620 // Release existing buffers, which will be of the wrong size. | |
621 // TODO(wez): Don't release buffers unless we find we really need to. | |
Jamie
2012/08/30 20:53:53
Is this really a big enough win to warrant a TODO?
Wez
2012/08/31 00:47:42
Done.
| |
584 ReleaseBuffers(); | 622 ReleaseBuffers(); |
585 helper_.ClearInvalidRegion(); | |
586 last_buffer_ = NULL; | 623 last_buffer_ = NULL; |
587 | 624 |
588 CGDirectDisplayID mainDevice = CGMainDisplayID(); | 625 // Clear the dirty region, in case the display is down-sizing. |
589 int width = CGDisplayPixelsWide(mainDevice); | 626 // TODO(wez): Clamp the dirty region to the new display size rather |
590 int height = CGDisplayPixelsHigh(mainDevice); | 627 // than clearing it. |
Jamie
2012/08/30 20:53:53
Since we invalidate the entire screen below, this
Wez
2012/08/31 00:47:42
In future we may not need to invalidate the whole
| |
591 helper_.InvalidateScreen(SkISize::Make(width, height)); | 628 helper_.ClearInvalidRegion(); |
629 | |
630 // Fetch the list if active displays and calculate their bounds. | |
631 CGDisplayCount display_count; | |
632 CGError error = CGGetActiveDisplayList(0, NULL, &display_count); | |
633 CHECK_EQ(error, CGDisplayNoErr); | |
634 | |
635 display_ids_.resize(display_count); | |
636 error = CGGetActiveDisplayList(display_count, &display_ids_[0], | |
637 &display_count); | |
638 CHECK_EQ(error, CGDisplayNoErr); | |
639 CHECK_EQ(display_count, display_ids_.size()); | |
640 | |
641 desktop_bounds_ = SkIRect::MakeEmpty(); | |
642 for (unsigned int d = 0; d < display_count; ++d) { | |
643 CGRect display_bounds = CGDisplayBounds(display_ids_[d]); | |
644 desktop_bounds_.join(CGRectToSkIRect(display_bounds)); | |
645 } | |
646 | |
647 // Re-mark the entire desktop as dirty. | |
648 helper_.InvalidateScreen(SkISize::Make(desktop_bounds_.width(), | |
649 desktop_bounds_.height())); | |
650 | |
651 LOG(ERROR) << "Desktop bounds are (" << | |
652 desktop_bounds_.left() << "," << desktop_bounds_.top() << ")-(" << | |
653 desktop_bounds_.right() << "," << desktop_bounds_.bottom() << ")"; | |
Jamie
2012/08/30 20:53:53
Left-over debugging?
Wez
2012/08/31 00:47:42
Sure is; removed it on a branch of this CL, left i
| |
592 | 654 |
593 if (base::mac::IsOSLionOrLater()) { | 655 if (base::mac::IsOSLionOrLater()) { |
594 LOG(INFO) << "Using CgBlitPostLion."; | 656 LOG(INFO) << "Using CgBlitPostLion."; |
595 // No need for any OpenGL support on Lion | 657 // No need for any OpenGL support on Lion |
596 return; | 658 return; |
597 } | 659 } |
598 | 660 |
599 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { | 661 if (display_ids_.size() > 1) { |
600 LOG(INFO) << "Using CgBlitPreLion."; | 662 LOG(INFO) << "Using CgBlitPreLion (Multi-monitor)."; |
601 return; | 663 return; |
602 } | 664 } |
603 | 665 |
666 if (!CGDisplayUsesOpenGLAcceleration(CGMainDisplayID())) { | |
667 LOG(INFO) << "Using CgBlitPreLion (OpenGL unavailable)."; | |
668 return; | |
669 } | |
670 | |
604 LOG(INFO) << "Using GlBlit"; | 671 LOG(INFO) << "Using GlBlit"; |
605 | 672 |
606 CGLPixelFormatAttribute attributes[] = { | 673 CGLPixelFormatAttribute attributes[] = { |
607 kCGLPFAFullScreen, | 674 kCGLPFAFullScreen, |
608 kCGLPFADisplayMask, | 675 kCGLPFADisplayMask, |
609 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), | 676 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(0 /*mainDevice*/), |
Jamie
2012/08/30 20:53:53
Why this change?
Wez
2012/08/31 00:47:42
Done.
| |
610 (CGLPixelFormatAttribute)0 | 677 (CGLPixelFormatAttribute)0 |
611 }; | 678 }; |
612 CGLPixelFormatObj pixel_format = NULL; | 679 CGLPixelFormatObj pixel_format = NULL; |
613 GLint matching_pixel_format_count = 0; | 680 GLint matching_pixel_format_count = 0; |
614 CGLError err = CGLChoosePixelFormat(attributes, | 681 CGLError err = CGLChoosePixelFormat(attributes, |
615 &pixel_format, | 682 &pixel_format, |
616 &matching_pixel_format_count); | 683 &matching_pixel_format_count); |
617 DCHECK_EQ(err, kCGLNoError); | 684 DCHECK_EQ(err, kCGLNoError); |
618 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); | 685 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); |
619 DCHECK_EQ(err, kCGLNoError); | 686 DCHECK_EQ(err, kCGLNoError); |
620 CGLDestroyPixelFormat(pixel_format); | 687 CGLDestroyPixelFormat(pixel_format); |
621 #pragma clang diagnostic push | 688 #pragma clang diagnostic push |
622 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 689 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
623 // TODO(jamiewalch): The non-deprecated equivalent code is shown below, but | 690 // TODO(jamiewalch): The non-deprecated equivalent code is shown below, but |
624 // it causes 10.6 Macs' displays to go black. Find out why. | 691 // it causes 10.6 Macs' displays to go black. Find out why. |
625 // | 692 // |
626 // CGLSetFullScreenOnDisplay(cgl_context_, | 693 // CGLSetFullScreenOnDisplay(cgl_context_, |
627 // CGDisplayIDToOpenGLDisplayMask(mainDevice)); | 694 // CGDisplayIDToOpenGLDisplayMask(mainDevice)); |
628 CGLSetFullScreen(cgl_context_); | 695 CGLSetFullScreen(cgl_context_); |
629 #pragma clang diagnostic pop | 696 #pragma clang diagnostic pop |
630 CGLSetCurrentContext(cgl_context_); | 697 CGLSetCurrentContext(cgl_context_); |
631 | 698 |
632 size_t buffer_size = width * height * sizeof(uint32_t); | 699 size_t buffer_size = desktop_bounds_.width() * desktop_bounds_.height() * |
700 sizeof(uint32_t); | |
633 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 701 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
634 } | 702 } |
635 | 703 |
636 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, | 704 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, |
637 const CGRect* rect_array) { | 705 const CGRect* rect_array) { |
638 SkIRect skirect_array[count]; | 706 SkIRect skirect_array[count]; |
639 for (CGRectCount i = 0; i < count; ++i) { | 707 for (CGRectCount i = 0; i < count; ++i) { |
640 skirect_array[i] = CGRectToSkIRect(rect_array[i]); | 708 skirect_array[i] = CGRectToSkIRect(rect_array[i]); |
709 skirect_array[i].offset(-desktop_bounds_.left(), -desktop_bounds_.top()); | |
641 } | 710 } |
642 SkRegion region; | 711 SkRegion region; |
643 region.setRects(skirect_array, count); | 712 region.setRects(skirect_array, count); |
644 InvalidateRegion(region); | 713 InvalidateRegion(region); |
645 } | 714 } |
646 | 715 |
647 void VideoFrameCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 716 void VideoFrameCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, |
648 size_t count, | 717 size_t count, |
649 const CGRect* rect_array) { | 718 const CGRect* rect_array) { |
650 SkIRect skirect_new_array[count]; | 719 SkIRect skirect_array[count]; |
651 for (CGRectCount i = 0; i < count; ++i) { | 720 for (CGRectCount i = 0; i < count; ++i) { |
652 CGRect rect = rect_array[i]; | 721 CGRect rect = rect_array[i]; |
653 rect = CGRectOffset(rect, delta.dX, delta.dY); | 722 rect = CGRectOffset(rect, delta.dX, delta.dY); |
654 skirect_new_array[i] = CGRectToSkIRect(rect); | 723 skirect_array[i] = CGRectToSkIRect(rect); |
724 skirect_array[i].offset(-desktop_bounds_.left(), -desktop_bounds_.top()); | |
655 } | 725 } |
656 SkRegion region; | 726 SkRegion region; |
657 region.setRects(skirect_new_array, count); | 727 region.setRects(skirect_array, count); |
658 InvalidateRegion(region); | 728 InvalidateRegion(region); |
659 } | 729 } |
660 | 730 |
661 void VideoFrameCapturerMac::DisplaysReconfigured( | 731 void VideoFrameCapturerMac::DisplaysReconfigured( |
662 CGDirectDisplayID display, | 732 CGDirectDisplayID display, |
663 CGDisplayChangeSummaryFlags flags) { | 733 CGDisplayChangeSummaryFlags flags) { |
664 if (display == CGMainDisplayID()) { | 734 if (display == CGMainDisplayID()) { |
665 if (flags & kCGDisplayBeginConfigurationFlag) { | 735 if (flags & kCGDisplayBeginConfigurationFlag) { |
666 // Wait on |display_configuration_capture_event_| to prevent more | 736 // Wait on |display_configuration_capture_event_| to prevent more |
667 // captures from occurring on a different thread while the displays | 737 // captures from occurring on a different thread while the displays |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 VideoFrameCapturer* VideoFrameCapturer::Create() { | 780 VideoFrameCapturer* VideoFrameCapturer::Create() { |
711 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); | 781 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); |
712 if (!capturer->Init()) { | 782 if (!capturer->Init()) { |
713 delete capturer; | 783 delete capturer; |
714 capturer = NULL; | 784 capturer = NULL; |
715 } | 785 } |
716 return capturer; | 786 return capturer; |
717 } | 787 } |
718 | 788 |
719 } // namespace remoting | 789 } // namespace remoting |
OLD | NEW |