1
0
Fork 0

drm_hwcomposer: Use single VSyncWorker per display

Composer 2.4 will require another vsyncworker callback to send
VsyncPeriodTimingChanged event. It makes sence to use single
VSyncWorker and flags to indicate which actions are required
to perform. This should also save some runtime resources.

Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
This commit is contained in:
Roman Stratiienko 2022-01-20 11:50:54 +02:00
parent 3dacd47d13
commit 099c31156d
4 changed files with 77 additions and 61 deletions

View file

@ -203,4 +203,21 @@ void DrmHwcTwo::SendHotplugEventToClient(hwc2_display_t displayid,
}
}
void DrmHwcTwo::SendVsyncEventToClient(
hwc2_display_t displayid, int64_t timestamp,
[[maybe_unused]] uint32_t vsync_period) const {
/* vsync callback */
#if PLATFORM_SDK_VERSION > 29
if (vsync_2_4_callback_.first != nullptr &&
vsync_2_4_callback_.second != nullptr) {
vsync_2_4_callback_.first(vsync_2_4_callback_.second, displayid, timestamp,
vsync_period);
} else
#endif
if (vsync_callback_.first != nullptr &&
vsync_callback_.second != nullptr) {
vsync_callback_.first(vsync_callback_.second, displayid, timestamp);
}
}
} // namespace android

View file

