sdm: Prioritize vsync register over commit
Back to back display commits can delay RegisterVsync()
-- Wait for previous retire fence.
This ensures that driver is flushed.
-- Register for vsync
-- Start commit processing.
Change-Id: Id2838dc8fe54cf4af8032cc794e2a12c0f716b88
CRs-Fixed: 2583241
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index d971255..57cf70b 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -54,6 +54,10 @@
: DisplayBase(display_id, kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler,
buffer_allocator, comp_manager, hw_info_intf) {}
+DisplayBuiltIn::~DisplayBuiltIn() {
+ CloseFd(&previous_retire_fence_);
+}
+
DisplayError DisplayBuiltIn::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
int32_t disable_defer_power_state = 0;
@@ -204,6 +208,16 @@
}
}
+ if (vsync_enable_) {
+ DTRACE_BEGIN("RegisterVsync");
+ // wait for previous frame's retire fence to signal.
+ buffer_sync_handler_->SyncWait(previous_retire_fence_);
+
+ // Register for vsync and then commit the frame.
+ hw_events_intf_->SetEventState(HWEvent::VSYNC, true);
+ DTRACE_END();
+ }
+
error = DisplayBase::Commit(layer_stack);
if (error != kErrorNone) {
return error;
@@ -241,6 +255,9 @@
first_cycle_ = false;
+ CloseFd(&previous_retire_fence_);
+ previous_retire_fence_ = Sys::dup_(layer_stack->retire_fence_fd);
+
return error;
}
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 9395c47..1de4b23 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -56,6 +56,8 @@
DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
HWInfoInterface *hw_info_intf, BufferSyncHandler *buffer_sync_handler,
BufferAllocator *buffer_allocator, CompManager *comp_manager);
+ virtual ~DisplayBuiltIn();
+
virtual DisplayError Init();
virtual DisplayError Deinit();
virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -108,6 +110,7 @@
LayerRect left_frame_roi_ = {};
LayerRect right_frame_roi_ = {};
bool first_cycle_ = true;
+ int previous_retire_fence_ = -1;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 3bb9a6a..63e7127 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -380,6 +380,7 @@
}
DisplayError HWEventsDRM::RegisterVSync() {
+ DTRACE_SCOPED();
drmVBlank vblank {};
uint32_t high_crtc = token_.crtc_index << DRM_VBLANK_HIGH_CRTC_SHIFT;
vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT |
@@ -501,6 +502,15 @@
}
void HWEventsDRM::HandleVSync(char *data) {
+ {
+ std::lock_guard<std::mutex> lock(vsync_mutex_);
+ vsync_registered_ = false;
+ if (vsync_enabled_) {
+ RegisterVSync();
+ vsync_registered_ = true;
+ }
+ }
+
drmEventContext event = {};
event.version = DRM_EVENT_CONTEXT_VERSION;
event.vblank_handler = &HWEventsDRM::VSyncHandlerCallback;
@@ -508,13 +518,6 @@
if (error != 0) {
DLOGE("drmHandleEvent failed: %i", error);
}
-
- std::lock_guard<std::mutex> lock(vsync_mutex_);
- vsync_registered_ = false;
- if (vsync_enabled_) {
- RegisterVSync();
- vsync_registered_ = true;
- }
}
void HWEventsDRM::HandlePanelDead(char *data) {
@@ -561,6 +564,7 @@
void HWEventsDRM::VSyncHandlerCallback(int fd, unsigned int sequence, unsigned int tv_sec,
unsigned int tv_usec, void *data) {
int64_t timestamp = (int64_t)(tv_sec)*1000000000 + (int64_t)(tv_usec)*1000;
+ DTRACE_SCOPED();
reinterpret_cast<HWEventsDRM *>(data)->event_handler_->VSync(timestamp);
}