*/
static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
struct dc_stream_state *stream,
+ struct dc_surface_update *srf_updates,
int surface_count,
bool *is_plane_addition)
{
*is_plane_addition = true;
}
}
+ if (dc->config.enable_windowed_mpo_odm) {
+ const struct rect *guaranteed_viewport = &stream->src;
+ const struct rect *surface_src, *surface_dst;
+ bool are_cur_planes_guaranteed = true;
+ bool are_new_planes_guaranteed = true;
+
+ for (i = 0; i < cur_stream_status->plane_count; i++) {
+ surface_src = &cur_stream_status->plane_states[i]->src_rect;
+ surface_dst = &cur_stream_status->plane_states[i]->dst_rect;
+ if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) ||
+ (surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width))
+ are_cur_planes_guaranteed = false;
+ }
+
+ for (i = 0; i < surface_count; i++) {
+ if (srf_updates[i].scaling_info) {
+ surface_src = &srf_updates[i].scaling_info->src_rect;
+ surface_dst = &srf_updates[i].scaling_info->dst_rect;
+ } else {
+ surface_src = &srf_updates[i].surface->src_rect;
+ surface_dst = &srf_updates[i].surface->dst_rect;
+ }
+ if ((surface_src->height > surface_dst->height && surface_src->height > guaranteed_viewport->height) ||
+ (surface_src->width > surface_dst->width && surface_src->width > guaranteed_viewport->width))
+ are_new_planes_guaranteed = false;
+ }
+
+ if (are_cur_planes_guaranteed && !are_new_planes_guaranteed) {
+ force_minimal_pipe_splitting = true;
+ *is_plane_addition = true;
+ } else if (!are_cur_planes_guaranteed && are_new_planes_guaranteed) {
+ force_minimal_pipe_splitting = true;
+ }
+ }
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes(
dc,
stream,
+ srf_updates,
surface_count,
&is_plane_addition);
{
struct dc_stream_state *stream = context->streams[0];
struct pipe_slice_table slice_table;
+ struct dc_plane_state *plane;
+ struct rect guaranteed_viewport;
int i;
/*
for (i = 0; i < slice_table.odm_combine_count; i++)
if (slice_table.odm_combines[i].slice_count > 1)
return false;
+
+ /* up to here we know that a plane with viewport equal to stream
+ * src can be validated with single DPP pipe. Therefore any
+ * planes with smaller or equal viewport is guaranteed to work
+ * regardless of its position and scaling ratio. Also we know
+ * any plane without downscale ratio greater than 1 should also
+ * work. Up until DCN3x we still have software limitation that
+ * doesn't implement a smooth transition between ODM combine and
+ * MPC combine during plane resizing when we are crossing ODM
+ * capability boundary. So we are adding this guaranteed
+ * viewport condition to limit ODM power optimization support
+ * for only the planes within the guaranteed viewport size. Such
+ * planes can be supported with ODM power optimization without
+ * ever the need to transition to MPC combine in any scaling
+ * ratios and positions. Therefore we cover the software
+ * limitation of this transition sequence.
+ */
+ guaranteed_viewport = stream->src;
+ for (i = 0; i < context->stream_status[0].plane_count; i++) {
+ plane = context->stream_status[0].plane_states[i];
+
+ if ((plane->src_rect.height > plane->dst_rect.height && plane->src_rect.height > guaranteed_viewport.height) ||
+ (plane->src_rect.width > plane->dst_rect.width && plane->src_rect.width > guaranteed_viewport.width))
+ return false;
+ }
} else {
/*
* the new ODM power optimization feature reduces software