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

Unified Diff: webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm

Issue 2908853002: desktopCapture: scale the cursor image according to screen scale factor on OSX (Closed)
Patch Set: address comments Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« 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