21QIOSurfaceGraphicsBuffer::QIOSurfaceGraphicsBuffer(
const QSize &size,
const QPixelFormat &format)
22 : QPlatformGraphicsBuffer(size, format)
24 const size_t width = size.width();
25 const size_t height = size.height();
27 Q_ASSERT(width <= IOSurfaceGetPropertyMaximum(kIOSurfaceWidth));
28 Q_ASSERT(height <= IOSurfaceGetPropertyMaximum(kIOSurfaceHeight));
30 static const char bytesPerElement = 4;
32 const size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement);
33 const size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow);
35 NSDictionary *options = @{
36 (id)kIOSurfaceWidth: @(width),
37 (id)kIOSurfaceHeight: @(height),
38 (id)kIOSurfacePixelFormat: @(
unsigned(
'BGRA')),
39 (id)kIOSurfaceBytesPerElement: @(bytesPerElement),
40 (id)kIOSurfaceBytesPerRow: @(bytesPerRow),
41 (id)kIOSurfaceAllocSize: @(totalBytes),
44 m_surface = IOSurfaceCreate((CFDictionaryRef)options);
47 Q_ASSERT(size_t(bytesPerLine()) == bytesPerRow);
48 Q_ASSERT(size_t(byteCount()) == totalBytes);
50 QObject::connect(
this, &QObject::objectNameChanged,
this, [
this]{
51 IOSurfaceSetValue(m_surface, kIOSurfaceName, objectName().toNSString());
59void QIOSurfaceGraphicsBuffer::setColorSpace(QCFType<CGColorSpaceRef> colorSpace)
61 static const auto kIOSurfaceColorSpace = CFSTR(
"IOSurfaceColorSpace");
63 qCDebug(lcQpaIOSurface) <<
"Tagging" <<
this <<
"with color space" << colorSpace;
66 IOSurfaceSetValue(m_surface, kIOSurfaceColorSpace,
67 QCFType<CFPropertyListRef>(CGColorSpaceCopyPropertyList(colorSpace)));
69 IOSurfaceRemoveValue(m_surface, kIOSurfaceColorSpace);
106bool QIOSurfaceGraphicsBuffer::doLock(AccessTypes access,
const QRect &rect)
109 Q_ASSERT(!isLocked());
111 qCDebug(lcQpaIOSurface) <<
"Locking" <<
this <<
"for" << access;
115 if (access & (TextureAccess | HWCompositor))
118 auto lockOptions = lockOptionsForAccess(access);
121 lockOptions |= kIOSurfaceLockAvoidSync;
122 kern_return_t ret = IOSurfaceLock(m_surface, lockOptions,
nullptr);
123 if (ret == kIOSurfaceSuccess)
126 if (ret == kIOReturnCannotLock) {
127 qCWarning(lcQpaIOSurface) <<
"Locking of" <<
this <<
"requires read-back";
128 lockOptions ^= kIOSurfaceLockAvoidSync;
129 ret = IOSurfaceLock(m_surface, lockOptions,
nullptr);
132 if (ret != kIOSurfaceSuccess) {
133 qCWarning(lcQpaIOSurface) <<
"Failed to lock" <<
this << ret;
140void QIOSurfaceGraphicsBuffer::doUnlock()
142 qCDebug(lcQpaIOSurface) <<
"Unlocking" <<
this <<
"from" << isLocked();
144 auto lockOptions = lockOptionsForAccess(isLocked());
145 bool success = IOSurfaceUnlock(m_surface, lockOptions,
nullptr) == kIOSurfaceSuccess;
146 Q_ASSERT_X(success,
"QIOSurfaceGraphicsBuffer",
"Unlocking surface should succeed");
152 QDebugStateSaver saver(debug);
154 debug <<
"QIOSurfaceGraphicsBuffer(" << (
const void *)graphicsBuffer;
155 if (graphicsBuffer) {
156 debug <<
", surface=" << graphicsBuffer->m_surface;
157 debug <<
", size=" << graphicsBuffer->size();
158 debug <<
", isLocked=" <<
bool(graphicsBuffer->isLocked());
159 debug <<
", isInUse=" << graphicsBuffer->isInUse();