Chromium Code Reviews| Index: webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm |
| diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm |
| index 73d5e028577225796cd38e35e580810cac02ba8b..3e81255546a79f70526952dfdedd3f8cb3660cd4 100644 |
| --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm |
| +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm |
| @@ -30,21 +30,27 @@ |
| namespace webrtc { |
| namespace { |
| -// Paint the image, so that we can get a bitmap representation compatible with |
| -// current context. For example, in the retina display, we are going to get an |
| -// image with same visual size but underlying pixel size conforms to the retina |
| -// setting. |
| -NSImage* PaintInCurrentContext(NSImage* source) { |
| - NSSize size = [source size]; |
| - NSImage* new_image = [[NSImage alloc] initWithSize:size]; |
| - [new_image lockFocus]; |
| - NSRect frame = NSMakeRect(0, 0, size.width, size.height); |
| - [source drawInRect:frame |
| - fromRect:frame |
| - operation:NSCompositeCopy |
| - fraction:1.0]; |
| - [new_image unlockFocus]; |
| - return new_image; |
| +CGImageRef CreateScaledCGImage(CGImageRef image, int width, int height) { |
| + // create context, keeping original image properties |
| + CGColorSpaceRef colorspace = CGImageGetColorSpace(image); |
| + CGContextRef context = |
| + CGBitmapContextCreate(NULL, |
|
Do not use (sergeyu)
2017/06/01 00:22:00
s/NULL/nullptr/
braveyao1
2017/06/01 17:50:14
Done.
|
| + width, |
|
Do not use (sergeyu)
2017/06/01 00:22:00
Please run 'git cl format'. It should format this
braveyao1
2017/06/01 17:50:14
Actually I tried to run "git cl format" before fil
Do not use (sergeyu)
2017/06/01 18:08:08
That's by design. Style guide for ObjC allows 100-
braveyao1
2017/06/01 18:17:56
Done.
I think 'git cl format' won't be wrong. :)
|
| + height, |
| + CGImageGetBitsPerComponent(image), |
| + width * 4, |
|
Do not use (sergeyu)
2017/06/01 00:22:00
width * DesktopFrame::kBytesPerPixel;
braveyao1
2017/06/01 17:50:14
Done.
|
| + colorspace, |
| + CGImageGetBitmapInfo(image)); |
| + |
| + if (context == NULL) return nil; |
|
Do not use (sergeyu)
2017/06/01 00:21:59
if (!context)
return nil;
braveyao1
2017/06/01 17:50:14
Done.
|
| + |
| + // draw image to context (resizing it) |
|
Do not use (sergeyu)
2017/06/01 00:21:59
Please reformat this as follows:
// Draw image t
braveyao1
2017/06/01 17:50:15
Done.
|
| + CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); |
| + // extract resulting image from context |
|
Do not use (sergeyu)
2017/06/01 00:21:59
// Extract resulting image from context.
braveyao1
2017/06/01 17:50:14
Done.
|
| + CGImageRef imgRef = CGBitmapContextCreateImage(context); |
| + CGContextRelease(context); |
| + |
| + return imgRef; |
| } |
| } // namespace |
| @@ -72,7 +78,7 @@ class MouseCursorMonitorMac : public MouseCursorMonitor { |
| ScreenId screen_id_; |
| Callback* callback_; |
| Mode mode_; |
| - std::unique_ptr<MouseCursor> last_cursor_; |
| + __strong NSImage* last_cursor_; |
| rtc::scoped_refptr<FullScreenChromeWindowDetector> |
| full_screen_chrome_window_detector_; |
| }; |
| @@ -253,10 +259,9 @@ void MouseCursorMonitorMac::CaptureImage(float scale) { |
| NSImage* nsimage = [nscursor image]; |
| NSSize nssize = [nsimage size]; // DIP size |
| - // For retina screen, we need to paint the cursor in current graphic context |
| - // to get retina representation. |
| - if (scale != 1.0) |
| - nsimage = PaintInCurrentContext(nsimage); |
| + if ([[nsimage TIFFRepresentation] isEqual: [last_cursor_ TIFFRepresentation]]) |
|
Do not use (sergeyu)
2017/06/01 00:21:59
Add a comment, to make it clear clear what happens
braveyao1
2017/06/01 17:50:14
Done.
|
| + return; |
| + last_cursor_ = nsimage; |
| DesktopSize size(round(nssize.width * scale), |
| round(nssize.height * scale)); // Pixel size |
| @@ -271,30 +276,34 @@ void MouseCursorMonitorMac::CaptureImage(float scale) { |
| if (!cg_image) |
| return; |
| + // Before 10.12, OSX may report 1X cursor on Retina screen. (See |
| + // crbug.com/632995.) After 10.12, OSX may report 2X cursor on non-Retina |
| + // screen. (See crbug.com/671436.) So scaling the cursor if needed. |
| + CGImageRef scaled_cg_image = nil; |
| + if (CGImageGetWidth(cg_image) != static_cast<size_t>(size.width())) { |
| + scaled_cg_image = |
| + CreateScaledCGImage(cg_image, size.width(), size.height()); |
| + if (scaled_cg_image != nil) { |
| + cg_image = scaled_cg_image; |
| + } |
| + } |
| if (CGImageGetBitsPerPixel(cg_image) != DesktopFrame::kBytesPerPixel * 8 || |
| CGImageGetWidth(cg_image) != static_cast<size_t>(size.width()) || |
| CGImageGetBitsPerComponent(cg_image) != 8) { |
| + if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); |
| return; |
| } |
| CGDataProviderRef provider = CGImageGetDataProvider(cg_image); |
| CFDataRef image_data_ref = CGDataProviderCopyData(provider); |
| - if (image_data_ref == NULL) |
| + if (image_data_ref == NULL) { |
| + if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); |
| return; |
| + } |
| const uint8_t* src_data = |
| reinterpret_cast<const uint8_t*>(CFDataGetBytePtr(image_data_ref)); |
| - // Compare the cursor with the previous one. |
| - if (last_cursor_.get() && |
| - last_cursor_->image()->size().equals(size) && |
| - last_cursor_->hotspot().equals(hotspot) && |
| - memcmp(last_cursor_->image()->data(), src_data, |
| - last_cursor_->image()->stride() * size.height()) == 0) { |
| - CFRelease(image_data_ref); |
| - return; |
| - } |
| - |
| // Create a MouseCursor that describes the cursor and pass it to |
| // the client. |
| std::unique_ptr<DesktopFrame> image( |
| @@ -304,10 +313,10 @@ void MouseCursorMonitorMac::CaptureImage(float scale) { |
| image->CopyPixelsFrom(src_data, src_stride, DesktopRect::MakeSize(size)); |
| CFRelease(image_data_ref); |
| + if (scaled_cg_image != nil) CGImageRelease(scaled_cg_image); |
| std::unique_ptr<MouseCursor> cursor( |
| new MouseCursor(image.release(), hotspot)); |
| - last_cursor_.reset(MouseCursor::CopyOf(*cursor)); |
| callback_->OnMouseCursor(cursor.release()); |
| } |
| @@ -317,10 +326,11 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( |
| return new MouseCursorMonitorMac(options, window, kInvalidScreenId); |
| } |
| +// ScreenCapture already contains current cursor in the captured frame on OSX. |
|
Do not use (sergeyu)
2017/06/01 00:21:59
This is not the right place to fix this. This clas
braveyao1
2017/06/01 17:50:14
OK. Then a separated cl is needed. This is under W
|
| MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( |
| const DesktopCaptureOptions& options, |
| ScreenId screen) { |
| - return new MouseCursorMonitorMac(options, kCGNullWindowID, screen); |
| + return nil; |
| } |
| } // namespace webrtc |