QScreen, iOS: Make grabWindow() use UIGraphicsImageRenderer
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 <tim.blechmann@qt.io>
This commit is contained in:
parent
e67c4c986f
commit
cb09be1512
@ -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);
|
||||
QMacAutoReleasePool autoReleasePool;
|
||||
|
||||
// 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];
|
||||
UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
|
||||
format.opaque = NO;
|
||||
format.scale = devicePixelRatio();
|
||||
// Could be adjusted to support HDR in the future.
|
||||
format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
|
||||
|
||||
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user