Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: remoting/host/video_frame_capturer_mac.mm

Issue 10917119: Dynamically link to deprecated APIs when running on OS 10.6 devices. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Also dynamic-link to CGLSetFullScreen API. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <OpenGL/CGLMacro.h> 11 #include <OpenGL/CGLMacro.h>
12 #include <OpenGL/OpenGL.h> 12 #include <OpenGL/OpenGL.h>
13 #include <stddef.h> 13 #include <stddef.h>
14 14
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/file_path.h"
16 #include "base/mac/mac_util.h" 17 #include "base/mac/mac_util.h"
17 #include "base/mac/scoped_cftyperef.h" 18 #include "base/mac/scoped_cftyperef.h"
18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
20 #include "base/scoped_native_library.h"
19 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
20 #include "base/time.h" 22 #include "base/time.h"
21 #include "remoting/base/capture_data.h" 23 #include "remoting/base/capture_data.h"
22 #include "remoting/base/util.h" 24 #include "remoting/base/util.h"
23 #include "remoting/host/mac/scoped_pixel_buffer_object.h" 25 #include "remoting/host/mac/scoped_pixel_buffer_object.h"
24 #include "remoting/host/video_frame_capturer_helper.h" 26 #include "remoting/host/video_frame_capturer_helper.h"
25 #include "remoting/proto/control.pb.h" 27 #include "remoting/proto/control.pb.h"
26 28
27 namespace remoting { 29 namespace remoting {
28 30
29 namespace { 31 namespace {
30 32
33 // Definitions used to dynamic-link to deprecated OS 10.6 functions.
34 const char* kApplicationServicesLibraryName =
35 "ApplicationServices.framework/ApplicationServices";
36 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID);
37 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID);
38 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID);
39 const char* kOpenGlLibraryName = "OpenGL.framework/OpenGL";
40 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj);
41
31 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). 42 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect().
32 SkIRect CGRectToSkIRect(const CGRect& rect) { 43 SkIRect CGRectToSkIRect(const CGRect& rect) {
33 SkIRect sk_rect = { 44 SkIRect sk_rect = {
34 SkScalarRound(rect.origin.x), 45 SkScalarRound(rect.origin.x),
35 SkScalarRound(rect.origin.y), 46 SkScalarRound(rect.origin.y),
36 SkScalarRound(rect.origin.x + rect.size.width), 47 SkScalarRound(rect.origin.x + rect.size.width),
37 SkScalarRound(rect.origin.y + rect.size.height) 48 SkScalarRound(rect.origin.y + rect.size.height)
38 }; 49 };
39 return sk_rect; 50 return sk_rect;
40 } 51 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // Acts as a critical section around our display configuration data 186 // Acts as a critical section around our display configuration data
176 // structures. Specifically cgl_context_ and pixel_buffer_object_. 187 // structures. Specifically cgl_context_ and pixel_buffer_object_.
177 base::WaitableEvent display_configuration_capture_event_; 188 base::WaitableEvent display_configuration_capture_event_;
178 189
179 // Power management assertion to prevent the screen from sleeping. 190 // Power management assertion to prevent the screen from sleeping.
180 IOPMAssertionID power_assertion_id_display_; 191 IOPMAssertionID power_assertion_id_display_;
181 192
182 // Power management assertion to indicate that the user is active. 193 // Power management assertion to indicate that the user is active.
183 IOPMAssertionID power_assertion_id_user_; 194 IOPMAssertionID power_assertion_id_user_;
184 195
196 // Dynamically link to deprecated APIs for Mac OS X 10.6 support.
197 base::ScopedNativeLibrary app_services_library_;
198 CGDisplayBaseAddressFunc cg_display_base_address_;
199 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_;
200 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_;
201 base::ScopedNativeLibrary opengl_library_;
202 CGLSetFullScreenFunc cgl_set_full_screen_;
203
185 DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerMac); 204 DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerMac);
186 }; 205 };
187 206
188 VideoFrameCapturerMac::VideoFrameCapturerMac() 207 VideoFrameCapturerMac::VideoFrameCapturerMac()
189 : cgl_context_(NULL), 208 : cgl_context_(NULL),
190 current_buffer_(0), 209 current_buffer_(0),
191 last_buffer_(NULL), 210 last_buffer_(NULL),
192 pixel_format_(media::VideoFrame::RGB32), 211 pixel_format_(media::VideoFrame::RGB32),
193 display_configuration_capture_event_(false, true), 212 display_configuration_capture_event_(false, true),
194 power_assertion_id_display_(kIOPMNullAssertionID), 213 power_assertion_id_display_(kIOPMNullAssertionID),
195 power_assertion_id_user_(kIOPMNullAssertionID) { 214 power_assertion_id_user_(kIOPMNullAssertionID),
215 cg_display_base_address_(NULL),
216 cg_display_bytes_per_row_(NULL),
217 cg_display_bits_per_pixel_(NULL),
218 cgl_set_full_screen_(NULL)
219 {
196 } 220 }
197 221
198 VideoFrameCapturerMac::~VideoFrameCapturerMac() { 222 VideoFrameCapturerMac::~VideoFrameCapturerMac() {
199 ReleaseBuffers(); 223 ReleaseBuffers();
200 CGUnregisterScreenRefreshCallback( 224 CGUnregisterScreenRefreshCallback(
201 VideoFrameCapturerMac::ScreenRefreshCallback, this); 225 VideoFrameCapturerMac::ScreenRefreshCallback, this);
202 CGScreenUnregisterMoveCallback( 226 CGScreenUnregisterMoveCallback(
203 VideoFrameCapturerMac::ScreenUpdateMoveCallback, this); 227 VideoFrameCapturerMac::ScreenUpdateMoveCallback, this);
204 CGError err = CGDisplayRemoveReconfigurationCallback( 228 CGError err = CGDisplayRemoveReconfigurationCallback(
205 VideoFrameCapturerMac::DisplaysReconfiguredCallback, this); 229 VideoFrameCapturerMac::DisplaysReconfiguredCallback, this);
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 GL_BGRA, GL_UNSIGNED_BYTE, buffer.ptr()); 530 GL_BGRA, GL_UNSIGNED_BYTE, buffer.ptr());
507 glPopClientAttrib(); 531 glPopClientAttrib();
508 } 532 }
509 533
510 void VideoFrameCapturerMac::CgBlitPreLion(const VideoFrameBuffer& buffer, 534 void VideoFrameCapturerMac::CgBlitPreLion(const VideoFrameBuffer& buffer,
511 const SkRegion& region) { 535 const SkRegion& region) {
512 const int buffer_height = buffer.size().height(); 536 const int buffer_height = buffer.size().height();
513 537
514 // Copy the entire contents of the previous capture buffer, to capture over. 538 // Copy the entire contents of the previous capture buffer, to capture over.
515 // TODO(wez): Get rid of this as per crbug.com/145064, or implement 539 // TODO(wez): Get rid of this as per crbug.com/145064, or implement
516 // crbug.com/92354. 540 // crbug.com/92354.
Nico 2012/09/06 21:12:19 Can this comment be updated?
Wez 2012/09/06 21:59:07 The changes in this CL don't affect whether we nee
517 if (last_buffer_) 541 if (last_buffer_)
518 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); 542 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height);
519 last_buffer_ = buffer.ptr(); 543 last_buffer_ = buffer.ptr();
520 544
521 for (unsigned int d = 0; d < display_ids_.size(); ++d) { 545 for (unsigned int d = 0; d < display_ids_.size(); ++d) {
522 #pragma clang diagnostic push 546 // Use deprecated APIs to determine the display buffer layout.
Nico 2012/09/06 21:12:19 // because the replacement APIs exist on 10.6, but
Wez 2012/09/06 21:59:07 This is the original capture code; we don't have a
523 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 547 DCHECK(cg_display_base_address_ && cg_display_bytes_per_row_ &&
548 cg_display_bits_per_pixel_);
524 uint8* display_base_address = 549 uint8* display_base_address =
525 reinterpret_cast<uint8*>(CGDisplayBaseAddress(display_ids_[d])); 550 reinterpret_cast<uint8*>((*cg_display_base_address_)(display_ids_[d]));
526 CHECK(display_base_address); 551 CHECK(display_base_address);
527 int src_bytes_per_row = CGDisplayBytesPerRow(display_ids_[d]); 552 int src_bytes_per_row = (*cg_display_bytes_per_row_)(display_ids_[d]);
528 int src_bytes_per_pixel = CGDisplayBitsPerPixel(display_ids_[d]) / 8; 553 int src_bytes_per_pixel =
529 #pragma clang diagnostic pop 554 (*cg_display_bits_per_pixel_)(display_ids_[d]) / 8;
555
530 // Determine the position of the display in the buffer. 556 // Determine the position of the display in the buffer.
531 SkIRect display_bounds = CGRectToSkIRect(CGDisplayBounds(display_ids_[d])); 557 SkIRect display_bounds = CGRectToSkIRect(CGDisplayBounds(display_ids_[d]));
532 display_bounds.offset(-desktop_bounds_.left(), -desktop_bounds_.top()); 558 display_bounds.offset(-desktop_bounds_.left(), -desktop_bounds_.top());
533 559
534 // Determine which parts of the blit region, if any, lay within the monitor. 560 // Determine which parts of the blit region, if any, lay within the monitor.
535 SkRegion copy_region; 561 SkRegion copy_region;
536 if (!copy_region.op(region, display_bounds, SkRegion::kIntersect_Op)) 562 if (!copy_region.op(region, display_bounds, SkRegion::kIntersect_Op))
537 continue; 563 continue;
538 564
539 // Translate the region to be copied into display-relative coordinates. 565 // Translate the region to be copied into display-relative coordinates.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 // Re-mark the entire desktop as dirty. 672 // Re-mark the entire desktop as dirty.
647 helper_.InvalidateScreen(SkISize::Make(desktop_bounds_.width(), 673 helper_.InvalidateScreen(SkISize::Make(desktop_bounds_.width(),
648 desktop_bounds_.height())); 674 desktop_bounds_.height()));
649 675
650 if (base::mac::IsOSLionOrLater()) { 676 if (base::mac::IsOSLionOrLater()) {
651 LOG(INFO) << "Using CgBlitPostLion."; 677 LOG(INFO) << "Using CgBlitPostLion.";
652 // No need for any OpenGL support on Lion 678 // No need for any OpenGL support on Lion
653 return; 679 return;
654 } 680 }
655 681
682 // Dynamically link to the deprecated pre-Lion capture APIs.
683 FilePath app_services_path(kApplicationServicesLibraryName);
684 app_services_library_.Reset(base::LoadNativeLibrary(app_services_path, NULL));
Jamie 2012/09/06 21:41:50 Pass a string for error logging?
Wez 2012/09/07 00:17:51 Seems overkill in this case, but OK...
685 FilePath opengl_path(kOpenGlLibraryName);
Nico 2012/09/06 21:12:19 http://code.google.com/searchframe#OAMlx_jo-ck/src
Wez 2012/09/06 21:59:07 Won't that break things if the locations of those
686 opengl_library_.Reset(base::LoadNativeLibrary(opengl_path, NULL));
687 CHECK(app_services_library_.is_valid() && opengl_library_.is_valid());
688
689 cg_display_base_address_ = reinterpret_cast<CGDisplayBaseAddressFunc>(
690 app_services_library_.GetFunctionPointer("CGDisplayBaseAddress"));
691 cg_display_bytes_per_row_ = reinterpret_cast<CGDisplayBytesPerRowFunc>(
692 app_services_library_.GetFunctionPointer("CGDisplayBytesPerRow"));
693 cg_display_bits_per_pixel_ = reinterpret_cast<CGDisplayBitsPerPixelFunc>(
694 app_services_library_.GetFunctionPointer("CGDisplayBitsPerPixel"));
695 cgl_set_full_screen_ = reinterpret_cast<CGLSetFullScreenFunc>(
696 opengl_library_.GetFunctionPointer("CGLSetFullScreen"));
697 CHECK(cg_display_base_address_ && cg_display_bytes_per_row_ &&
698 cg_display_bits_per_pixel_ && cgl_set_full_screen_);
699
656 if (display_ids_.size() > 1) { 700 if (display_ids_.size() > 1) {
657 LOG(INFO) << "Using CgBlitPreLion (Multi-monitor)."; 701 LOG(INFO) << "Using CgBlitPreLion (Multi-monitor).";
658 return; 702 return;
659 } 703 }
660 704
661 CGDirectDisplayID mainDevice = CGMainDisplayID(); 705 CGDirectDisplayID mainDevice = CGMainDisplayID();
662 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { 706 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) {
663 LOG(INFO) << "Using CgBlitPreLion (OpenGL unavailable)."; 707 LOG(INFO) << "Using CgBlitPreLion (OpenGL unavailable).";
664 return; 708 return;
665 } 709 }
666 710
667 LOG(INFO) << "Using GlBlit"; 711 LOG(INFO) << "Using GlBlit";
668 712
669 CGLPixelFormatAttribute attributes[] = { 713 CGLPixelFormatAttribute attributes[] = {
670 kCGLPFAFullScreen, 714 kCGLPFAFullScreen,
671 kCGLPFADisplayMask, 715 kCGLPFADisplayMask,
672 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), 716 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice),
673 (CGLPixelFormatAttribute)0 717 (CGLPixelFormatAttribute)0
674 }; 718 };
675 CGLPixelFormatObj pixel_format = NULL; 719 CGLPixelFormatObj pixel_format = NULL;
676 GLint matching_pixel_format_count = 0; 720 GLint matching_pixel_format_count = 0;
677 CGLError err = CGLChoosePixelFormat(attributes, 721 CGLError err = CGLChoosePixelFormat(attributes,
678 &pixel_format, 722 &pixel_format,
679 &matching_pixel_format_count); 723 &matching_pixel_format_count);
680 DCHECK_EQ(err, kCGLNoError); 724 DCHECK_EQ(err, kCGLNoError);
681 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); 725 err = CGLCreateContext(pixel_format, NULL, &cgl_context_);
682 DCHECK_EQ(err, kCGLNoError); 726 DCHECK_EQ(err, kCGLNoError);
683 CGLDestroyPixelFormat(pixel_format); 727 CGLDestroyPixelFormat(pixel_format);
684 #pragma clang diagnostic push 728 (*cgl_set_full_screen_)(cgl_context_);
Jamie 2012/09/06 21:41:50 I think it's worth preserving the TODO in some for
Wez 2012/09/07 00:17:51 We'll never use the new API, though; it's crashy o
685 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
686 // TODO(jamiewalch): The non-deprecated equivalent code is shown below, but
687 // it causes 10.6 Macs' displays to go black. Find out why.
688 //
689 // CGLSetFullScreenOnDisplay(cgl_context_,
690 // CGDisplayIDToOpenGLDisplayMask(mainDevice));
691 CGLSetFullScreen(cgl_context_);
692 #pragma clang diagnostic pop
693 CGLSetCurrentContext(cgl_context_); 729 CGLSetCurrentContext(cgl_context_);
694 730
695 size_t buffer_size = desktop_bounds_.width() * desktop_bounds_.height() * 731 size_t buffer_size = desktop_bounds_.width() * desktop_bounds_.height() *
696 sizeof(uint32_t); 732 sizeof(uint32_t);
697 pixel_buffer_object_.Init(cgl_context_, buffer_size); 733 pixel_buffer_object_.Init(cgl_context_, buffer_size);
698 } 734 }
699 735
700 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, 736 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count,
701 const CGRect* rect_array) { 737 const CGRect* rect_array) {
702 SkIRect skirect_array[count]; 738 SkIRect skirect_array[count];
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 VideoFrameCapturer* VideoFrameCapturer::Create() { 812 VideoFrameCapturer* VideoFrameCapturer::Create() {
777 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); 813 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac();
778 if (!capturer->Init()) { 814 if (!capturer->Init()) {
779 delete capturer; 815 delete capturer;
780 capturer = NULL; 816 capturer = NULL;
781 } 817 }
782 return capturer; 818 return capturer;
783 } 819 }
784 820
785 } // namespace remoting 821 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698