drm/amd/display: Refine condition for cursor visibility
authorKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Fri, 9 Jul 2021 14:25:44 +0000 (10:25 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Jul 2021 14:07:58 +0000 (10:07 -0400)
[why]
There's a special case where upper plane is not the main plane. If it owns
the cursor, it will be invisible in the majority of the screen.

[How]
The condition for disabling cursor is changed:
- check if upper viewport completely covers current. This was the
previous change that doesn't handle all scenarios with pipe splitting.
- if not, show the cursor only if it's not scaled or no upper pipe.

Reviewed-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h

index 89e6837..35af040 100644 (file)
@@ -3177,21 +3177,40 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
 static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
 {
        struct pipe_ctx *test_pipe;
+       const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
+       const struct rect *r1 = &scl_data->recout, *r2;
+       int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b;
        int cur_layer = pipe_ctx->plane_state->layer_index;
+       bool upper_pipe_exists = false;
+       struct fixed31_32 one = dc_fixpt_from_int(1);
 
        /**
-        * Disable the cursor if there's there's an upper layer active,
-        * assume it's the one owning the cursor
+        * Disable the cursor if there's another pipe above this with a
+        * plane that contains this pipe's viewport to prevent double cursor
+        * and incorrect scaling artifacts.
         */
        for (test_pipe = pipe_ctx->top_pipe; test_pipe;
             test_pipe = test_pipe->top_pipe) {
                if (!test_pipe->plane_state->visible)
                        continue;
 
-               if (test_pipe->plane_state->layer_index < cur_layer)
+               r2 = &test_pipe->plane_res.scl_data.recout;
+               r2_r = r2->x + r2->width;
+               r2_b = r2->y + r2->height;
+
+               if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b)
                        return true;
+
+               if (test_pipe->plane_state->layer_index < cur_layer)
+                       upper_pipe_exists = true;
        }
 
+       // if plane scaled, assume an upper plane can handle cursor if it exists.
+       if (upper_pipe_exists &&
+                       (scl_data->ratios.horz.value != one.value ||
+                       scl_data->ratios.vert.value != one.value))
+               return true;
+
        return false;
 }
 
index cb1a862..df43082 100644 (file)
@@ -2636,6 +2636,7 @@ static inline bool dmub_rb_pop_front(struct dmub_rb *rb)
  */
 static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
 {
+       uint8_t buf[DMUB_RB_CMD_SIZE];
        uint32_t rptr = rb->rptr;
        uint32_t wptr = rb->wrpt;