Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qiosurfacegraphicsbuffer.mm
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qdebug.h>
7#include <QtCore/qloggingcategory.h>
8
9#include <CoreGraphics/CoreGraphics.h>
10#include <IOSurface/IOSurface.h>
11
12// CGColorSpaceCopyPropertyList is available on 10.12 and above,
13// but was only added in the 10.14 SDK, so declare it just in case.
14extern "C" CFPropertyListRef CGColorSpaceCopyPropertyList(CGColorSpaceRef space);
15
17
18Q_LOGGING_CATEGORY(lcQpaIOSurface, "qt.qpa.backingstore.iosurface");
19
22{
23 const size_t width = size.width();
24 const size_t height = size.height();
25
26 Q_ASSERT(width <= IOSurfaceGetPropertyMaximum(kIOSurfaceWidth));
27 Q_ASSERT(height <= IOSurfaceGetPropertyMaximum(kIOSurfaceHeight));
28
29 static const char bytesPerElement = 4;
30
31 const size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement);
32 const size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow);
33
34 NSDictionary *options = @{
35 (id)kIOSurfaceWidth: @(width),
36 (id)kIOSurfaceHeight: @(height),
37 (id)kIOSurfacePixelFormat: @(unsigned('BGRA')),
38 (id)kIOSurfaceBytesPerElement: @(bytesPerElement),
39 (id)kIOSurfaceBytesPerRow: @(bytesPerRow),
40 (id)kIOSurfaceAllocSize: @(totalBytes),
41 };
42
43 m_surface = IOSurfaceCreate((CFDictionaryRef)options);
44 Q_ASSERT(m_surface);
45
46 Q_ASSERT(size_t(bytesPerLine()) == bytesPerRow);
47 Q_ASSERT(size_t(byteCount()) == totalBytes);
48}
49
53
54void QIOSurfaceGraphicsBuffer::setColorSpace(QCFType<CGColorSpaceRef> colorSpace)
55{
56 static const auto kIOSurfaceColorSpace = CFSTR("IOSurfaceColorSpace");
57
58 qCDebug(lcQpaIOSurface) << "Tagging" << this << "with color space" << colorSpace;
59
60 if (colorSpace) {
61 IOSurfaceSetValue(m_surface, kIOSurfaceColorSpace,
62 QCFType<CFPropertyListRef>(CGColorSpaceCopyPropertyList(colorSpace)));
63 } else {
64 IOSurfaceRemoveValue(m_surface, kIOSurfaceColorSpace);
65 }
66}
67
69{
70 return (const uchar *)IOSurfaceGetBaseAddress(m_surface);
71}
72
74{
75 return (uchar *)IOSurfaceGetBaseAddress(m_surface);
76}
77
79{
80 return IOSurfaceGetBytesPerRow(m_surface);
81}
82
84{
85 return m_surface;
86}
87
89{
90 return IOSurfaceIsInUse(m_surface);
91}
92
93IOSurfaceLockOptions lockOptionsForAccess(QPlatformGraphicsBuffer::AccessTypes access)
94{
95 IOSurfaceLockOptions lockOptions = 0;
97 lockOptions |= kIOSurfaceLockReadOnly;
98 return lockOptions;
99}
100
102{
103 Q_UNUSED(rect);
104 Q_ASSERT(!isLocked());
105
106 qCDebug(lcQpaIOSurface) << "Locking" << this << "for" << access;
107
108 // FIXME: Teach QPlatformBackingStore::composeAndFlush about non-2D texture
109 // targets, so that we can use CGLTexImageIOSurface2D to support TextureAccess.
111 return false;
112
113 auto lockOptions = lockOptionsForAccess(access);
114
115 // Try without read-back first
116 lockOptions |= kIOSurfaceLockAvoidSync;
117 kern_return_t ret = IOSurfaceLock(m_surface, lockOptions, nullptr);
118 if (ret == kIOSurfaceSuccess)
119 return true;
120
121 if (ret == kIOReturnCannotLock) {
122 qCWarning(lcQpaIOSurface) << "Locking of" << this << "requires read-back";
123 lockOptions ^= kIOSurfaceLockAvoidSync;
124 ret = IOSurfaceLock(m_surface, lockOptions, nullptr);
125 }
126
127 if (ret != kIOSurfaceSuccess) {
128 qCWarning(lcQpaIOSurface) << "Failed to lock" << this << ret;
129 return false;
130 }
131
132 return true;
133}
134
136{
137 qCDebug(lcQpaIOSurface) << "Unlocking" << this << "from" << isLocked();
138
139 auto lockOptions = lockOptionsForAccess(isLocked());
140 bool success = IOSurfaceUnlock(m_surface, lockOptions, nullptr) == kIOSurfaceSuccess;
141 Q_ASSERT_X(success, "QIOSurfaceGraphicsBuffer", "Unlocking surface should succeed");
142}
143
144#ifndef QT_NO_DEBUG_STREAM
146{
147 QDebugStateSaver saver(debug);
148 debug.nospace();
149 debug << "QIOSurfaceGraphicsBuffer(" << (const void *)graphicsBuffer;
150 if (graphicsBuffer) {
151 debug << ", surface=" << graphicsBuffer->m_surface;
152 debug << ", size=" << graphicsBuffer->size();
153 debug << ", isLocked=" << bool(graphicsBuffer->isLocked());
154 debug << ", isInUse=" << graphicsBuffer->isInUse();
155 }
156 debug << ')';
157 return debug;
158}
159#endif // !QT_NO_DEBUG_STREAM
160
\inmodule QtCore
\inmodule QtCore
void setColorSpace(QCFType< CGColorSpaceRef > colorSpace)
QIOSurfaceGraphicsBuffer(const QSize &size, const QPixelFormat &format)
bool doLock(AccessTypes access, const QRect &rect) override
This function should be reimplemented by subclasses.
int bytesPerLine() const override
Accessor for bytes per line in the graphics buffer.
const uchar * data() const override
Accessor for the bytes of the buffer.
void doUnlock() override
This function should remove all locks set on the buffer.
\inmodule QtGui
AccessTypes isLocked() const
Function to check if the buffer is locked.
QSize size() const
Accessor for content size.
int byteCount() const
Accessor for the length of the data buffer.
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:25
rect
[4]
Combined button and popup list for selecting options.
CFPropertyListRef CGColorSpaceCopyPropertyList(CGColorSpaceRef space)
IOSurfaceLockOptions lockOptionsForAccess(QPlatformGraphicsBuffer::AccessTypes access)
QDebug operator<<(QDebug debug, const QIOSurfaceGraphicsBuffer *graphicsBuffer)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
return ret
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint id
[7]
GLint GLsizei width
GLenum access
GLint GLsizei GLsizei GLenum format
struct CGColorSpace * CGColorSpaceRef
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
#define Q_UNUSED(x)
unsigned char uchar
Definition qtypes.h:32