Delay enabling vsync till first frame is rendered

According to the hwcomposer documentation:
"It is a (silent) error to have HWC_EVENT_VSYNC enabled when calling
hwc_composer_device.set(..., 0, 0, 0) (screen off)".

Because of that we may not enable vsync directly after toggling the
output, but need to wait till after calling the set call.

Reviewed-by: Bhushan Shah
This commit is contained in:
Martin Graesslin 2015-10-19 08:13:04 +00:00 committed by Martin Gräßlin
parent b20ccf91c6
commit d2cb445f4c
2 changed files with 16 additions and 1 deletions

View file

@ -164,7 +164,10 @@ 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);
// only disable Vsycn, enable happens after next frame rendered
if (m_outputBlank) {
enableVSync(false);
}
// enable/disable compositor repainting when blanked
if (Compositor *compositor = Compositor::self()) {
if (m_outputBlank) {
@ -176,6 +179,15 @@ void HwcomposerBackend::toggleBlankOutput()
}
}
void HwcomposerBackend::enableVSync(bool enable)
{
if (m_hasVsync == enable) {
return;
}
const int result = m_device->eventControl(m_device, 0, HWC_EVENT_VSYNC, enable ? 1: 0);
m_hasVsync = enable && (result == 0);
}
HwcomposerWindow *HwcomposerBackend::createSurface()
{
return new HwcomposerWindow(this);
@ -282,6 +294,7 @@ void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
err = device->set(device, 1, m_list);
assert(err == 0);
m_backend->enableVSync(true);
setFenceBufferFd(buffer, fblayer->releaseFenceFd);
if (m_list[0]->retireFenceFd != -1) {

View file

@ -65,6 +65,7 @@ public:
int refreshRate() const {
return m_refreshRate;
}
void enableVSync(bool enable);
public Q_SLOTS:
void vsync();
@ -79,6 +80,7 @@ private:
bool m_pageFlipPending = false;
int m_refreshRate = 60000;
QTimer *m_vsyncFailSafeTimer;
bool m_hasVsync = false;
};
class HwcomposerWindow : public HWComposerNativeWindow