Message ID | 1416301209-19596-1-git-send-email-michel@daenzer.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Nov 18, 2014 at 4:00 AM, Michel Dänzer <michel@daenzer.net> wrote: > From: Michel Dänzer <michel.daenzer@amd.com> > > The cursor_set2 hook provides the cursor hotspot position within the > cursor image. When the hotspot position changes, we can adjust the cursor > position such that the hotspot doesn't move on the screen. This prevents > the cursor from appearing to intermittently jump around on the screen > when the position of the hotspot within the cursor image changes. > > Reviewed-by: Alex Deucher <alexander.deucher@amd.com> > Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> Series applied to my -next tree. Thanks! Alex > --- > drivers/gpu/drm/radeon/radeon_cursor.c | 51 ++++++++++++++++++++++++++------- > drivers/gpu/drm/radeon/radeon_display.c | 2 +- > drivers/gpu/drm/radeon/radeon_mode.h | 16 +++++++---- > 3 files changed, 52 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c > index 9630e8d..fd4bddf 100644 > --- a/drivers/gpu/drm/radeon/radeon_cursor.c > +++ b/drivers/gpu/drm/radeon/radeon_cursor.c > @@ -117,8 +117,10 @@ static void radeon_show_cursor(struct drm_crtc *crtc) > } > } > > +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y); > + > static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, > - uint64_t gpu_addr) > + uint64_t gpu_addr, int hot_x, int hot_y) > { > struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > struct radeon_device *rdev = crtc->dev->dev_private; > @@ -142,13 +144,28 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, > /* offset is from DISP(2)_BASE_ADDRESS */ > WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); > } > + > + if (hot_x != radeon_crtc->cursor_hot_x || > + hot_y != radeon_crtc->cursor_hot_y) { > + int x, y; > + > + x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; > + y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; > + > + radeon_cursor_move_locked(crtc, x, y); > + > + radeon_crtc->cursor_hot_x = hot_x; > + radeon_crtc->cursor_hot_y = hot_y; > + } > } > > -int radeon_crtc_cursor_set(struct drm_crtc *crtc, > - struct drm_file *file_priv, > - uint32_t handle, > - uint32_t width, > - uint32_t height) > +int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > + struct drm_file *file_priv, > + uint32_t handle, > + uint32_t width, > + uint32_t height, > + int32_t hot_x, > + int32_t hot_y) > { > struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > struct radeon_device *rdev = crtc->dev->dev_private; > @@ -192,7 +209,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, > radeon_crtc->cursor_height = height; > > radeon_lock_cursor(crtc, true); > - radeon_set_cursor(crtc, obj, gpu_addr); > + radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); > radeon_show_cursor(crtc); > radeon_lock_cursor(crtc, false); > > @@ -215,8 +232,7 @@ fail: > return ret; > } > > -int radeon_crtc_cursor_move(struct drm_crtc *crtc, > - int x, int y) > +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) > { > struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > struct radeon_device *rdev = crtc->dev->dev_private; > @@ -281,7 +297,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, > } > } > > - radeon_lock_cursor(crtc, true); > if (ASIC_IS_DCE4(rdev)) { > WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); > WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); > @@ -308,7 +323,21 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, > WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + > (yorigin * 256))); > } > - radeon_lock_cursor(crtc, false); > + > + radeon_crtc->cursor_x = x; > + radeon_crtc->cursor_y = y; > > return 0; > } > + > +int radeon_crtc_cursor_move(struct drm_crtc *crtc, > + int x, int y) > +{ > + int ret; > + > + radeon_lock_cursor(crtc, true); > + ret = radeon_cursor_move_locked(crtc, x, y); > + radeon_lock_cursor(crtc, false); > + > + return ret; > +} > diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c > index 00ead8c..b233dcd 100644 > --- a/drivers/gpu/drm/radeon/radeon_display.c > +++ b/drivers/gpu/drm/radeon/radeon_display.c > @@ -634,7 +634,7 @@ radeon_crtc_set_config(struct drm_mode_set *set) > return ret; > } > static const struct drm_crtc_funcs radeon_crtc_funcs = { > - .cursor_set = radeon_crtc_cursor_set, > + .cursor_set2 = radeon_crtc_cursor_set2, > .cursor_move = radeon_crtc_cursor_move, > .gamma_set = radeon_crtc_gamma_set, > .set_config = radeon_crtc_set_config, > diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h > index 04db2fd..de1b0d6 100644 > --- a/drivers/gpu/drm/radeon/radeon_mode.h > +++ b/drivers/gpu/drm/radeon/radeon_mode.h > @@ -321,6 +321,10 @@ struct radeon_crtc { > uint32_t crtc_offset; > struct drm_gem_object *cursor_bo; > uint64_t cursor_addr; > + int cursor_x; > + int cursor_y; > + int cursor_hot_x; > + int cursor_hot_y; > int cursor_width; > int cursor_height; > int max_cursor_width; > @@ -802,11 +806,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, > extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, > struct drm_framebuffer *fb, > int x, int y, int atomic); > -extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, > - struct drm_file *file_priv, > - uint32_t handle, > - uint32_t width, > - uint32_t height); > +extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > + struct drm_file *file_priv, > + uint32_t handle, > + uint32_t width, > + uint32_t height, > + int32_t hot_x, > + int32_t hot_y); > extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, > int x, int y); > > -- > 2.1.3 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 9630e8d..fd4bddf 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -117,8 +117,10 @@ static void radeon_show_cursor(struct drm_crtc *crtc) } } +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y); + static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, - uint64_t gpu_addr) + uint64_t gpu_addr, int hot_x, int hot_y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -142,13 +144,28 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, /* offset is from DISP(2)_BASE_ADDRESS */ WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); } + + if (hot_x != radeon_crtc->cursor_hot_x || + hot_y != radeon_crtc->cursor_hot_y) { + int x, y; + + x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; + y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; + + radeon_cursor_move_locked(crtc, x, y); + + radeon_crtc->cursor_hot_x = hot_x; + radeon_crtc->cursor_hot_y = hot_y; + } } -int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height) +int radeon_crtc_cursor_set2(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, + uint32_t height, + int32_t hot_x, + int32_t hot_y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -192,7 +209,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, radeon_crtc->cursor_height = height; radeon_lock_cursor(crtc, true); - radeon_set_cursor(crtc, obj, gpu_addr); + radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); radeon_show_cursor(crtc); radeon_lock_cursor(crtc, false); @@ -215,8 +232,7 @@ fail: return ret; } -int radeon_crtc_cursor_move(struct drm_crtc *crtc, - int x, int y) +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -281,7 +297,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, } } - radeon_lock_cursor(crtc, true); if (ASIC_IS_DCE4(rdev)) { WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); @@ -308,7 +323,21 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + (yorigin * 256))); } - radeon_lock_cursor(crtc, false); + + radeon_crtc->cursor_x = x; + radeon_crtc->cursor_y = y; return 0; } + +int radeon_crtc_cursor_move(struct drm_crtc *crtc, + int x, int y) +{ + int ret; + + radeon_lock_cursor(crtc, true); + ret = radeon_cursor_move_locked(crtc, x, y); + radeon_lock_cursor(crtc, false); + + return ret; +} diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 00ead8c..b233dcd 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -634,7 +634,7 @@ radeon_crtc_set_config(struct drm_mode_set *set) return ret; } static const struct drm_crtc_funcs radeon_crtc_funcs = { - .cursor_set = radeon_crtc_cursor_set, + .cursor_set2 = radeon_crtc_cursor_set2, .cursor_move = radeon_crtc_cursor_move, .gamma_set = radeon_crtc_gamma_set, .set_config = radeon_crtc_set_config, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 04db2fd..de1b0d6 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -321,6 +321,10 @@ struct radeon_crtc { uint32_t crtc_offset; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; + int cursor_x; + int cursor_y; + int cursor_hot_x; + int cursor_hot_y; int cursor_width; int cursor_height; int max_cursor_width; @@ -802,11 +806,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic); -extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height); +extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, + uint32_t height, + int32_t hot_x, + int32_t hot_y); extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);