@ -64,6 +64,9 @@ class DrmHwcTwo : public PipelineToFrontendBindingInterface {
bool UnbindDisplay(DrmDisplayPipeline *pipeline) override;
void FinalizeDisplayBinding() override;
void SendVsyncEventToClient(hwc2_display_t displayid, int64_t timestamp,
uint32_t vsync_period) const;
private:
void SendHotplugEventToClient(hwc2_display_t displayid, bool connected);

View file

@ -115,8 +115,6 @@ HwcDisplay::~HwcDisplay() {
auto &main_lock = hwc2_->GetResMan().GetMainLock();
/* Unlock to allow pending vsync callbacks to finish */
main_lock.unlock();
flattening_vsync_worker_.VSyncControl(false);
flattening_vsync_worker_.Exit();
vsync_worker_.VSyncControl(false);
vsync_worker_.Exit();
main_lock.lock();
@ -135,37 +133,16 @@ void HwcDisplay::ClearDisplay() {
HWC2::Error HwcDisplay::Init() {
int ret = vsync_worker_.Init(pipeline_, [this](int64_t timestamp) {
const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
/* vsync callback */
#if PLATFORM_SDK_VERSION > 29
if (hwc2_->vsync_2_4_callback_.first != nullptr &&
hwc2_->vsync_2_4_callback_.second != nullptr) {
hwc2_vsync_period_t period_ns{};
if (vsync_event_en_) {
uint32_t period_ns{};
GetDisplayVsyncPeriod(&period_ns);
hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
handle_, timestamp, period_ns);
} else
#endif
if (hwc2_->vsync_callback_.first != nullptr &&
hwc2_->vsync_callback_.second != nullptr) {
hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
timestamp);
hwc2_->SendVsyncEventToClient(handle_, timestamp, period_ns);
}
});
if (ret) {
ALOGE("Failed to create event worker for d=%d %d\n", int(handle_), ret);
return HWC2::Error::BadDisplay;
}
ret = flattening_vsync_worker_.Init(pipeline_, [this](int64_t /*timestamp*/) {
const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
/* Frontend flattening */
if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
--flattenning_state_ ==
ClientFlattenningState::ClientRefreshRequested &&
hwc2_->refresh_callback_.first != nullptr &&
hwc2_->refresh_callback_.second != nullptr) {
hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
flattening_vsync_worker_.VSyncControl(false);
if (vsync_flattening_en_) {
ProcessFlatenningVsyncInternal();
}
if (!vsync_event_en_ && !vsync_flattening_en_) {
vsync_worker_.VSyncControl(false);
}
});
if (ret) {
@ -700,7 +677,10 @@ HWC2::Error HwcDisplay::SetPowerMode(int32_t mode_in) {
}
HWC2::Error HwcDisplay::SetVsyncEnabled(int32_t enabled) {
vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
vsync_event_en_ = HWC2_VSYNC_ENABLE == enabled;
if (vsync_event_en_) {
vsync_worker_.VSyncControl(true);
}
return HWC2::Error::None;
}
@ -729,6 +709,13 @@ std::vector<HwcLayer *> HwcDisplay::GetOrderLayersByZPos() {
return ordered_layers;
}
HWC2::Error HwcDisplay::GetDisplayVsyncPeriod(
uint32_t *outVsyncPeriod /* ns */) {
return GetDisplayAttribute(configs_.active_config_id,
HWC2_ATTRIBUTE_VSYNC_PERIOD,
(int32_t *)(outVsyncPeriod));
}
#if PLATFORM_SDK_VERSION > 29
HWC2::Error HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
if (IsInHeadlessMode()) {
@ -748,13 +735,6 @@ HWC2::Error HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
return HWC2::Error::None;
}
HWC2::Error HwcDisplay::GetDisplayVsyncPeriod(
hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
return GetDisplayAttribute(configs_.active_config_id,
HWC2_ATTRIBUTE_VSYNC_PERIOD,
(int32_t *)(outVsyncPeriod));
}
HWC2::Error HwcDisplay::SetActiveConfigWithConstraints(
hwc2_config_t /*config*/,
hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
@ -887,4 +867,37 @@ void HwcDisplay::set_backend(std::unique_ptr<Backend> backend) {
backend_ = std::move(backend);
}
/* returns true if composition should be sent to client */
bool HwcDisplay::ProcessClientFlatteningState(bool skip) {
int flattenning_state = flattenning_state_;
if (flattenning_state == ClientFlattenningState::Disabled) {
return false;
}
if (skip) {
flattenning_state_ = ClientFlattenningState::NotRequired;
return false;
}
if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
flattenning_state_ = ClientFlattenningState::Flattened;
return true;
}
vsync_flattening_en_ = true;
vsync_worker_.VSyncControl(true);
flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
return false;
}
void HwcDisplay::ProcessFlatenningVsyncInternal() {
if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
--flattenning_state_ == ClientFlattenningState::ClientRefreshRequested &&
hwc2_->refresh_callback_.first != nullptr &&
hwc2_->refresh_callback_.second != nullptr) {
hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
vsync_flattening_en_ = false;
}
}
} // namespace android

View file

@ -83,7 +83,6 @@ class HwcDisplay {
#endif
#if PLATFORM_SDK_VERSION > 29
HWC2::Error GetDisplayConnectionType(uint32_t *outType);
HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *outVsyncPeriod);
HWC2::Error SetActiveConfigWithConstraints(
hwc2_config_t config,
@ -96,6 +95,7 @@ class HwcDisplay {
HWC2::Error SetContentType(int32_t contentType);
#endif
HWC2::Error GetDisplayVsyncPeriod(uint32_t *outVsyncPeriod);
HWC2::Error GetDozeSupport(int32_t *support);
HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
@ -165,26 +165,8 @@ class HwcDisplay {
}
/* returns true if composition should be sent to client */
bool ProcessClientFlatteningState(bool skip) {
int flattenning_state = flattenning_state_;
if (flattenning_state == ClientFlattenningState::Disabled) {
return false;
}
if (skip) {
flattenning_state_ = ClientFlattenningState::NotRequired;
return false;
}
if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
flattenning_state_ = ClientFlattenningState::Flattened;
return true;
}
flattening_vsync_worker_.VSyncControl(true);
flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
return false;
}
bool ProcessClientFlatteningState(bool skip);
void ProcessFlatenningVsyncInternal();
/* Headless mode required to keep SurfaceFlinger alive when all display are
* disconnected, Without headless mode Android will continuously crash.
@ -206,7 +188,6 @@ class HwcDisplay {
};
std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
VSyncWorker flattening_vsync_worker_;
constexpr static size_t MATRIX_SIZE = 16;
@ -221,6 +202,8 @@ class HwcDisplay {
std::unique_ptr<Backend> backend_;
VSyncWorker vsync_worker_;
bool vsync_event_en_{};
bool vsync_flattening_en_{};
const hwc2_display_t handle_;
HWC2::DisplayType type_;