diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp index 7a3d3851..86a3f544 100644 --- a/sdm/libs/core/drm/hw_events_drm.cpp +++ b/sdm/libs/core/drm/hw_events_drm.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -182,7 +182,6 @@ DisplayError HWEventsDRM::Init(int display_type, HWEventHandler *event_handler, static_cast(hw_intf)->GetDRMDisplayToken(&token_); is_primary_ = static_cast(hw_intf)->IsPrimaryDisplay(); - vsync_enabled_ = is_primary_; DLOGI("Setup event handler for display %d, CRTC %d, Connector %d", display_type, token_.crtc_id, token_.conn_id); @@ -198,6 +197,11 @@ DisplayError HWEventsDRM::Init(int display_type, HWEventHandler *event_handler, return kErrorResources; } + if (is_primary_) { + RegisterVSync(); + vsync_registered_ = true; + } + RegisterPanelDead(true); RegisterIdleNotify(true); RegisterIdlePowerCollapse(true); @@ -220,15 +224,17 @@ DisplayError HWEventsDRM::Deinit() { DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) { switch (event) { - case HWEvent::VSYNC: + case HWEvent::VSYNC: { + std::lock_guard lock(vsync_mutex_); if (!is_primary_) { break; } vsync_enabled_ = enable; - if (enable) { - WakeUpEventThread(); + if (vsync_enabled_ && !vsync_registered_) { + RegisterVSync(); + vsync_registered_ = true; } - break; + } break; default: DLOGE("Event not supported"); return kErrorNotSupported; @@ -295,11 +301,6 @@ void *HWEventsDRM::DisplayEventHandler() { setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent); while (!exit_threads_) { - if (vsync_enabled_ && RegisterVSync() != kErrorNone) { - pthread_exit(0); - return nullptr; - } - int error = Sys::poll_(poll_fds_.data(), UINT32(poll_fds_.size()), -1); if (error <= 0) { DLOGW("poll failed. error = %s", strerror(errno)); @@ -469,6 +470,13 @@ void HWEventsDRM::HandleVSync(char *data) { if (error != 0) { DLOGE("drmHandleEvent failed: %i", error); } + + std::lock_guard lock(vsync_mutex_); + vsync_registered_ = false; + if (vsync_enabled_) { + RegisterVSync(); + vsync_registered_ = true; + } } void HWEventsDRM::HandlePanelDead(char *data) { diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h index c54ac6fb..fafe606b 100644 --- a/sdm/libs/core/drm/hw_events_drm.h +++ b/sdm/libs/core/drm/hw_events_drm.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,8 @@ class HWEventsDRM : public HWEventsInterface { bool exit_threads_ = false; uint32_t vsync_index_ = 0; bool vsync_enabled_ = false; + bool vsync_registered_ = false; + std::mutex vsync_mutex_; // To protect vsync_enabled_ and vsync_registered_ uint32_t idle_notify_index_ = 0; sde_drm::DRMDisplayToken token_ = {}; bool is_primary_ = false;