Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 62018a0 in mainline


Ignore:
Timestamp:
2020-06-24T12:32:04Z (12 days ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
8630748
Parents:
2fc1e6d
git-author:
Jiri Svoboda <jiri@…> (2020-06-23 18:31:47)
git-committer:
Jiri Svoboda <jiri@…> (2020-06-24 12:32:04)
Message:

Properly clip cursor when repainting a part of the display

Not doing so was causing excessively large update rectangles, increasing
CPU usage and display artifacts.

Location:
uspace/srv/hid/display
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/cursor.c

    r2fc1e6d r62018a0  
    8989 * @param cursor Cusor to paint
    9090 * @param pos Position to paint at
     91 * @param clip Clipping rectangle or @c NULL
    9192 * @return EOK on success or an error code
    9293 */
    93 errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos)
     94errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos,
     95    gfx_rect_t *clip)
    9496{
    9597        gfx_context_t *dgc;
     
    98100        gfx_bitmap_alloc_t alloc;
    99101        gfx_coord2_t dims;
     102        gfx_rect_t sclip;
     103        gfx_rect_t srect;
    100104        pixelmap_t pixelmap;
    101105        pixel_t pixel;
     
    150154        }
    151155
    152         return gfx_bitmap_render(cursor->bitmap, NULL, pos);
     156        /* Determine source rectangle */
     157        if (clip == NULL) {
     158                srect = cursor->rect;
     159        } else {
     160                gfx_rect_rtranslate(pos, clip, &sclip);
     161                gfx_rect_clip(&cursor->rect, &sclip, &srect);
     162        }
     163
     164        if (!gfx_rect_is_empty(&srect)) {
     165                rc = gfx_bitmap_render(cursor->bitmap, &srect, pos);
     166                if (rc != EOK)
     167                        return rc;
     168        }
     169
     170        return EOK;
    153171error:
    154172        return rc;
  • uspace/srv/hid/display/cursor.h

    r2fc1e6d r62018a0  
    4646    ds_cursor_t **);
    4747extern void ds_cursor_destroy(ds_cursor_t *);
    48 extern errno_t ds_cursor_paint(ds_cursor_t *, gfx_coord2_t *);
     48extern errno_t ds_cursor_paint(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
    4949extern void ds_cursor_get_rect(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
    5050
  • uspace/srv/hid/display/seat.c

    r2fc1e6d r62018a0  
    420420
    421421        cursor = ds_seat_get_cursor(seat);
    422         (void) rect; // XXX ds_cursor_paint should accept a clipping rectangle
    423         return ds_cursor_paint(cursor, &seat->pntpos);
     422        return ds_cursor_paint(cursor, &seat->pntpos, rect);
    424423}
    425424
  • uspace/srv/hid/display/test/cursor.c

    r2fc1e6d r62018a0  
    8282}
    8383
    84 /** Test ds_cursor_paint(). */
    85 PCUT_TEST(cursor_paint)
     84/** Test ds_cursor_paint() renders the cursor. */
     85PCUT_TEST(cursor_paint_render)
    8686{
    8787        gfx_context_t *gc;
     
    113113        pos.x = 0;
    114114        pos.y = 0;
    115         ds_cursor_paint(cursor, &pos);
     115        ds_cursor_paint(cursor, &pos, NULL);
    116116
    117117        PCUT_ASSERT_TRUE(resp.render_called);
     118
     119        ds_cursor_destroy(cursor);
     120        ds_display_destroy(disp);
     121}
     122
     123/** Test ds_cursor_paint() optimizes out rendering using clipping rectangle. */
     124PCUT_TEST(cursor_paint_norender)
     125{
     126        gfx_context_t *gc;
     127        ds_display_t *disp;
     128        ds_cursor_t *cursor;
     129        ds_ddev_t *ddev;
     130        ddev_info_t ddinfo;
     131        gfx_coord2_t pos;
     132        gfx_rect_t clip;
     133        test_response_t resp;
     134        errno_t rc;
     135
     136        rc = gfx_context_new(&dummy_ops, &resp, &gc);
     137        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     138
     139        rc = ds_display_create(gc, df_none, &disp);
     140        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     141
     142        ddev_info_init(&ddinfo);
     143
     144        rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
     145        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     146
     147        rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
     148            ds_cursimg[dcurs_arrow].image, &cursor);
     149        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     150
     151        resp.render_called = false;
     152
     153        /*
     154         * Clipping rectangle not intersecting the area where cursor is to
     155         * be rendered
     156         */
     157        clip.p0.x = 100;
     158        clip.p0.y = 100;
     159        clip.p1.x = 150;
     160        clip.p1.y = 150;
     161
     162        pos.x = 0;
     163        pos.y = 0;
     164        ds_cursor_paint(cursor, &pos, &clip);
     165
     166        /* Rendering should have been optimized out */
     167        PCUT_ASSERT_FALSE(resp.render_called);
    118168
    119169        ds_cursor_destroy(cursor);
Note: See TracChangeset for help on using the changeset viewer.