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
qeglfskmseventreader.cpp
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#include "qeglfskmsdevice_p.h"
6#include "qeglfskmsscreen_p.h"
7#include <QSocketNotifier>
8#include <QCoreApplication>
9#include <QLoggingCategory>
10
12
13Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
14
15static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
16{
17 Q_UNUSED(fd);
18
21
23 screen->pageFlipped(sequence, tv_sec, tv_usec);
24}
25
37
39{
40 if (event->type() == RegisterWaitFlipEvent::TYPE) {
44 while (p < end) {
45 if (!p->key) {
46 p->key = e->key;
47 p->mutex = e->mutex;
48 p->cond = e->cond;
50 return true;
51 }
52 ++p;
53 }
54 qWarning("Cannot queue page flip wait (more than %d screens?)", MAX_FLIPS);
55 e->mutex->lock();
56 e->cond->wakeOne();
57 e->mutex->unlock();
58 return true;
59 }
60 return QObject::event(event);
61}
62
64{
65 void **begin = &completedFlips[0];
66 void **end = begin + MAX_FLIPS;
67
68 for (int i = 0; i < MAX_FLIPS; ++i) {
70 if (!w->key)
71 continue;
72
73 void **p = begin;
74 while (p < end) {
75 if (*p == w->key) {
76 *p = nullptr;
77 w->key = nullptr;
78 w->mutex->lock();
79 w->cond->wakeOne();
80 w->mutex->unlock();
81 return;
82 }
83 ++p;
84 }
85 }
86}
87
89{
90 void **begin = &completedFlips[0];
91 void **end = begin + MAX_FLIPS;
92 void **p = begin;
93 while (p < end) {
94 if (*p == key) {
96 return;
97 }
98 ++p;
99 }
100 p = begin;
101 while (p < end) {
102 if (!*p) {
103 *p = key;
104 updateStatus();
105 return;
106 }
107 ++p;
108 }
109 qWarning("Cannot store page flip status (more than %d screens?)", MAX_FLIPS);
110}
111
113{
114 qCDebug(qLcEglfsKmsDebug, "Event reader thread: entering event loop");
115
118 drmEventContext drmEvent;
119 memset(&drmEvent, 0, sizeof(drmEvent));
120 drmEvent.version = 2;
121 drmEvent.vblank_handler = nullptr;
122 drmEvent.page_flip_handler = pageFlipHandler;
123 drmHandleEvent(m_fd, &drmEvent);
124 });
125
126 exec();
127
128 m_ev.moveToThread(thread()); // move back to the thread where m_ev was created
129
130 qCDebug(qLcEglfsKmsDebug, "Event reader thread: event loop stopped");
131}
132
137
139{
140 destroy();
141
142 if (!device)
143 return;
144
145 m_device = device;
146
147 qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
148 m_device, m_device->fd());
149
150 m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
151 m_thread->start();
152
153 // Change thread affinity for the event host, so that postEvent()
154 // goes through the event reader thread's event loop for that object.
155 m_thread->eventHost()->moveToThread(m_thread);
156}
157
159{
160 if (!m_device)
161 return;
162
163 qCDebug(qLcEglfsKmsDebug, "Stopping event reader for device %p", m_device);
164
165 if (m_thread) {
166 m_thread->quit();
167 m_thread->wait();
168 delete m_thread;
169 m_thread = nullptr;
170 }
171
172 m_device = nullptr;
173}
174
176{
177 if (m_thread) {
179 new RegisterWaitFlipEvent(key, mutex, cond));
180 }
181}
182
DarwinBluetooth::LECBManagerNotifier * notifier
IOBluetoothDevice * device
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
QEglFSKmsEventHost * eventHost()
void startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond)
void create(QEglFSKmsDevice *device)
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
int fd() const
\inmodule QtCore
Definition qmutex.h:281
void unlock() noexcept
Unlocks the mutex.
Definition qmutex.h:289
void lock() noexcept
Locks the mutex.
Definition qmutex.h:286
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1389
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
\inmodule QtCore
void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal)
void start(Priority=InheritPriority)
Definition qthread.cpp:996
static QThread * currentThread()
Definition qthread.cpp:1039
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
Definition qthread.cpp:1023
int exec()
Definition qthread.cpp:991
void quit()
Definition qthread.cpp:1008
RegisterWaitFlipEvent(void *key, QMutex *mutex, QWaitCondition *cond)
static const QEvent::Type TYPE
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
static QT_BEGIN_NAMESPACE void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLuint GLuint end
GLuint64 GLenum GLint fd
struct _cl_event * event
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QScreen * screen
[1]
Definition main.cpp:29
#define Q_UNUSED(x)
QMutex mutex
[2]
QEglFSKmsEventHost::PendingFlipWait pendingFlipWaits[MAX_FLIPS]
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void * completedFlips[MAX_FLIPS]
void handlePageFlipCompleted(void *key)