aboutsummaryrefslogtreecommitdiff
path: root/drm/VSyncWorker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drm/VSyncWorker.cpp')
-rw-r--r--drm/VSyncWorker.cpp42
1 files changed, 15 insertions, 27 deletions
diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp
index dfbf8ce..b2f7e5f 100644
--- a/drm/VSyncWorker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -50,6 +50,14 @@ void VSyncWorker::RegisterCallback(std::shared_ptr<VsyncCallback> callback) {
Unlock();
}
+void VSyncWorker::RegisterClientCallback(hwc2_callback_data_t data,
+ hwc2_function_pointer_t hook) {
+ Lock();
+ vsync_callback_data_ = data;
+ vsync_callback_hook_ = reinterpret_cast<HWC2_PFN_VSYNC>(hook);
+ Unlock();
+}
+
void VSyncWorker::VSyncControl(bool enabled) {
Lock();
enabled_ = enabled;
@@ -151,37 +159,17 @@ void VSyncWorker::Routine() {
(int64_t)vblank.reply.tval_usec * 1000;
}
- /*
- * VSync could be disabled during routine execution so it could potentially
- * lead to crash since callback's inner hook could be invalid anymore. We have
- * no control over lifetime of this hook, therefore we can't rely that it'll
- * be valid after vsync disabling.
- *
- * Blocking VSyncControl to wait until routine
- * will finish execution is logically correct way to fix this issue, but it
- * creates visible lags and stutters, so we have to resort to other ways of
- * mitigating this issue.
- *
- * Doing check before attempt to invoke callback drastically shortens the
- * window when such situation could happen and that allows us to practically
- * avoid this issue.
- *
- * Please note that issue described below is different one and it is related
- * to RegisterCallback, not to disabling vsync via VSyncControl.
- */
if (!enabled_)
return;
- /*
- * There's a race here where a change in callback_ will not take effect until
- * the next subsequent requested vsync. This is unavoidable since we can't
- * call the vsync hook while holding the thread lock.
- *
- * We could shorten the race window by caching callback_ right before calling
- * the hook. However, in practice, callback_ is only updated once, so it's not
- * worth the overhead.
- */
+
if (callback)
callback->Callback(display, timestamp);
+
+ Lock();
+ if (enabled_ && vsync_callback_hook_ && vsync_callback_data_)
+ vsync_callback_hook_(vsync_callback_data_, display, timestamp);
+ Unlock();
+
last_timestamp_ = timestamp;
}
} // namespace android