Page flip event support in drm backend

This commit is contained in:
Martin Gräßlin 2015-04-13 09:23:03 +02:00
parent c759551340
commit 3a7d0c395e
2 changed files with 40 additions and 1 deletions

View file

@ -18,12 +18,15 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/ *********************************************************************/
#include "drm_backend.h" #include "drm_backend.h"
#include "composite.h"
#include "logind.h" #include "logind.h"
#include "scene_qpainter.h" #include "scene_qpainter.h"
#include "screens_drm.h" #include "screens_drm.h"
#include "udev.h" #include "udev.h"
#include "utils.h" #include "utils.h"
#include "virtual_terminal.h" #include "virtual_terminal.h"
// Qt
#include <QSocketNotifier>
// system // system
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -69,6 +72,17 @@ void DrmBackend::init()
VirtualTerminal::create(this); VirtualTerminal::create(this);
} }
void DrmBackend::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
{
Q_UNUSED(fd)
Q_UNUSED(frame)
Q_UNUSED(sec)
Q_UNUSED(usec)
DrmBuffer *buffer = reinterpret_cast<DrmBuffer*>(data);
buffer->m_backend->m_pageFlipPending = false;
Compositor::self()->bufferSwapComplete();
}
void DrmBackend::openDrm() void DrmBackend::openDrm()
{ {
VirtualTerminal::self()->init(); VirtualTerminal::self()->init();
@ -83,6 +97,16 @@ void DrmBackend::openDrm()
return; return;
} }
m_fd = fd; m_fd = fd;
QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated, this,
[this] {
drmEventContext e;
memset(&e, 0, sizeof e);
e.version = DRM_EVENT_CONTEXT_VERSION;
e.page_flip_handler = pageFlipHandler;
drmHandleEvent(m_fd, &e);
}
);
m_drmId = device->sysNum(); m_drmId = device->sysNum();
queryResources(); queryResources();
emit screensQueried(); emit screensQueried();
@ -129,6 +153,11 @@ void DrmBackend::queryResources()
m_crtcId = encoder->crtc_id; m_crtcId = encoder->crtc_id;
m_connector = connector->connector_id; m_connector = connector->connector_id;
m_mode = crtc->mode; m_mode = crtc->mode;
// TODO: improve
DrmBuffer *b = new DrmBuffer(this, m_resolution);
b->map();
b->image()->fill(Qt::black);
drmModeSetCrtc(m_fd, m_crtcId, b->m_bufferId, 0, 0, &m_connector, 1, &m_mode);
// for the moment only one crtc // for the moment only one crtc
break; break;
} }
@ -136,7 +165,15 @@ void DrmBackend::queryResources()
void DrmBackend::present(DrmBuffer *buffer) void DrmBackend::present(DrmBuffer *buffer)
{ {
drmModeSetCrtc(m_fd, m_crtcId, buffer->m_bufferId, 0, 0, &m_connector, 1, &m_mode); if (!buffer || buffer->m_bufferId == 0) {
return;
}
if (m_pageFlipPending) {
return;
}
m_pageFlipPending = true;
Compositor::self()->aboutToSwapBuffers();
drmModePageFlip(m_fd, m_crtcId, buffer->m_bufferId, DRM_MODE_PAGE_FLIP_EVENT, buffer);
} }
Screens *DrmBackend::createScreens(QObject *parent) Screens *DrmBackend::createScreens(QObject *parent)

View file

@ -58,6 +58,7 @@ Q_SIGNALS:
void screensQueried(); void screensQueried();
private: private:
static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data);
void openDrm(); void openDrm();
void queryResources(); void queryResources();
QScopedPointer<Udev> m_udev; QScopedPointer<Udev> m_udev;
@ -68,6 +69,7 @@ private:
quint32 m_crtcId = 0; quint32 m_crtcId = 0;
quint32 m_connector = 0; quint32 m_connector = 0;
drmModeModeInfo m_mode; drmModeModeInfo m_mode;
bool m_pageFlipPending = false;
}; };
class DrmBuffer class DrmBuffer