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

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: run git cl format 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..af63bfdbb4f418baf65382877b40278f7f73ceda 100644
--- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
+++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
@@ -30,21 +30,26 @@
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(nullptr,
+ width,
+ height,
+ CGImageGetBitsPerComponent(image),
+ width * DesktopFrame::kBytesPerPixel,
+ colorspace,
+ CGImageGetBitmapInfo(image));
+
+ if (!context) return nil;
+
+ // Draw image to context, resizing it.
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
+ // Extract resulting image from context.
+ CGImageRef imgRef = CGBitmapContextCreateImage(context);
+ CGContextRelease(context);
+
+ return imgRef;
}
} // namespace
@@ -72,7 +77,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 +258,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);
+ // No need to caputre cursor image if it's unchanged since last capture.
+ if ([[nsimage TIFFRepresentation] isEqual:[last_cursor_ TIFFRepresentation]]) return;
+ last_cursor_ = nsimage;
DesktopSize size(round(nssize.width * scale),
round(nssize.height * scale)); // Pixel size
@@ -271,30 +275,33 @@ 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 +311,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());
}
« 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