Merge "sdm: add support to idle timer optimization for DemuraTn"
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index a5b1c1b..330cc49 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -4193,6 +4193,14 @@
int HWCSession::WaitForCommitDoneAsync(hwc2_display_t display, int client_id) {
std::chrono::milliseconds span(5000);
+ if (commit_done_future_.valid()) {
+ std::future_status status = commit_done_future_.wait_for(std::chrono::milliseconds(0));
+ if (status != std::future_status::ready) {
+ // Previous task is stuck. Bail out early.
+ return -ETIMEDOUT;
+ }
+ }
+
commit_done_future_ = std::async([](HWCSession* session, hwc2_display_t display, int client_id) {
return session->WaitForCommitDone(display, client_id);
}, this, display, client_id);
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index ab94535..ac7a6eb 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -370,6 +370,9 @@
LayerRect cwb_full_rect = {}; //!< Same as Output buffer Rect (unaligned).
CwbTapPoint tap_point = CwbTapPoint::kLmTapPoint; //!< Client specified tap point for CWB.
void *dither_info = nullptr; //!< Pointer to the cwb dither setting.
+ bool avoid_refresh = false; //!< Whether to avoid additional refresh for
+ //!< CWB Request, by default refresh occurs
+ //!< for each CWB request to process it.
};
class LayerBufferObject {
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index ee063c0..2161fed 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -4245,6 +4245,49 @@
event_handler_->Refresh();
}
+DisplayError DisplayBase::ValidateCwbRoiWithOutputBuffer(const LayerBuffer &output_buffer,
+ CwbConfig &cwb_config) {
+ if (cwb_config.pu_as_cwb_roi) {
+ uint32_t full_frame_width = cwb_config.cwb_full_rect.right - cwb_config.cwb_full_rect.left;
+ uint32_t full_frame_height = cwb_config.cwb_full_rect.bottom - cwb_config.cwb_full_rect.top;
+ if (full_frame_width > output_buffer.width || full_frame_height > output_buffer.height) {
+ // If output buffer is less than full frame when PU as CWB ROI is enabled, then it
+ // may possible in later validation for partial update that it may fallback to full frame
+ // ROI and then it will cause commit failure due to falling of PU ROI out of CWB ROI
+ // bounds. So, to avoid such case, just disable pu_as_cwb_roi to fallback to full
+ // frame update instead of partial update.
+ cwb_config.pu_as_cwb_roi = false;
+ }
+ }
+
+ if (!cwb_config.pu_as_cwb_roi && !IsValid(cwb_config.cwb_roi)) {
+ // Fall to full frame ROI for invalid CWB ROI, when pu_as_cwb_roi is disabled.
+ cwb_config.cwb_roi = cwb_config.cwb_full_rect;
+ }
+
+ // If CWB ROI doesn't fit into provided output buffer, then it limits the right and bottom
+ // bounds of CWB ROI as per provided output buffer to avoid commit failure due to insufficient
+ // buffer detection for CWB ROI.
+ int32_t roi_width = cwb_config.cwb_roi.right - cwb_config.cwb_roi.left;
+ int32_t roi_height = cwb_config.cwb_roi.bottom - cwb_config.cwb_roi.top;
+ if (roi_width > output_buffer.width || roi_height > output_buffer.height) {
+ DLOGW("Insufficient buffer(%dx%d) provided for cwb roi(%f, %f, %f, %f). "
+ "Thus, falling to buffer fit ROI.", output_buffer.width,
+ output_buffer.height, cwb_config.cwb_roi.left, cwb_config.cwb_roi.top,
+ cwb_config.cwb_roi.right, cwb_config.cwb_roi.bottom);
+
+ if (roi_width > output_buffer.width) {
+ cwb_config.cwb_roi.right = FLOAT(output_buffer.width) + cwb_config.cwb_roi.left;
+ }
+
+ if (roi_height > output_buffer.height) {
+ cwb_config.cwb_roi.bottom = FLOAT(output_buffer.height) + cwb_config.cwb_roi.top;
+ }
+ }
+
+ return kErrorNone;
+}
+
DisplayError DisplayBase::CaptureCwb(const LayerBuffer &output_buffer, const CwbConfig &config) {
ClientLock lock(disp_mutex_);
@@ -4281,6 +4324,12 @@
return error;
}
+ error = ValidateCwbRoiWithOutputBuffer(output_buffer, cwb_config);
+ if (error != kErrorNone) {
+ DLOGW("Buffer validation failed");
+ return error;
+ }
+
error = comp_manager_->CaptureCwb(display_comp_ctx_, output_buffer, cwb_config);
if (error != kErrorNone) {
DLOGE("CWB config failed");
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 13d7c35..3b54419 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -174,6 +174,8 @@
LayerBufferFormat format,
const ColorMetaData &color_metadata);
virtual DisplayError HandleSecureEvent(SecureEvent secure_event, bool *needs_refresh);
+ virtual DisplayError ValidateCwbRoiWithOutputBuffer(const LayerBuffer &output_buffer,
+ CwbConfig &cwb_config);
virtual DisplayError CaptureCwb(const LayerBuffer &output_buffer, const CwbConfig &config);
virtual DisplayError PostHandleSecureEvent(SecureEvent secure_event) {
return kErrorNotSupported;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index c10e23a..3a8d6ee 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -254,6 +254,8 @@
DLOGE("Unable to DeInit DemuraTn on Display %d", display_id_);
}
}
+
+ DeinitCWBBuffer();
}
return DisplayBase::Deinit();
}
@@ -2703,38 +2705,37 @@
return;
}
- if (disable_cwb_idle_fallback_) {
+ if (disable_cwb_idle_fallback_ || cwb_buffer_initialized_) {
return;
}
- BufferInfo output_buffer_info;
// Initialize CWB buffer with display resolution to get full size buffer
// as mixer or fb can init with custom values based on property
- output_buffer_info.buffer_config.width = display_attributes_.x_pixels;
- output_buffer_info.buffer_config.height = display_attributes_.y_pixels;
+ output_buffer_info_.buffer_config.width = display_attributes_.x_pixels;
+ output_buffer_info_.buffer_config.height = display_attributes_.y_pixels;
- output_buffer_info.buffer_config.format = kFormatRGBX8888Ubwc;
- output_buffer_info.buffer_config.buffer_count = 1;
- if (buffer_allocator_->AllocateBuffer(&output_buffer_info) != 0) {
+ output_buffer_info_.buffer_config.format = kFormatRGBX8888Ubwc;
+ output_buffer_info_.buffer_config.buffer_count = 1;
+ if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
DLOGE("Buffer allocation failed");
return;
}
LayerBuffer buffer = {};
- buffer.planes[0].fd = output_buffer_info.alloc_buffer_info.fd;
+ buffer.planes[0].fd = output_buffer_info_.alloc_buffer_info.fd;
buffer.planes[0].offset = 0;
- buffer.planes[0].stride = output_buffer_info.alloc_buffer_info.stride;
- buffer.size = output_buffer_info.alloc_buffer_info.size;
- buffer.handle_id = output_buffer_info.alloc_buffer_info.id;
- buffer.width = output_buffer_info.alloc_buffer_info.aligned_width;
- buffer.height = output_buffer_info.alloc_buffer_info.aligned_height;
- buffer.format = output_buffer_info.alloc_buffer_info.format;
- buffer.unaligned_width = output_buffer_info.buffer_config.width;
- buffer.unaligned_height = output_buffer_info.buffer_config.height;
+ buffer.planes[0].stride = output_buffer_info_.alloc_buffer_info.stride;
+ buffer.size = output_buffer_info_.alloc_buffer_info.size;
+ buffer.handle_id = output_buffer_info_.alloc_buffer_info.id;
+ buffer.width = output_buffer_info_.alloc_buffer_info.aligned_width;
+ buffer.height = output_buffer_info_.alloc_buffer_info.aligned_height;
+ buffer.format = output_buffer_info_.alloc_buffer_info.format;
+ buffer.unaligned_width = output_buffer_info_.buffer_config.width;
+ buffer.unaligned_height = output_buffer_info_.buffer_config.height;
cwb_layer_.composition = kCompositionCWBTarget;
cwb_layer_.input_buffer = buffer;
- cwb_layer_.input_buffer.buffer_id = reinterpret_cast<uint64_t>(output_buffer_info.private_data);
+ cwb_layer_.input_buffer.buffer_id = reinterpret_cast<uint64_t>(output_buffer_info_.private_data);
cwb_layer_.src_rect = {0, 0, FLOAT(cwb_layer_.input_buffer.unaligned_width),
FLOAT(cwb_layer_.input_buffer.unaligned_height)};
cwb_layer_.dst_rect = {0, 0, FLOAT(cwb_layer_.input_buffer.unaligned_width),
@@ -2745,7 +2746,26 @@
return;
}
+void DisplayBuiltIn::DeinitCWBBuffer() {
+ if (!cwb_buffer_initialized_) {
+ return;
+ }
+
+ buffer_allocator_->FreeBuffer(&output_buffer_info_);
+ cwb_layer_ = {};
+ cwb_buffer_initialized_ = false;
+}
+
void DisplayBuiltIn::AppendCWBLayer(LayerStack *layer_stack) {
+ if (cwb_buffer_initialized_ &&
+ (cwb_layer_.input_buffer.unaligned_width < display_attributes_.x_pixels ||
+ cwb_layer_.input_buffer.unaligned_height < display_attributes_.y_pixels)) {
+ DLOGI("Resetting CWB layer due to insufficient buffer size(%dx%d) compare to output(%dx%d).",
+ cwb_layer_.input_buffer.unaligned_width, cwb_layer_.input_buffer.unaligned_height,
+ display_attributes_.x_pixels, display_attributes_.y_pixels);
+ DeinitCWBBuffer();
+ }
+
if (!cwb_buffer_initialized_) {
// If CWB buffer is not initialized, then it must be initialized for video mode
InitCWBBuffer();
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index e172547..d4c7e88 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -182,6 +182,7 @@
DisplayError SetAlternateDisplayConfig(uint32_t *alt_config) override;
DisplayError PostHandleSecureEvent(SecureEvent secure_event) override;
void InitCWBBuffer();
+ void DeinitCWBBuffer();
void AppendCWBLayer(LayerStack *layer_stack);
uint32_t GetUpdatingAppLayersCount(LayerStack *layer_stack);
DisplayError ChangeFps();
@@ -307,6 +308,7 @@
Layer cwb_layer_ = {};
bool lower_fps_ = false;
bool cwb_buffer_initialized_ = false;
+ BufferInfo output_buffer_info_ = {};
};
} // namespace sdm