[PATCH 2/2] drm/udl: implement cursor.

David Herrmann dh.herrmann at gmail.com
Thu Mar 5 03:54:32 PST 2015


Hi

On Thu, Mar 5, 2015 at 3:26 AM, Haixia Shi <hshi at chromium.org> wrote:
> Signed-off-by: Haixia Shi <hshi at chromium.org>
> Reviewed-by: Stéphane Marchesin <marcheu at chromium.org>
> Tested-by: Haixia Shi <hshi at chromium.org>
> ---
>  drivers/gpu/drm/udl/Makefile       |   2 +-
>  drivers/gpu/drm/udl/udl_cursor.c   | 156 +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/udl/udl_cursor.h   |  46 +++++++++++
>  drivers/gpu/drm/udl/udl_drv.h      |   4 +
>  drivers/gpu/drm/udl/udl_fb.c       |  31 ++++----
>  drivers/gpu/drm/udl/udl_gem.c      |   3 +
>  drivers/gpu/drm/udl/udl_main.c     |  10 +++
>  drivers/gpu/drm/udl/udl_modeset.c  |  45 +++++++++++
>  drivers/gpu/drm/udl/udl_transfer.c |  36 ++++++++-
>  9 files changed, 317 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/gpu/drm/udl/udl_cursor.c
>  create mode 100644 drivers/gpu/drm/udl/udl_cursor.h

Why pretend the hw supports cursors if it clearly does not? I don't
see why we cannot leave this to user-space (which can apply
optimizations for software-only devices, which the kernel cannot). And
a commit-message would also be nice.

Thanks
David

> diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile
> index 195bcac..67ccab4 100644
> --- a/drivers/gpu/drm/udl/Makefile
> +++ b/drivers/gpu/drm/udl/Makefile
> @@ -1,6 +1,6 @@
>
>  ccflags-y := -Iinclude/drm
>
> -udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o udl_dmabuf.o
> +udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o udl_dmabuf.o udl_cursor.o
>
>  obj-$(CONFIG_DRM_UDL) := udl.o
> diff --git a/drivers/gpu/drm/udl/udl_cursor.c b/drivers/gpu/drm/udl/udl_cursor.c
> new file mode 100644
> index 0000000..3b38ef5
> --- /dev/null
> +++ b/drivers/gpu/drm/udl/udl_cursor.c
> @@ -0,0 +1,156 @@
> +/*
> + * udl_cursor.c
> + *
> + * Copyright (c) 2015 The Chromium OS Authors
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_crtc_helper.h>
> +
> +#include "udl_cursor.h"
> +#include "udl_drv.h"
> +
> +#define UDL_CURSOR_W 64
> +#define UDL_CURSOR_H 64
> +#define UDL_CURSOR_BUF (UDL_CURSOR_W * UDL_CURSOR_H)
> +
> +/*
> + * UDL drm cursor private structure.
> + */
> +struct udl_cursor {
> +       uint32_t buffer[UDL_CURSOR_BUF];
> +       bool enabled;
> +       int x;
> +       int y;
> +};
> +
> +int udl_cursor_alloc(struct udl_cursor **cursor)
> +{
> +       struct udl_cursor *new_cursor = kzalloc(sizeof(struct udl_cursor),
> +               GFP_KERNEL);
> +       if (!new_cursor)
> +               return -ENOMEM;
> +       *cursor = new_cursor;
> +       return 0;
> +}
> +
> +void udl_cursor_free(struct udl_cursor *cursor)
> +{
> +       BUG_ON(!cursor);
> +       kfree(cursor);
> +}
> +
> +void udl_cursor_copy(struct udl_cursor *dst, struct udl_cursor *src)
> +{
> +       memcpy(dst, src, sizeof(struct udl_cursor));
> +}
> +
> +bool udl_cursor_enabled(struct udl_cursor *cursor)
> +{
> +       return cursor->enabled;
> +}
> +
> +void udl_cursor_get_hline(struct udl_cursor *cursor, int x, int y,
> +               struct udl_cursor_hline *hline)
> +{
> +       if (!cursor || !cursor->enabled ||
> +               x >= cursor->x + UDL_CURSOR_W ||
> +               y < cursor->y || y >= cursor->y + UDL_CURSOR_H) {
> +               hline->buffer = NULL;
> +               return;
> +       }
> +
> +       hline->buffer = &cursor->buffer[UDL_CURSOR_W * (y - cursor->y)];
> +       hline->width = UDL_CURSOR_W;
> +       hline->offset = x - cursor->x;
> +}
> +
> +/*
> + * Return pre-computed cursor blend value defined as:
> + * R: 5 bits (bit 0:4)
> + * G: 6 bits (bit 5:10)
> + * B: 5 bits (bit 11:15)
> + * A: 7 bits (bit 16:22)
> + */
> +static uint32_t cursor_blend_val32(uint32_t pix)
> +{
> +       /* range of alpha_scaled is 0..64 */
> +       uint32_t alpha_scaled = ((pix >> 24) * 65) >> 8;
> +       return ((pix >> 3) & 0x1f) |
> +               ((pix >> 5) & 0x7e0) |
> +               ((pix >> 8) & 0xf800) |
> +               (alpha_scaled << 16);
> +}
> +
> +static int udl_cursor_download(struct udl_cursor *cursor,
> +               struct drm_gem_object *obj)
> +{
> +       struct udl_gem_object *udl_gem_obj = to_udl_bo(obj);
> +       uint32_t *src_ptr, *dst_ptr;
> +       size_t i;
> +
> +       int ret = udl_gem_vmap(udl_gem_obj);
> +       if (ret != 0) {
> +               DRM_ERROR("failed to vmap cursor\n");
> +               return ret;
> +       }
> +
> +       src_ptr = udl_gem_obj->vmapping;
> +       dst_ptr = cursor->buffer;
> +       for (i = 0; i < UDL_CURSOR_BUF; ++i)
> +               dst_ptr[i] = cursor_blend_val32(le32_to_cpu(src_ptr[i]));
> +       return 0;
> +}
> +
> +int udl_cursor_set(struct drm_crtc *crtc, struct drm_file *file,
> +               uint32_t handle, uint32_t width, uint32_t height,
> +               struct udl_cursor *cursor)
> +{
> +       if (handle) {
> +               struct drm_gem_object *obj;
> +               int err;
> +               /* Currently we only support 64x64 cursors */
> +               if (width != UDL_CURSOR_W || height != UDL_CURSOR_H) {
> +                       DRM_ERROR("we currently only support %dx%d cursors\n",
> +                                       UDL_CURSOR_W, UDL_CURSOR_H);
> +                       return -EINVAL;
> +               }
> +               obj = drm_gem_object_lookup(crtc->dev, file, handle);
> +               if (!obj) {
> +                       DRM_ERROR("failed to lookup gem object.\n");
> +                       return -EINVAL;
> +               }
> +               err = udl_cursor_download(cursor, obj);
> +               drm_gem_object_unreference(obj);
> +               if (err != 0) {
> +                       DRM_ERROR("failed to copy cursor.\n");
> +                       return err;
> +               }
> +               cursor->enabled = true;
> +       } else {
> +               cursor->enabled = false;
> +       }
> +
> +       return 0;
> +}
> +
> +int udl_cursor_move(struct drm_crtc *crtc, int x, int y,
> +               struct udl_cursor *cursor)
> +{
> +       cursor->x = x;
> +       cursor->y = y;
> +       return 0;
> +}
> diff --git a/drivers/gpu/drm/udl/udl_cursor.h b/drivers/gpu/drm/udl/udl_cursor.h
> new file mode 100644
> index 0000000..4b83f5b
> --- /dev/null
> +++ b/drivers/gpu/drm/udl/udl_cursor.h
> @@ -0,0 +1,46 @@
> +/*
> + * udl_cursor.h
> + *
> + * Copyright (c) 2015 The Chromium OS Authors
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef _UDL_CURSOR_H_
> +#define _UDL_CURSOR_H_
> +
> +#include <linux/module.h>
> +#include <drm/drmP.h>
> +#include <drm/drm_crtc.h>
> +
> +struct udl_cursor;
> +struct udl_cursor_hline {
> +       uint32_t *buffer;
> +       int width;
> +       int offset;
> +};
> +
> +extern int udl_cursor_alloc(struct udl_cursor **cursor);
> +extern void udl_cursor_free(struct udl_cursor *cursor);
> +extern void udl_cursor_copy(struct udl_cursor *dst, struct udl_cursor *src);
> +extern bool udl_cursor_enabled(struct udl_cursor *cursor);
> +extern void udl_cursor_get_hline(struct udl_cursor *cursor, int x, int y,
> +               struct udl_cursor_hline *hline);
> +extern int udl_cursor_set(struct drm_crtc *crtc, struct drm_file *file,
> +               uint32_t handle, uint32_t width, uint32_t height,
> +               struct udl_cursor *cursor);
> +extern int udl_cursor_move(struct drm_crtc *crtc, int x, int y,
> +               struct udl_cursor *cursor);
> +
> +#endif
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index b1e9fae..9fe4520 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -47,6 +47,8 @@ struct urb_list {
>  };
>
>  struct udl_fbdev;
> +struct udl_cursor;
> +struct udl_cursor_hline;
>  struct udl_flip_queue;
>
>  struct udl_device {
> @@ -60,6 +62,7 @@ struct udl_device {
>         atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
>
>         struct udl_fbdev *fbdev;
> +       struct udl_cursor *cursor;
>         char mode_buf[1024];
>         uint32_t mode_buf_len;
>         atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
> @@ -116,6 +119,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
>  int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
>                      const char *front, char **urb_buf_ptr,
>                      u32 byte_offset, u32 device_byte_offset, u32 byte_width,
> +                    struct udl_cursor_hline *cursor_hline,
>                      int *ident_ptr, int *sent_ptr);
>
>  int udl_dumb_create(struct drm_file *file_priv,
> diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
> index 5fc16ce..a4ccbc1 100644
> --- a/drivers/gpu/drm/udl/udl_fb.c
> +++ b/drivers/gpu/drm/udl/udl_fb.c
> @@ -19,6 +19,7 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_crtc_helper.h>
>  #include "udl_drv.h"
> +#include "udl_cursor.h"
>
>  #include <drm/drm_fb_helper.h>
>
> @@ -116,8 +117,8 @@ static void udlfb_dpy_deferred_io(struct fb_info *info,
>                 if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
>                                      &urb, (char *) info->fix.smem_start,
>                                      &cmd, cur->index << PAGE_SHIFT,
> -                                    cur->index << PAGE_SHIFT,
> -                                    PAGE_SIZE, &bytes_identical, &bytes_sent))
> +                                    cur->index << PAGE_SHIFT, PAGE_SIZE, NULL,
> +                                    &bytes_identical, &bytes_sent))
>                         goto error;
>                 bytes_rendered += PAGE_SIZE;
>         }
> @@ -156,20 +157,15 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
>         int x2, y2;
>         bool store_for_later = false;
>         unsigned long flags;
> +       struct udl_cursor *cursor_copy = NULL;
>
>         if (!fb->active_16)
>                 return 0;
>
> -       if (!fb->obj->vmapping) {
> -               ret = udl_gem_vmap(fb->obj);
> -               if (ret == -ENOMEM) {
> -                       DRM_ERROR("failed to vmap fb\n");
> -                       return 0;
> -               }
> -               if (!fb->obj->vmapping) {
> -                       DRM_ERROR("failed to vmapping\n");
> -                       return 0;
> -               }
> +       ret = udl_gem_vmap(fb->obj);
> +       if (ret) {
> +               DRM_ERROR("failed to vmap fb\n");
> +               return 0;
>         }
>
>         aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
> @@ -220,14 +216,21 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
>                 return 0;
>         cmd = urb->transfer_buffer;
>
> +       mutex_lock(&dev->struct_mutex);
> +       if (udl_cursor_alloc(&cursor_copy) == 0)
> +               udl_cursor_copy(cursor_copy, udl->cursor);
> +       mutex_unlock(&dev->struct_mutex);
> +
>         for (i = y; i <= y2 ; i++) {
>                 const int line_offset = fb->base.pitches[0] * i;
>                 const int byte_offset = line_offset + (x * bpp);
>                 const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
> +               struct udl_cursor_hline cursor_hline;
> +               udl_cursor_get_hline(cursor_copy, x, i, &cursor_hline);
>                 if (udl_render_hline(dev, bpp, &urb,
>                                      (char *) fb->obj->vmapping,
>                                      &cmd, byte_offset, dev_byte_offset,
> -                                    (x2 - x + 1) * bpp,
> +                                    (x2 - x + 1) * bpp, &cursor_hline,
>                                      &bytes_identical, &bytes_sent))
>                         goto error;
>         }
> @@ -241,6 +244,8 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
>                 udl_urb_completion(urb);
>
>  error:
> +       if (cursor_copy)
> +               udl_cursor_free(cursor_copy);
>         atomic_add(bytes_sent, &udl->bytes_sent);
>         atomic_add(bytes_identical, &udl->bytes_identical);
>         atomic_add(width*height*bpp, &udl->bytes_rendered);
> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
> index 2a0a784..9d950ae 100644
> --- a/drivers/gpu/drm/udl/udl_gem.c
> +++ b/drivers/gpu/drm/udl/udl_gem.c
> @@ -160,6 +160,9 @@ int udl_gem_vmap(struct udl_gem_object *obj)
>         int page_count = obj->base.size / PAGE_SIZE;
>         int ret;
>
> +       if (obj->vmapping)
> +               return 0;
> +
>         if (obj->base.import_attach) {
>                 obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
>                 if (!obj->vmapping)
> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> index 33dbfb2..1f86779 100644
> --- a/drivers/gpu/drm/udl/udl_main.c
> +++ b/drivers/gpu/drm/udl/udl_main.c
> @@ -12,6 +12,7 @@
>   */
>  #include <drm/drmP.h>
>  #include "udl_drv.h"
> +#include "udl_cursor.h"
>
>  /* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
>  #define BULK_SIZE 512
> @@ -307,6 +308,10 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags)
>         }
>
>         DRM_DEBUG("\n");
> +       ret = udl_cursor_alloc(&udl->cursor);
> +       if (ret)
> +               goto err;
> +
>         ret = udl_modeset_init(dev);
>         if (ret)
>                 goto err;
> @@ -325,6 +330,8 @@ err_fb:
>  err:
>         if (udl->urbs.count)
>                 udl_free_urb_list(dev);
> +       if (udl->cursor)
> +               udl_cursor_free(udl->cursor);
>         kfree(udl);
>         DRM_ERROR("%d\n", ret);
>         return ret;
> @@ -345,6 +352,9 @@ int udl_driver_unload(struct drm_device *dev)
>         if (udl->urbs.count)
>                 udl_free_urb_list(dev);
>
> +       if (udl->cursor)
> +               udl_cursor_free(udl->cursor);
> +
>         udl_fbdev_cleanup(dev);
>         udl_modeset_cleanup(dev);
>         kfree(udl);
> diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
> index f3804b4..d464286 100644
> --- a/drivers/gpu/drm/udl/udl_modeset.c
> +++ b/drivers/gpu/drm/udl/udl_modeset.c
> @@ -16,6 +16,7 @@
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_plane_helper.h>
>  #include "udl_drv.h"
> +#include "udl_cursor.h"
>
>  /*
>   * All DisplayLink bulk operations start with 0xAF, followed by specific code
> @@ -471,6 +472,48 @@ static void udl_crtc_commit(struct drm_crtc *crtc)
>         udl_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
>  }
>
> +static int udl_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file,
> +               uint32_t handle, uint32_t width, uint32_t height)
> +{
> +       struct drm_device *dev = crtc->dev;
> +       struct udl_device *udl = dev->dev_private;
> +       int ret;
> +
> +       mutex_lock(&dev->struct_mutex);
> +       ret = udl_cursor_set(crtc, file, handle, width, height, udl->cursor);
> +       mutex_unlock(&dev->struct_mutex);
> +
> +       if (ret) {
> +               DRM_ERROR("Failed to set UDL cursor\n");
> +               return ret;
> +       }
> +
> +       return udl_crtc_page_flip(crtc, NULL, NULL, 0);
> +}
> +
> +static int udl_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
> +{
> +       struct drm_device *dev = crtc->dev;
> +       struct udl_device *udl = dev->dev_private;
> +       int ret = 0;
> +
> +       mutex_lock(&dev->struct_mutex);
> +       if (!udl_cursor_enabled(udl->cursor))
> +               goto error;
> +       ret = udl_cursor_move(crtc, x, y, udl->cursor);
> +       if (ret) {
> +               DRM_ERROR("Failed to move UDL cursor\n");
> +               goto error;
> +       }
> +       mutex_unlock(&dev->struct_mutex);
> +
> +       return udl_crtc_page_flip(crtc, NULL, NULL, 0);
> +
> +error:
> +       mutex_unlock(&dev->struct_mutex);
> +       return ret;
> +}
> +
>  static struct drm_crtc_helper_funcs udl_helper_funcs = {
>         .dpms = udl_crtc_dpms,
>         .mode_fixup = udl_crtc_mode_fixup,
> @@ -484,6 +527,8 @@ static const struct drm_crtc_funcs udl_crtc_funcs = {
>         .set_config = drm_crtc_helper_set_config,
>         .destroy = udl_crtc_destroy,
>         .page_flip = udl_crtc_page_flip,
> +       .cursor_set = udl_crtc_cursor_set,
> +       .cursor_move = udl_crtc_cursor_move,
>  };
>
>  static int udl_crtc_init(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
> index 917dcb9..2f59603 100644
> --- a/drivers/gpu/drm/udl/udl_transfer.c
> +++ b/drivers/gpu/drm/udl/udl_transfer.c
> @@ -17,6 +17,7 @@
>
>  #include <drm/drmP.h>
>  #include "udl_drv.h"
> +#include "udl_cursor.h"
>
>  #define MAX_CMD_PIXELS         255
>
> @@ -92,6 +93,19 @@ static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp)
>         return pixel_val16;
>  }
>
> +static inline u16 blend_alpha(const uint16_t pixel_val16, uint32_t blend_val32)
> +{
> +       uint32_t alpha = (blend_val32 >> 16);
> +       uint32_t alpha_inv = 64 - alpha;
> +
> +       return (((pixel_val16 & 0x1f) * alpha_inv +
> +               (blend_val32 & 0x1f) * alpha) >> 6) |
> +               ((((pixel_val16 & 0x7e0) * alpha_inv +
> +               (blend_val32 & 0x7e0) * alpha) >> 6) & 0x7e0) |
> +               ((((pixel_val16 & 0xf800) * alpha_inv +
> +               (blend_val32 & 0xf800) * alpha) >> 6) & 0xf800);
> +}
> +
>  /*
>   * Render a command stream for an encoded horizontal line segment of pixels.
>   *
> @@ -123,12 +137,16 @@ static void udl_compress_hline16(
>         const u8 **pixel_start_ptr,
>         const u8 *const pixel_end,
>         uint32_t *device_address_ptr,
> +       struct udl_cursor_hline *cursor_hline,
>         uint8_t **command_buffer_ptr,
>         const uint8_t *const cmd_buffer_end, int bpp)
>  {
>         const u8 *pixel = *pixel_start_ptr;
>         uint32_t dev_addr  = *device_address_ptr;
>         uint8_t *cmd = *command_buffer_ptr;
> +       const uint32_t *cursor_buf = cursor_hline ? cursor_hline->buffer : NULL;
> +       int cursor_pos = cursor_buf ? cursor_hline->offset : 0;
> +       int cursor_width = cursor_buf ? cursor_hline->width : 0;
>
>         while ((pixel_end > pixel) &&
>                (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
> @@ -158,6 +176,11 @@ static void udl_compress_hline16(
>
>                 prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
>                 pixel_val16 = get_pixel_val16(pixel, bpp);
> +               if (cursor_buf && cursor_pos >= 0 &&
> +                       cursor_pos < cursor_width) {
> +                       pixel_val16 = blend_alpha(pixel_val16,
> +                               cursor_buf[cursor_pos]);
> +               }
>
>                 while (pixel < cmd_pixel_end) {
>                         const u8 *const start = pixel;
> @@ -167,12 +190,19 @@ static void udl_compress_hline16(
>
>                         cmd += 2;
>                         pixel += bpp;
> +                       cursor_pos++;
>
>                         while (pixel < cmd_pixel_end) {
>                                 pixel_val16 = get_pixel_val16(pixel, bpp);
> +                               if (cursor_buf && cursor_pos >= 0 &&
> +                                       cursor_pos < cursor_width) {
> +                                       pixel_val16 = blend_alpha(pixel_val16,
> +                                               cursor_buf[cursor_pos]);
> +                               }
>                                 if (pixel_val16 != repeating_pixel_val16)
>                                         break;
>                                 pixel += bpp;
> +                               cursor_pos++;
>                         }
>
>                         if (unlikely(pixel > start + bpp)) {
> @@ -208,6 +238,8 @@ static void udl_compress_hline16(
>         *command_buffer_ptr = cmd;
>         *pixel_start_ptr = pixel;
>         *device_address_ptr = dev_addr;
> +       if (cursor_buf)
> +               cursor_hline->offset = cursor_pos;
>
>         return;
>  }
> @@ -221,7 +253,7 @@ static void udl_compress_hline16(
>  int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
>                      const char *front, char **urb_buf_ptr,
>                      u32 byte_offset, u32 device_byte_offset,
> -                    u32 byte_width,
> +                    u32 byte_width, struct udl_cursor_hline *cursor_hline,
>                      int *ident_ptr, int *sent_ptr)
>  {
>         const u8 *line_start, *line_end, *next_pixel;
> @@ -239,7 +271,7 @@ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
>         while (next_pixel < line_end) {
>
>                 udl_compress_hline16(&next_pixel,
> -                            line_end, &base16,
> +                            line_end, &base16, cursor_hline,
>                              (u8 **) &cmd, (u8 *) cmd_end, bpp);
>
>                 if (cmd >= cmd_end) {
> --
> 2.2.0.rc0.207.ga3a616c
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list