summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNils Petter Skålerud <[email protected]>2025-05-28 15:45:03 +0200
committerNils Petter Skålerud <[email protected]>2025-06-04 02:37:47 +0200
commitcb09be1512e5f932af1744773a7638f23ebd57f9 (patch)
treead493468fe7310bc65d76e237bb85f0e339bf895
parente67c4c986ffaeb98c1ccb52b689e7a8b37eb6672 (diff)
QScreen, iOS: Make grabWindow() use UIGraphicsImageRendererHEADdev
Currently the QIOSScreen::grabWindow implementaton relies on UIGraphicsBeginImageContextWithOptions to do a screenshot. This API is deprecated and produces a few warnings logs that we can't silence even when we handle the errors. The current approach also has a memory leak when taking screenshots in rapid succession (i.e 60 FPS). This patch modifies grabWindow() to use UIGraphicsImageRenderer, which replaces the deprecated API. This no longer produces warning logs when errors are handled. This API can be used in the future to let us take HDR screenshots once Qt has support for this. This patch solves the mentioned memory leak. Pick-to: 6.10 6.9 6.8 Change-Id: Ifbc8503482886246ce9611d0b7a19462fc830ecd Reviewed-by: Tim Blechmann <[email protected]>
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 1e0d074330a..ad735266e03 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -428,19 +428,33 @@ QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height)
CGRect captureRect = [view.window convertRect:CGRectMake(x, y, width, height) fromView:view];
captureRect = CGRectIntersection(captureRect, view.window.bounds);
- UIGraphicsBeginImageContextWithOptions(captureRect.size, NO, 0.0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y);
-
- // Draws the complete view hierarchy of view.window into the given rect, which
- // needs to be the same aspect ratio as the view.window's size. Since we've
- // translated the graphics context, and are potentially drawing into a smaller
- // context than the full window, the resulting image will be a subsection of the
- // full screen.
- [view.window drawViewHierarchyInRect:view.window.bounds afterScreenUpdates:NO];
-
- UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
+ QMacAutoReleasePool autoReleasePool;
+
+ UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
+ format.opaque = NO;
+ format.scale = devicePixelRatio();
+ // Could be adjusted to support HDR in the future.
+ format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
+
+ UIGraphicsImageRenderer *renderer = [[[UIGraphicsImageRenderer alloc]
+ initWithSize:captureRect.size format:format]
+ autorelease];
+
+ UIImage *screenshot = [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
+ CGContextRef context = rendererContext.CGContext;
+ CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y);
+
+ // Draws the complete view hierarchy of view.window into the given rect, which
+ // needs to be the same aspect ratio as the view.window's size. Since we've
+ // translated the graphics context, and are potentially drawing into a smaller
+ // context than the full window, the resulting image will be a subsection of the
+ // full screen.
+ //
+ // TODO: Should only be run on the UI thread in the future. At
+ // the time of writing, QScreen::grabWindow doesn't include any
+ // requirements as to which thread it can be called from.
+ [view.window drawViewHierarchyInRect:view.window.bounds afterScreenUpdates:NO];
+ }];
return QPixmap::fromImage(qt_mac_toQImage(screenshot.CGImage));
}