Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
// Qt-Security score:significant reason:default
4
5
#
include
"qeglfskmseventreader_p.h"
6
#
include
"qeglfskmsdevice_p.h"
7
#
include
"qeglfskmsscreen_p.h"
8
#
include
"qeglfskmsintegration_p.h"
9
10
#
include
<
QSocketNotifier
>
11
#
include
<
QCoreApplication
>
12
#
include
<
QLoggingCategory
>
13
14
QT_BEGIN_NAMESPACE
15
16
static
void
pageFlipHandler
(
int
fd,
unsigned
int
sequence,
unsigned
int
tv_sec,
unsigned
int
tv_usec,
void
*user_data)
17
{
18
Q_UNUSED(fd);
19
20
QEglFSKmsEventReaderThread
*t =
static_cast
<QEglFSKmsEventReaderThread *>(QThread::currentThread());
21
t
->
eventHost
(
)
->
handlePageFlipCompleted
(
user_data
)
;
22
23
QEglFSKmsScreen *screen =
static_cast
<QEglFSKmsScreen *>(user_data);
24
if
(QEglFSKmsScreen::isScreenKnown(screen))
25
screen->pageFlipped(sequence, tv_sec, tv_usec);
26
else
27
qWarning(
"Deleted screen got it's pageFlipHandler called; Dead pointer: %p"
, user_data);
28
}
29
30
class
RegisterWaitFlipEvent
:
public
QEvent
31
{
32
public
:
33
static
const
QEvent
::
Type
TYPE
=
QEvent
::
Type
(
QEvent
::
User
+ 1);
34
RegisterWaitFlipEvent
(
void
*key, QMutex *mutex, QWaitCondition *cond)
35
:
QEvent
(
TYPE
),
key
(key),
mutex
(
mutex
),
cond
(
cond
)
36
{ }
37
void
*
key
;
38
QMutex
*
mutex
;
39
QWaitCondition
*
cond
;
40
};
41
42
bool
QEglFSKmsEventHost
::
event
(QEvent *event)
43
{
44
if
(event->type() == RegisterWaitFlipEvent::TYPE) {
45
RegisterWaitFlipEvent
*e =
static_cast
<
RegisterWaitFlipEvent
*>(event);
46
PendingFlipWait
*p = &pendingFlipWaits[0];
47
PendingFlipWait
*end = p +
MAX_FLIPS
;
48
while
(p < end) {
49
if
(!p
->
key
) {
50
p
->
key
= e
->
key
;
51
p->mutex = e->mutex;
52
p->cond = e->cond;
53
updateStatus
(
)
;
54
return
true
;
55
}
56
++p;
57
}
58
qWarning(
"Cannot queue page flip wait (more than %d screens?)"
,
MAX_FLIPS
);
59
e->mutex->lock();
60
e->cond->wakeOne();
61
e->mutex->unlock();
62
return
true
;
63
}
64
return
QObject::event(event);
65
}
66
67
void
QEglFSKmsEventHost
::
updateStatus
()
68
{
69
void
**begin = &
completedFlips
[0];
70
void
**end = begin +
MAX_FLIPS
;
71
72
for
(
int
i = 0; i <
MAX_FLIPS
; ++i) {
73
PendingFlipWait
*w = pendingFlipWaits + i;
74
if
(!w
->
key
)
75
continue
;
76
77
void
**p = begin;
78
while
(p < end) {
79
if
(*p == w
->
key
) {
80
*p =
nullptr
;
81
w
->
key
=
nullptr
;
82
w->mutex->lock();
83
w->cond->wakeOne();
84
w->mutex->unlock();
85
return
;
86
}
87
++p;
88
}
89
}
90
}
91
92
void
QEglFSKmsEventHost
::
handlePageFlipCompleted
(
void
*key)
93
{
94
void
**begin = &
completedFlips
[0];
95
void
**end = begin +
MAX_FLIPS
;
96
void
**p = begin;
97
while
(p < end) {
98
if
(*p == key) {
99
updateStatus
(
)
;
100
return
;
101
}
102
++p;
103
}
104
p = begin;
105
while
(p < end) {
106
if
(!*p) {
107
*p = key;
108
updateStatus
(
)
;
109
return
;
110
}
111
++p;
112
}
113
qWarning(
"Cannot store page flip status (more than %d screens?)"
,
MAX_FLIPS
);
114
}
115
116
void
QEglFSKmsEventReaderThread
::
run
()
117
{
118
qCDebug(qLcEglfsKmsDebug,
"Event reader thread: entering event loop"
);
119
120
QSocketNotifier notifier(m_fd, QSocketNotifier::Read);
121
QObject::connect(¬ifier, &QSocketNotifier::activated, ¬ifier, [
this
] {
122
drmEventContext drmEvent;
123
memset(&drmEvent, 0,
sizeof
(drmEvent));
124
drmEvent.version = 2;
125
drmEvent.vblank_handler =
nullptr
;
126
drmEvent.page_flip_handler = pageFlipHandler;
127
drmHandleEvent(m_fd, &drmEvent);
128
});
129
130
exec();
131
132
m_ev.moveToThread(thread());
// move back to the thread where m_ev was created
133
134
qCDebug(qLcEglfsKmsDebug,
"Event reader thread: event loop stopped"
);
135
}
136
137
QEglFSKmsEventReader::~QEglFSKmsEventReader()
138
{
139
destroy();
140
}
141
142
void
QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
143
{
144
destroy();
145
146
if
(!device)
147
return
;
148
149
m_device = device;
150
151
qCDebug(qLcEglfsKmsDebug,
"Initializing event reader for device %p fd %d"
,
152
m_device, m_device->fd());
153
154
m_thread =
new
QEglFSKmsEventReaderThread(m_device->fd());
155
m_thread->start();
156
157
// Change thread affinity for the event host, so that postEvent()
158
// goes through the event reader thread's event loop for that object.
159
m_thread->eventHost()->moveToThread(m_thread);
160
}
161
162
void
QEglFSKmsEventReader::destroy()
163
{
164
if
(!m_device)
165
return
;
166
167
qCDebug(qLcEglfsKmsDebug,
"Stopping event reader for device %p"
, m_device);
168
169
if
(m_thread) {
170
m_thread->quit();
171
m_thread->wait();
172
delete
m_thread;
173
m_thread =
nullptr
;
174
}
175
176
m_device =
nullptr
;
177
}
178
179
void
QEglFSKmsEventReader::startWaitFlip(
void
*key, QMutex *mutex, QWaitCondition *cond)
180
{
181
if
(m_thread) {
182
QCoreApplication::postEvent(m_thread->eventHost(),
183
new
RegisterWaitFlipEvent(key, mutex, cond));
184
}
185
}
186
187
QT_END_NAMESPACE
QEglFSKmsEventReaderThread
Definition
qeglfskmseventreader_p.h:47
QEglFSKmsEventReaderThread::eventHost
QEglFSKmsEventHost * eventHost()
Definition
qeglfskmseventreader_p.h:51
QEglFSKmsEventReaderThread::run
void run() override
Definition
qeglfskmseventreader.cpp:116
RegisterWaitFlipEvent
Definition
qeglfskmseventreader.cpp:31
RegisterWaitFlipEvent::RegisterWaitFlipEvent
RegisterWaitFlipEvent(void *key, QMutex *mutex, QWaitCondition *cond)
Definition
qeglfskmseventreader.cpp:34
RegisterWaitFlipEvent::cond
QWaitCondition * cond
Definition
qeglfskmseventreader.cpp:39
RegisterWaitFlipEvent::key
void * key
Definition
qeglfskmseventreader.cpp:37
RegisterWaitFlipEvent::TYPE
static const QEvent::Type TYPE
Definition
qeglfskmseventreader.cpp:33
RegisterWaitFlipEvent::mutex
QMutex * mutex
Definition
qeglfskmseventreader.cpp:38
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
pageFlipHandler
static QT_BEGIN_NAMESPACE void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
Definition
qeglfskmseventreader.cpp:16
QEglFSKmsEventHost::PendingFlipWait
Definition
qeglfskmseventreader_p.h:31
QEglFSKmsEventHost::PendingFlipWait::key
void * key
Definition
qeglfskmseventreader_p.h:32
QEglFSKmsEventHost
Definition
qeglfskmseventreader_p.h:30
QEglFSKmsEventHost::MAX_FLIPS
static const int MAX_FLIPS
Definition
qeglfskmseventreader_p.h:37
QEglFSKmsEventHost::updateStatus
void updateStatus()
Definition
qeglfskmseventreader.cpp:67
QEglFSKmsEventHost::event
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition
qeglfskmseventreader.cpp:42
QEglFSKmsEventHost::completedFlips
void * completedFlips[MAX_FLIPS]
Definition
qeglfskmseventreader_p.h:38
QEglFSKmsEventHost::handlePageFlipCompleted
void handlePageFlipCompleted(void *key)
Definition
qeglfskmseventreader.cpp:92
qtbase
src
plugins
platforms
eglfs
deviceintegration
eglfs_kms_support
qeglfskmseventreader.cpp
Generated on
for Qt by
1.18.0