On Tue, Nov 18, 2014 at 4:00 AM, Michel Dänzer <michel at daenzer.net> wrote: > From: Michel Dänzer <michel.daenzer at 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 at amd.com> > Signed-off-by: Michel Dänzer <michel.daenzer at 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 at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel