[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:
parent
03074c925c
commit
f36af69a0e
3 changed files with 52 additions and 0 deletions
|
@ -35,6 +35,7 @@ EglHwcomposerBackend::EglHwcomposerBackend(HwcomposerBackend *backend)
|
||||||
init();
|
init();
|
||||||
// EGL is always direct rendering
|
// EGL is always direct rendering
|
||||||
setIsDirectRendering(true);
|
setIsDirectRendering(true);
|
||||||
|
setSyncsToVBlank(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EglHwcomposerBackend::~EglHwcomposerBackend()
|
EglHwcomposerBackend::~EglHwcomposerBackend()
|
||||||
|
|
|
@ -110,6 +110,28 @@ void HwcomposerBackend::init()
|
||||||
|
|
||||||
// unblank, setPowerMode?
|
// unblank, setPowerMode?
|
||||||
m_device = hwcDevice;
|
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();
|
toggleBlankOutput();
|
||||||
|
|
||||||
// get display configuration
|
// get display configuration
|
||||||
|
@ -136,6 +158,7 @@ void HwcomposerBackend::toggleBlankOutput()
|
||||||
}
|
}
|
||||||
m_outputBlank = !m_outputBlank;
|
m_outputBlank = !m_outputBlank;
|
||||||
m_device->blank(m_device, 0, m_outputBlank ? 1 : 0);
|
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
|
// enable/disable compositor repainting when blanked
|
||||||
if (Compositor *compositor = Compositor::self()) {
|
if (Compositor *compositor = Compositor::self()) {
|
||||||
if (m_outputBlank) {
|
if (m_outputBlank) {
|
||||||
|
@ -162,6 +185,27 @@ OpenGLBackend *HwcomposerBackend::createOpenGLBackend()
|
||||||
return new EglHwcomposerBackend(this);
|
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)
|
static void initLayer(hwc_layer_1_t *layer, const hwc_rect_t &rect)
|
||||||
{
|
{
|
||||||
memset(layer, 0, sizeof(hwc_layer_1_t));
|
memset(layer, 0, sizeof(hwc_layer_1_t));
|
||||||
|
@ -217,6 +261,7 @@ HwcomposerWindow::~HwcomposerWindow()
|
||||||
|
|
||||||
void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
|
void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
|
||||||
{
|
{
|
||||||
|
m_backend->present();
|
||||||
hwc_composer_device_1_t *device = m_backend->device();
|
hwc_composer_device_1_t *device = m_backend->device();
|
||||||
|
|
||||||
auto fblayer = &m_list[0]->hwLayers[1];
|
auto fblayer = &m_list[0]->hwLayers[1];
|
||||||
|
@ -235,6 +280,7 @@ void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
|
||||||
close(m_list[0]->retireFenceFd);
|
close(m_list[0]->retireFenceFd);
|
||||||
m_list[0]->retireFenceFd = -1;
|
m_list[0]->retireFenceFd = -1;
|
||||||
}
|
}
|
||||||
|
m_list[0]->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,14 @@ public:
|
||||||
hwc_composer_device_1_t *device() const {
|
hwc_composer_device_1_t *device() const {
|
||||||
return m_device;
|
return m_device;
|
||||||
}
|
}
|
||||||
|
void present();
|
||||||
int refreshRate() const {
|
int refreshRate() const {
|
||||||
return m_refreshRate;
|
return m_refreshRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void vsync();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void toggleBlankOutput();
|
void toggleBlankOutput();
|
||||||
|
|
||||||
|
@ -70,6 +74,7 @@ private:
|
||||||
QSize m_displaySize;
|
QSize m_displaySize;
|
||||||
hwc_composer_device_1_t *m_device = nullptr;
|
hwc_composer_device_1_t *m_device = nullptr;
|
||||||
bool m_outputBlank = true;
|
bool m_outputBlank = true;
|
||||||
|
bool m_pageFlipPending = false;
|
||||||
int m_refreshRate = 60000;
|
int m_refreshRate = 60000;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue