[hwcomposer] Add support for vsync

Note: qt5-qpa-hwcomposer-plugin does the vsync in a different way:
it uses a wait condition to truly block in present till the vsync.
Maybe we need to do that as well.
This commit is contained in:
Martin Gräßlin 2015-06-26 10:09:16 +02:00
parent 03074c925c
commit f36af69a0e
3 changed files with 52 additions and 0 deletions

View file

@ -35,6 +35,7 @@ EglHwcomposerBackend::EglHwcomposerBackend(HwcomposerBackend *backend)
init();
// EGL is always direct rendering
setIsDirectRendering(true);
setSyncsToVBlank(true);
}
EglHwcomposerBackend::~EglHwcomposerBackend()

View file

@ -110,6 +110,28 @@ void HwcomposerBackend::init()
// unblank, setPowerMode?
m_device = hwcDevice;
// register callbacks
hwc_procs_t *procs = new hwc_procs_t;
procs->invalidate = [] (const struct hwc_procs* procs) {
Q_UNUSED(procs)
};
procs->vsync = [] (const struct hwc_procs* procs, int disp, int64_t timestamp) {
Q_UNUSED(procs)
if (disp != 0) {
return;
}
QMetaObject::invokeMethod(dynamic_cast<HwcomposerBackend*>(waylandServer()->backend()),
"vsync",
Qt::QueuedConnection);
};
procs->hotplug = [] (const struct hwc_procs* procs, int disp, int connected) {
Q_UNUSED(procs)
Q_UNUSED(disp)
Q_UNUSED(connected)
};
m_device->registerProcs(m_device, procs);
toggleBlankOutput();
// get display configuration
@ -136,6 +158,7 @@ void HwcomposerBackend::toggleBlankOutput()
}
m_outputBlank = !m_outputBlank;
m_device->blank(m_device, 0, m_outputBlank ? 1 : 0);
m_device->eventControl(m_device, 0, HWC_EVENT_VSYNC, m_outputBlank ? 0 : 1);
// enable/disable compositor repainting when blanked
if (Compositor *compositor = Compositor::self()) {
if (m_outputBlank) {
@ -162,6 +185,27 @@ OpenGLBackend *HwcomposerBackend::createOpenGLBackend()
return new EglHwcomposerBackend(this);
}
void HwcomposerBackend::present()
{
if (m_pageFlipPending) {
return;
}
m_pageFlipPending = true;
if (Compositor::self()) {
Compositor::self()->aboutToSwapBuffers();
}
}
void HwcomposerBackend::vsync()
{
if (m_pageFlipPending) {
m_pageFlipPending = false;
if (Compositor::self()) {
Compositor::self()->bufferSwapComplete();
}
}
}
static void initLayer(hwc_layer_1_t *layer, const hwc_rect_t &rect)
{
memset(layer, 0, sizeof(hwc_layer_1_t));
@ -217,6 +261,7 @@ HwcomposerWindow::~HwcomposerWindow()
void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
{
m_backend->present();
hwc_composer_device_1_t *device = m_backend->device();
auto fblayer = &m_list[0]->hwLayers[1];
@ -235,6 +280,7 @@ void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
close(m_list[0]->retireFenceFd);
m_list[0]->retireFenceFd = -1;
}
m_list[0]->flags = 0;
}
}

View file

@ -59,10 +59,14 @@ public:
hwc_composer_device_1_t *device() const {
return m_device;
}
void present();
int refreshRate() const {
return m_refreshRate;
}
public Q_SLOTS:
void vsync();
private Q_SLOTS:
void toggleBlankOutput();
@ -70,6 +74,7 @@ private:
QSize m_displaySize;
hwc_composer_device_1_t *m_device = nullptr;
bool m_outputBlank = true;
bool m_pageFlipPending = false;
int m_refreshRate = 60000;
};