Changeset 68a552f in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2021-02-22T19:52:08Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
26853ebc
Parents:
2ab8ab3
Message:

Efficient way of rendering to the console via shared buffer

Makes congfx reasonably fast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/console/console.c

    r2ab8ab3 r68a552f  
    11/*
     2 * Copyright (c) 2021 Jiri Svoboda
    23 * Copyright (c) 2011 Martin Decky
    34 * All rights reserved.
     
    7980        console_caps_t ccaps;  /**< Console capabilities */
    8081
     82        sysarg_t ucols;         /**< Number of columns in user buffer */
     83        sysarg_t urows;         /**< Number of rows in user buffer */
     84        charfield_t *ubuf;      /**< User buffer */
     85
    8186        chargrid_t *frontbuf;    /**< Front buffer */
    8287        frontbuf_handle_t fbid;  /**< Front buffer handle */
     
    135140static void cons_set_cursor_visibility(con_srv_t *, bool);
    136141static errno_t cons_get_event(con_srv_t *, cons_event_t *);
     142static errno_t cons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
     143static void cons_unmap(con_srv_t *);
     144static void cons_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t,
     145    sysarg_t);
    137146
    138147static con_ops_t con_ops = {
     
    151160        .set_rgb_color = cons_set_rgb_color,
    152161        .set_cursor_visibility = cons_set_cursor_visibility,
    153         .get_event = cons_get_event
     162        .get_event = cons_get_event,
     163        .map = cons_map,
     164        .unmap = cons_unmap,
     165        .update = cons_buf_update
    154166};
    155167
     
    508520}
    509521
     522/** Create shared buffer for efficient rendering.
     523 *
     524 * @param srv Console server
     525 * @param cols Number of columns in buffer
     526 * @param rows Number of rows in buffer
     527 * @param rbuf Place to store pointer to new sharable buffer
     528 *
     529 * @return EOK on sucess or an error code
     530 */
     531static errno_t cons_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows,
     532    charfield_t **rbuf)
     533{
     534        console_t *cons = srv_to_console(srv);
     535        void *buf;
     536
     537        fibril_mutex_lock(&cons->mtx);
     538
     539        if (cons->ubuf != NULL) {
     540                fibril_mutex_unlock(&cons->mtx);
     541                return EBUSY;
     542        }
     543
     544        buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t),
     545            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     546        if (buf == AS_MAP_FAILED) {
     547                fibril_mutex_unlock(&cons->mtx);
     548                return ENOMEM;
     549        }
     550
     551        cons->ucols = cols;
     552        cons->urows = rows;
     553        cons->ubuf = buf;
     554        fibril_mutex_unlock(&cons->mtx);
     555
     556        *rbuf = buf;
     557        return EOK;
     558}
     559
     560/** Delete shared buffer.
     561 *
     562 * @param srv Console server
     563 */
     564static void cons_unmap(con_srv_t *srv)
     565{
     566        console_t *cons = srv_to_console(srv);
     567        void *buf;
     568
     569        fibril_mutex_lock(&cons->mtx);
     570
     571        buf = cons->ubuf;
     572        cons->ubuf = NULL;
     573
     574        if (buf != NULL)
     575                as_area_destroy(buf);
     576
     577        fibril_mutex_unlock(&cons->mtx);
     578}
     579
     580/** Update area of console from shared buffer.
     581 *
     582 * @param srv Console server
     583 * @param c0 Column coordinate of top-left corner (inclusive)
     584 * @param r0 Row coordinate of top-left corner (inclusive)
     585 * @param c1 Column coordinate of bottom-right corner (exclusive)
     586 * @param r1 Row coordinate of bottom-right corner (exclusive)
     587 */
     588static void cons_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0,
     589    sysarg_t c1, sysarg_t r1)
     590{
     591        console_t *cons = srv_to_console(srv);
     592        charfield_t *ch;
     593        sysarg_t col, row;
     594
     595        fibril_mutex_lock(&cons->mtx);
     596
     597        if (cons->ubuf == NULL) {
     598                fibril_mutex_unlock(&cons->mtx);
     599                return;
     600        }
     601
     602        /* Make sure we have meaningful coordinates, within bounds */
     603
     604        if (c1 > cons->ucols)
     605                c1 = cons->ucols;
     606        if (c1 > cons->cols)
     607                c1 = cons->cols;
     608        if (c0 >= c1) {
     609                fibril_mutex_unlock(&cons->mtx);
     610                return;
     611        }
     612        if (r1 > cons->urows)
     613                r1 = cons->urows;
     614        if (r1 > cons->rows)
     615                r1 = cons->rows;
     616        if (r0 >= r1) {
     617                fibril_mutex_unlock(&cons->mtx);
     618                return;
     619        }
     620
     621        /* Update front buffer from user buffer */
     622
     623        for (row = r0; row < r1; row++) {
     624                for (col = c0; col < c1; col++) {
     625                        ch = chargrid_charfield_at(cons->frontbuf, col, row);
     626                        *ch = cons->ubuf[row * cons->ucols + col];
     627                }
     628        }
     629
     630        fibril_mutex_unlock(&cons->mtx);
     631
     632        /* Update console */
     633        cons_update(cons);
     634}
     635
    510636static void client_connection(ipc_call_t *icall, void *arg)
    511637{
Note: See TracChangeset for help on using the changeset viewer.