diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h index 303c89bc..1f813acf 100644 --- a/sdm/include/core/display_interface.h +++ b/sdm/include/core/display_interface.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -388,12 +388,13 @@ class DisplayInterface { /*! @brief Method to set current state of the display device. @param[in] state \link DisplayState \endlink + @param[in] pointer to release fence @return \link DisplayError \endlink @sa SetDisplayState */ - virtual DisplayError SetDisplayState(DisplayState state) = 0; + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence) = 0; /*! @brief Method to set active configuration for variable properties of the display device. diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp index 936c3985..3bb34414 100644 --- a/sdm/libs/core/display_base.cpp +++ b/sdm/libs/core/display_base.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -433,7 +433,7 @@ DisplayState DisplayBase::GetLastPowerMode() { return last_power_mode_; } -DisplayError DisplayBase::SetDisplayState(DisplayState state) { +DisplayError DisplayBase::SetDisplayState(DisplayState state, int *release_fence) { lock_guard obj(recursive_mutex_); DisplayError error = kErrorNone; bool active = false; @@ -455,7 +455,7 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state) { break; case kStateOn: - error = hw_intf_->PowerOn(); + error = hw_intf_->PowerOn(release_fence); if (error != kErrorNone) { return error; } @@ -471,13 +471,13 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state) { break; case kStateDoze: - error = hw_intf_->Doze(); + error = hw_intf_->Doze(release_fence); active = true; last_power_mode_ = kStateDoze; break; case kStateDozeSuspend: - error = hw_intf_->DozeSuspend(); + error = hw_intf_->DozeSuspend(release_fence); if (display_type_ != kPrimary) { active = true; } diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h index 514f09d4..5e697d9c 100644 --- a/sdm/libs/core/display_base.h +++ b/sdm/libs/core/display_base.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014-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 met: @@ -62,7 +62,7 @@ class DisplayBase : public DisplayInterface { virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info); virtual DisplayError GetActiveConfig(uint32_t *index); virtual DisplayError GetVSyncState(bool *enabled); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual DisplayError SetActiveConfig(uint32_t index); virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) { return kErrorNotSupported; diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp index 91c0d7d2..718dd1e8 100644 --- a/sdm/libs/core/display_primary.cpp +++ b/sdm/libs/core/display_primary.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -166,10 +166,10 @@ DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) { return error; } -DisplayError DisplayPrimary::SetDisplayState(DisplayState state) { +DisplayError DisplayPrimary::SetDisplayState(DisplayState state, int *release_fence) { lock_guard obj(recursive_mutex_); DisplayError error = kErrorNone; - error = DisplayBase::SetDisplayState(state); + error = DisplayBase::SetDisplayState(state, release_fence); if (error != kErrorNone) { return error; } @@ -393,19 +393,26 @@ bool DisplayPrimary::NeedsAVREnable() { void DisplayPrimary::ResetPanel() { DisplayError status = kErrorNone; + int release_fence = -1; DLOGI("Powering off primary"); - status = SetDisplayState(kStateOff); + status = SetDisplayState(kStateOff, &release_fence); if (status != kErrorNone) { DLOGE("power-off on primary failed with error = %d", status); } + if (release_fence >= 0) { + ::close(release_fence); + } DLOGI("Restoring power mode on primary"); DisplayState mode = GetLastPowerMode(); - status = SetDisplayState(mode); + status = SetDisplayState(mode, &release_fence); if (status != kErrorNone) { DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status); } + if (release_fence >= 0) { + ::close(release_fence); + } DLOGI("Enabling HWVsync"); status = SetVSyncState(true); diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h index 621906b3..21ada7ca 100644 --- a/sdm/libs/core/display_primary.h +++ b/sdm/libs/core/display_primary.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -44,7 +44,7 @@ class DisplayPrimary : public DisplayBase, HWEventHandler { virtual DisplayError Commit(LayerStack *layer_stack); virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending); virtual DisplayError DisablePartialUpdateOneFrame(); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual void SetIdleTimeoutMs(uint32_t active_ms); virtual DisplayError SetDisplayMode(uint32_t mode); virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate); diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp index d5bf482d..d28d911b 100644 --- a/sdm/libs/core/drm/hw_device_drm.cpp +++ b/sdm/libs/core/drm/hw_device_drm.cpp @@ -709,7 +709,7 @@ DisplayError HWDeviceDRM::GetConfigIndex(char *mode, uint32_t *index) { return kErrorNone; } -DisplayError HWDeviceDRM::PowerOn() { +DisplayError HWDeviceDRM::PowerOn(int *release_fence) { DTRACE_SCOPED(); if (!drm_atomic_intf_) { DLOGE("DRM Atomic Interface is null!"); @@ -727,6 +727,7 @@ DisplayError HWDeviceDRM::PowerOn() { DLOGE("Failed with error: %d", ret); return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); return kErrorNone; } @@ -750,7 +751,7 @@ DisplayError HWDeviceDRM::PowerOff() { return kErrorNone; } -DisplayError HWDeviceDRM::Doze() { +DisplayError HWDeviceDRM::Doze(int *release_fence) { DTRACE_SCOPED(); drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE); @@ -760,10 +761,12 @@ DisplayError HWDeviceDRM::Doze() { return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); + return kErrorNone; } -DisplayError HWDeviceDRM::DozeSuspend() { +DisplayError HWDeviceDRM::DozeSuspend(int *release_fence) { DTRACE_SCOPED(); drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, @@ -774,6 +777,8 @@ DisplayError HWDeviceDRM::DozeSuspend() { return kErrorHardware; } + drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence); + return kErrorNone; } diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h index 3af3b77d..a0f579d4 100644 --- a/sdm/libs/core/drm/hw_device_drm.h +++ b/sdm/libs/core/drm/hw_device_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 @@ -67,10 +67,10 @@ class HWDeviceDRM : public HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); - virtual DisplayError PowerOn(); + virtual DisplayError PowerOn(int *release_fence); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp index 245b5738..adf1f1ea 100644 --- a/sdm/libs/core/drm/hw_tv_drm.cpp +++ b/sdm/libs/core/drm/hw_tv_drm.cpp @@ -165,11 +165,11 @@ DisplayError HWTVDRM::PowerOff() { return kErrorNone; } -DisplayError HWTVDRM::Doze() { +DisplayError HWTVDRM::Doze(int *release_fence) { return kErrorNone; } -DisplayError HWTVDRM::DozeSuspend() { +DisplayError HWTVDRM::DozeSuspend(int *release_fence) { return kErrorNone; } diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h index 49384a2f..3e592f97 100644 --- a/sdm/libs/core/drm/hw_tv_drm.h +++ b/sdm/libs/core/drm/hw_tv_drm.h @@ -43,8 +43,8 @@ class HWTVDRM : public HWDeviceDRM { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Commit(HWLayers *hw_layers); virtual void PopulateHWPanelInfo(); diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp index 2c529ae0..1f733a04 100644 --- a/sdm/libs/core/fb/hw_device.cpp +++ b/sdm/libs/core/fb/hw_device.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 @@ -155,7 +155,7 @@ DisplayError HWDevice::GetConfigIndex(char *mode, uint32_t *index) { return kErrorNone; } -DisplayError HWDevice::PowerOn() { +DisplayError HWDevice::PowerOn(int *release_fence) { DTRACE_SCOPED(); if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) { @@ -174,11 +174,11 @@ DisplayError HWDevice::PowerOff() { return kErrorNone; } -DisplayError HWDevice::Doze() { +DisplayError HWDevice::Doze(int *release_fence) { return kErrorNone; } -DisplayError HWDevice::DozeSuspend() { +DisplayError HWDevice::DozeSuspend(int *release_fence) { return kErrorNone; } diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h index f32c5bda..353cce5b 100644 --- a/sdm/libs/core/fb/hw_device.h +++ b/sdm/libs/core/fb/hw_device.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -70,10 +70,10 @@ class HWDevice : public HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); - virtual DisplayError PowerOn(); + virtual DisplayError PowerOn(int *release_fence); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Standby(); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp index 5ee81219..3f3c28e2 100644 --- a/sdm/libs/core/fb/hw_primary.cpp +++ b/sdm/libs/core/fb/hw_primary.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2015 - 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 @@ -344,7 +344,7 @@ DisplayError HWPrimary::PowerOff() { return kErrorNone; } -DisplayError HWPrimary::Doze() { +DisplayError HWPrimary::Doze(int *release_fence) { if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) { IOCTL_LOGE(FB_BLANK_NORMAL, device_type_); return kErrorHardware; @@ -353,7 +353,7 @@ DisplayError HWPrimary::Doze() { return kErrorNone; } -DisplayError HWPrimary::DozeSuspend() { +DisplayError HWPrimary::DozeSuspend(int *release_fence) { if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) { IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_); return kErrorHardware; diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h index 69b54452..c6ca5a98 100644 --- a/sdm/libs/core/fb/hw_primary.h +++ b/sdm/libs/core/fb/hw_primary.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +* Copyright (c) 2015-2016, 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 met: @@ -46,8 +46,8 @@ class HWPrimary : public HWDevice { virtual DisplayError SetDisplayAttributes(uint32_t index); virtual DisplayError GetConfigIndex(char *mode, uint32_t *index); virtual DisplayError PowerOff(); - virtual DisplayError Doze(); - virtual DisplayError DozeSuspend(); + virtual DisplayError Doze(int *release_fence); + virtual DisplayError DozeSuspend(int *release_fence); virtual DisplayError Validate(HWLayers *hw_layers); virtual DisplayError Commit(HWLayers *hw_layers); virtual void SetIdleTimeoutMs(uint32_t timeout_ms); diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h index 9bb825e8..483a4df4 100644 --- a/sdm/libs/core/hw_interface.h +++ b/sdm/libs/core/hw_interface.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 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 met: @@ -85,10 +85,10 @@ class HWInterface { virtual DisplayError SetDisplayAttributes(uint32_t index) = 0; virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0; virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0; - virtual DisplayError PowerOn() = 0; + virtual DisplayError PowerOn(int *release_fence) = 0; virtual DisplayError PowerOff() = 0; - virtual DisplayError Doze() = 0; - virtual DisplayError DozeSuspend() = 0; + virtual DisplayError Doze(int *release_fence) = 0; + virtual DisplayError DozeSuspend(int *release_fence) = 0; virtual DisplayError Standby() = 0; virtual DisplayError Validate(HWLayers *hw_layers) = 0; virtual DisplayError Commit(HWLayers *hw_layers) = 0; diff --git a/sdm/libs/hwc2/display_null.cpp b/sdm/libs/hwc2/display_null.cpp index 16f4da66..7e52911c 100644 --- a/sdm/libs/hwc2/display_null.cpp +++ b/sdm/libs/hwc2/display_null.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 @@ -50,7 +50,7 @@ DisplayError DisplayNull::GetDisplayState(DisplayState *state) { return kErrorNone; } -DisplayError DisplayNull::SetDisplayState(DisplayState state) { +DisplayError DisplayNull::SetDisplayState(DisplayState state, int *release_fence) { state_ = state; return kErrorNone; } diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h index f6c0ddaa..bd49a162 100644 --- a/sdm/libs/hwc2/display_null.h +++ b/sdm/libs/hwc2/display_null.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 @@ -44,7 +44,7 @@ class DisplayNull : public DisplayInterface { virtual ~DisplayNull() { } virtual DisplayError Commit(LayerStack *layer_stack); virtual DisplayError GetDisplayState(DisplayState *state); - virtual DisplayError SetDisplayState(DisplayState state); + virtual DisplayError SetDisplayState(DisplayState state, int *release_fence); virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info); virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info); virtual bool IsUnderscanSupported() { return true; } diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp index 03aa7a11..a1d21d8a 100644 --- a/sdm/libs/hwc2/hwc_display.cpp +++ b/sdm/libs/hwc2/hwc_display.cpp @@ -743,9 +743,10 @@ HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { default: return HWC2::Error::BadParameter; } + int release_fence = -1; ATRACE_INT("SetPowerMode ", state); - DisplayError error = display_intf_->SetDisplayState(state); + DisplayError error = display_intf_->SetDisplayState(state, &release_fence); validated_ = false; if (error == kErrorNone) { @@ -759,6 +760,20 @@ HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) { return HWC2::Error::BadParameter; } + if (release_fence >= 0) { + for (auto hwc_layer : layer_set_) { + auto fence = hwc_layer->PopBackReleaseFence(); + auto merged_fence = -1; + if (fence >= 0) { + merged_fence = sync_merge("sync_merge", release_fence, fence); + ::close(fence); + } else { + merged_fence = ::dup(release_fence); + } + hwc_layer->PushBackReleaseFence(merged_fence); + } + ::close(release_fence); + } return HWC2::Error::None; } @@ -1142,7 +1157,7 @@ HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_ for (uint32_t i = 0; i < *out_num_elements; i++, it++) { auto hwc_layer = *it; out_layers[i] = hwc_layer->GetId(); - out_fences[i] = hwc_layer->PopReleaseFence(); + out_fences[i] = hwc_layer->PopFrontReleaseFence(); } } else { *out_num_elements = UINT32(layer_set_.size()); @@ -1313,15 +1328,15 @@ HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) { if (swap_interval_zero_ || layer->flags.single_buffer) { close(layer_buffer->release_fence_fd); } else if (layer->composition != kCompositionGPU) { - hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd); + hwc_layer->PushBackReleaseFence(layer_buffer->release_fence_fd); } else { - hwc_layer->PushReleaseFence(-1); + hwc_layer->PushBackReleaseFence(-1); } } else { // In case of flush, we don't return an error to f/w, so it will get a release fence out of // the hwc_layer's release fence queue. We should push a -1 to preserve release fence // circulation semantics. - hwc_layer->PushReleaseFence(-1); + hwc_layer->PushBackReleaseFence(-1); } layer_buffer->release_fence_fd = -1; diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp index 04595ba5..45ed8919 100644 --- a/sdm/libs/hwc2/hwc_display_external.cpp +++ b/sdm/libs/hwc2/hwc_display_external.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +* Copyright (c) 2014-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 @@ -239,9 +239,12 @@ int HWCDisplayExternal::SetState(bool connected) { DLOGW("Set frame buffer config failed. Error = %d", error); return -1; } - + int release_fence = -1; display_null_.GetDisplayState(&state); - display_intf_->SetDisplayState(state); + display_intf_->SetDisplayState(state, &release_fence); + if (release_fence >= 0) { + ::close(release_fence); + } validated_ = false; SetVsyncEnabled(HWC2::Vsync::Enable); @@ -253,10 +256,14 @@ int HWCDisplayExternal::SetState(bool connected) { } } else { if (!display_null_.IsActive()) { + int release_fence = -1; // Preserve required attributes of HDMI display that surfaceflinger sees. // Restore HDMI attributes when display is reconnected. display_intf_->GetDisplayState(&state); - display_null_.SetDisplayState(state); + display_null_.SetDisplayState(state, &release_fence); + if (release_fence >= 0) { + ::close(release_fence); + } error = display_intf_->GetFrameBufferConfig(&fb_config); if (error != kErrorNone) { diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp index 605b319e..43203970 100644 --- a/sdm/libs/hwc2/hwc_layers.cpp +++ b/sdm/libs/hwc2/hwc_layers.cpp @@ -170,14 +170,14 @@ HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator) layer_ = new Layer(); // Fences are deferred, so the first time this layer is presented, return -1 // TODO(user): Verify that fences are properly obtained on suspend/resume - release_fences_.push(-1); + release_fences_.push_back(-1); } HWCLayer::~HWCLayer() { // Close any fences left for this layer while (!release_fences_.empty()) { ::close(release_fences_.front()); - release_fences_.pop(); + release_fences_.pop_front(); } if (layer_) { if (layer_->input_buffer.acquire_fence_fd >= 0) { @@ -887,14 +887,28 @@ void HWCLayer::SetComposition(const LayerComposition &sdm_composition) { return; } -void HWCLayer::PushReleaseFence(int32_t fence) { - release_fences_.push(fence); + +void HWCLayer::PushBackReleaseFence(int32_t fence) { + release_fences_.push_back(fence); } -int32_t HWCLayer::PopReleaseFence(void) { + +int32_t HWCLayer::PopBackReleaseFence() { if (release_fences_.empty()) return -1; + + auto fence = release_fences_.back(); + release_fences_.pop_back(); + + return fence; +} + +int32_t HWCLayer::PopFrontReleaseFence() { + if (release_fences_.empty()) + return -1; + auto fence = release_fences_.front(); - release_fences_.pop(); + release_fences_.pop_front(); + return fence; } diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h index bbc602e6..92267445 100644 --- a/sdm/libs/hwc2/hwc_layers.h +++ b/sdm/libs/hwc2/hwc_layers.h @@ -32,7 +32,7 @@ #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 #include -#include +#include #include #include "core/buffer_allocator.h" #include "hwc_buffer_allocator.h" @@ -88,8 +88,9 @@ class HWCLayer { int32_t GetLayerDataspace() { return dataspace_; } uint32_t GetGeometryChanges() { return geometry_changes_; } void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; } - void PushReleaseFence(int32_t fence); - int32_t PopReleaseFence(void); + void PushBackReleaseFence(int32_t fence); + int32_t PopBackReleaseFence(void); + int32_t PopFrontReleaseFence(void); bool ValidateAndSetCSC(); bool SupportLocalConversion(ColorPrimaries working_primaries); void ResetValidation() { needs_validate_ = false; } @@ -105,7 +106,7 @@ class HWCLayer { const hwc2_layer_t id_; const hwc2_display_t display_id_; static std::atomic next_id_; - std::queue release_fences_; + std::deque release_fences_; HWCBufferAllocator *buffer_allocator_ = NULL; int32_t dataspace_ = HAL_DATASPACE_UNKNOWN; LayerTransform layer_transform_ = {};