macOS: Optionally flush sub-layers via sub-image copies of the backingstore
When we're flushing the backingstore to sub-views with their own layers we don't want to pay the cost of uploading the whole backingstore to the GPU in the case where we're dealing with a discrete GPU. To work around this we make a copy of the appropriate part of the surfcace. This results in additional copies of the data, and will need further investigation to limit these. Task-number: QTBUG-77447 Change-Id: I318ae80e433dd7b0a55fd5a598b19f114d8bd28e Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> (cherry picked from commit eaf4911db29a82b3d94826a8ff09afe075a2b636) Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
45237fa54c
commit
197dfcd36f
@ -572,17 +572,26 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
flushedView.layer.contents = nil;
|
||||
}
|
||||
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
if (flushedView == backingStoreView) {
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
} else {
|
||||
auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
|
||||
auto scale = flushedView.layer.contentsScale;
|
||||
subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
|
||||
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
// We make a copy of the image data up front, which means we don't
|
||||
// need to mark the IOSurface as being in use. FIXME: Investigate
|
||||
// if there's a cheaper way to get sub-image data to a layer.
|
||||
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||
QImage subImage = m_buffers.back()->asImage()->copy(QRectF::fromCGRect(subviewRect).toRect());
|
||||
m_buffers.back()->unlock();
|
||||
|
||||
if (flushedView != backingStoreView) {
|
||||
const CGSize backingStoreSize = backingStoreView.bounds.size;
|
||||
flushedView.layer.contentsRect = CGRectApplyAffineTransform(
|
||||
[flushedView convertRect:flushedView.bounds toView:backingStoreView],
|
||||
// The contentsRect is in unit coordinate system
|
||||
CGAffineTransformMakeScale(1.0 / backingStoreSize.width, 1.0 / backingStoreSize.height));
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << subImage
|
||||
<< "to" << flushedView.layer << "of subview" << flushedView;
|
||||
QCFType<CGImageRef> cgImage = subImage.toCGImage();
|
||||
flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
|
||||
}
|
||||
|
||||
// Since we may receive multiple flushes before a new frame is started, we do not
|
||||
|
Loading…
x
Reference in New Issue
Block a user