-
Notifications
You must be signed in to change notification settings - Fork 6
/
DrmVsyncThread.cpp
77 lines (63 loc) · 1.94 KB
/
DrmVsyncThread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2019 Stephan Gerhold
#define LOG_TAG "drmfb-vsync"
#include <time.h>
#include <android-base/logging.h>
#include <xf86drm.h>
#include "DrmVsyncThread.h"
#include "DrmDevice.h"
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace drmfb {
namespace {
constexpr int64_t NANO = 1'000'000'000;
constexpr int64_t DEFAULT_PERIOD = NANO / 60; // 60 Hz
}
DrmVsyncThread::DrmVsyncThread(DrmDisplay& display)
: GraphicsThread("drm-vsync-" + std::to_string(display.id())),
mDisplay(display) {}
void DrmVsyncThread::run() {
auto highCrtc = mDisplay.pipe() << DRM_VBLANK_HIGH_CRTC_SHIFT;
drmVBlank vBlank{ .request = {
.type = static_cast<drmVBlankSeqType>(
DRM_VBLANK_RELATIVE | (highCrtc & DRM_VBLANK_HIGH_CRTC_MASK)),
.sequence = 1,
}};
auto ret = drmWaitVBlank(mDisplay.device().fd(), &vBlank);
if (ret) {
PLOG(ERROR) << "drmWaitBlank failed";
if (errno == EBUSY || waitFallback())
return;
} else {
mTimestamp = vBlank.reply.tval_sec * NANO + vBlank.reply.tval_usec * 1000;
}
mDisplay.vsync(mTimestamp);
}
int DrmVsyncThread::waitFallback() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
int64_t period = mDisplay.vsyncPeriod(mDisplay.currentMode());
if (period <= 0)
period = DEFAULT_PERIOD;
int64_t now = ts.tv_sec * NANO + ts.tv_nsec;
mTimestamp = mTimestamp ? mTimestamp + period : now + period;
while (mTimestamp < now) {
mTimestamp += period;
}
ts.tv_sec = mTimestamp / NANO;
ts.tv_nsec = mTimestamp % NANO;
int ret;
do {
ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr);
} while (ret == EINTR);
return ret;
}
} // namespace drmfb
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android