sdm: drm: Add support for partial update
Add support for partial update
Change-Id: I29b6c3cdb71e6a26ab21679494f04ced5052a1e3
CRs-fixed: 1114808
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index d41181f..13a8620 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -154,6 +154,13 @@
*/
CRTC_SET_POST_PROC,
/*
+ * Op: Sets CRTC ROIs.
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - number of ROIs
+ * DRMRect * - Array of CRTC ROIs
+ */
+ CRTC_SET_ROI,
+ /*
* Op: Returns retire fence for this commit. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - Connector ID
@@ -178,6 +185,13 @@
* uint32_t - Power Mode
*/
CONNECTOR_SET_POWER_MODE,
+ /*
+ * Op: Sets panel ROIs.
+ * Arg: uint32_t - Connector ID
+ * uint32_t - number of ROIs
+ * DRMRect * - Array of Connector ROIs
+ */
+ CONNECTOR_SET_ROI,
};
enum struct DRMRotation {
@@ -298,6 +312,15 @@
std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
// Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
uint32_t max_linewidth;
+ // Valid only if mode is command
+ int num_roi;
+ int xstart;
+ int ystart;
+ int walign;
+ int halign;
+ int wmin;
+ int hmin;
+ bool roi_merge;
};
/* Identifier token for a display */
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 8052613..288c20c 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -429,24 +429,22 @@
display_attributes_.x_pixels / 2;
}
- hw_panel_info_.partial_update = 0;
- hw_panel_info_.left_align = 0;
- hw_panel_info_.width_align = 0;
- hw_panel_info_.top_align = 0;
- hw_panel_info_.height_align = 0;
- hw_panel_info_.min_roi_width = 0;
- hw_panel_info_.min_roi_height = 0;
- hw_panel_info_.needs_roi_merge = 0;
+ hw_panel_info_.partial_update = connector_info_.num_roi;
+ hw_panel_info_.left_roi_count = UINT32(connector_info_.num_roi);
+ hw_panel_info_.right_roi_count = UINT32(connector_info_.num_roi);
+ hw_panel_info_.left_align = connector_info_.xstart;
+ hw_panel_info_.top_align = connector_info_.ystart;
+ hw_panel_info_.width_align = connector_info_.walign;
+ hw_panel_info_.height_align = connector_info_.halign;
+ hw_panel_info_.min_roi_width = connector_info_.wmin;
+ hw_panel_info_.min_roi_height = connector_info_.hmin;
+ hw_panel_info_.needs_roi_merge = connector_info_.roi_merge;
hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
hw_panel_info_.min_fps = 60;
hw_panel_info_.max_fps = 60;
hw_panel_info_.is_primary_panel = connector_info_.is_primary;
hw_panel_info_.is_pluggable = 0;
- if (!default_mode_) {
- hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE);
- }
-
GetHWDisplayPortAndMode();
GetHWPanelMaxBrightness();
@@ -601,6 +599,34 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
+ // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
+ if (hw_panel_info_.partial_update) {
+ const int kNumMaxROIs = 4;
+ DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
+ DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_.x_pixels,
+ display_attributes_.y_pixels}};
+
+ for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
+ auto &roi = hw_layer_info.left_frame_roi.at(i);
+ // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
+ crtc_rects[i].left = UINT32(roi.left);
+ crtc_rects[i].right = UINT32(roi.right);
+ crtc_rects[i].top = UINT32(roi.top);
+ crtc_rects[i].bottom = UINT32(roi.bottom);
+ // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
+ conn_rects[i].left = UINT32(roi.left);
+ conn_rects[i].right = UINT32(roi.right);
+ conn_rects[i].top = UINT32(roi.top);
+ conn_rects[i].bottom = UINT32(roi.bottom);
+ }
+
+ uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
+ num_rects, crtc_rects);
+ drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
+ num_rects, conn_rects);
+ }
+
for (uint32_t i = 0; i < hw_layer_count; i++) {
Layer &layer = hw_layer_info.hw_layers.at(i);
LayerBuffer *input_buffer = &layer.input_buffer;