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>bb10
parent
35713ef3ff
commit
eaf4911db2
|
|
@ -560,17 +560,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…
Reference in New Issue