Changeset 68a552f in mainline for uspace/app/terminal/terminal.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/app/terminal/terminal.c

    r2ab8ab3 r68a552f  
    3737#include <adt/list.h>
    3838#include <adt/prodcons.h>
     39#include <as.h>
    3940#include <errno.h>
    4041#include <fbfont/font-8x16.h>
     
    4950#include <task.h>
    5051#include <stdarg.h>
     52#include <stdio.h>
    5153#include <stdlib.h>
    5254#include <str.h>
     
    8688static void term_set_cursor_visibility(con_srv_t *, bool);
    8789static errno_t term_get_event(con_srv_t *, cons_event_t *);
     90static errno_t term_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
     91static void term_unmap(con_srv_t *);
     92static void term_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t,
     93    sysarg_t);
    8894
    8995static con_ops_t con_ops = {
     
    102108        .set_rgb_color = term_set_rgb_color,
    103109        .set_cursor_visibility = term_set_cursor_visibility,
    104         .get_event = term_get_event
     110        .get_event = term_get_event,
     111        .map = term_map,
     112        .unmap = term_unmap,
     113        .update = term_buf_update
    105114};
    106115
     
    344353                                charfield_t *back_field =
    345354                                    chargrid_charfield_at(term->backbuf, x, y);
    346                                 bool update = false;
     355                                bool cupdate = false;
    347356
    348357                                if ((front_field->flags & CHAR_FLAG_DIRTY) ==
     
    350359                                        if (front_field->ch != back_field->ch) {
    351360                                                back_field->ch = front_field->ch;
    352                                                 update = true;
     361                                                cupdate = true;
    353362                                        }
    354363
     
    356365                                            back_field->attrs)) {
    357366                                                back_field->attrs = front_field->attrs;
    358                                                 update = true;
     367                                                cupdate = true;
    359368                                        }
    360369
     
    362371                                }
    363372
    364                                 if (update) {
     373                                if (cupdate) {
    365374                                        term_update_char(term, &pixelmap, sx, sy, x, y);
    366375                                        update = true;
     
    645654}
    646655
     656/** Create shared buffer for efficient rendering.
     657 *
     658 * @param srv Console server
     659 * @param cols Number of columns in buffer
     660 * @param rows Number of rows in buffer
     661 * @param rbuf Place to store pointer to new sharable buffer
     662 *
     663 * @return EOK on sucess or an error code
     664 */
     665static errno_t term_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows,
     666    charfield_t **rbuf)
     667{
     668        terminal_t *term = srv_to_terminal(srv);
     669        void *buf;
     670
     671        fibril_mutex_lock(&term->mtx);
     672
     673        if (term->ubuf != NULL) {
     674                fibril_mutex_unlock(&term->mtx);
     675                return EBUSY;
     676        }
     677
     678        buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t),
     679            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     680        if (buf == AS_MAP_FAILED) {
     681                fibril_mutex_unlock(&term->mtx);
     682                return ENOMEM;
     683        }
     684
     685        term->ucols = cols;
     686        term->urows = rows;
     687        term->ubuf = buf;
     688        fibril_mutex_unlock(&term->mtx);
     689
     690        *rbuf = buf;
     691        return EOK;
     692}
     693
     694/** Delete shared buffer.
     695 *
     696 * @param srv Console server
     697 */
     698static void term_unmap(con_srv_t *srv)
     699{
     700        terminal_t *term = srv_to_terminal(srv);
     701        void *buf;
     702
     703        fibril_mutex_lock(&term->mtx);
     704
     705        buf = term->ubuf;
     706        term->ubuf = NULL;
     707
     708        if (buf != NULL)
     709                as_area_destroy(buf);
     710
     711        fibril_mutex_unlock(&term->mtx);
     712}
     713
     714/** Update area of terminal from shared buffer.
     715 *
     716 * @param srv Console server
     717 * @param c0 Column coordinate of top-left corner (inclusive)
     718 * @param r0 Row coordinate of top-left corner (inclusive)
     719 * @param c1 Column coordinate of bottom-right corner (exclusive)
     720 * @param r1 Row coordinate of bottom-right corner (exclusive)
     721 */
     722static void term_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0,
     723    sysarg_t c1, sysarg_t r1)
     724{
     725        terminal_t *term = srv_to_terminal(srv);
     726        charfield_t *ch;
     727        sysarg_t col, row;
     728
     729        fibril_mutex_lock(&term->mtx);
     730
     731        if (term->ubuf == NULL) {
     732                fibril_mutex_unlock(&term->mtx);
     733                return;
     734        }
     735
     736        /* Make sure we have meaningful coordinates, within bounds */
     737
     738        if (c1 > term->ucols)
     739                c1 = term->ucols;
     740        if (c1 > term->cols)
     741                c1 = term->cols;
     742        if (c0 >= c1) {
     743                fibril_mutex_unlock(&term->mtx);
     744                return;
     745        }
     746        if (r1 > term->urows)
     747                r1 = term->urows;
     748        if (r1 > term->rows)
     749                r1 = term->rows;
     750        if (r0 >= r1) {
     751                fibril_mutex_unlock(&term->mtx);
     752                return;
     753        }
     754
     755        /* Update front buffer from user buffer */
     756
     757        for (row = r0; row < r1; row++) {
     758                for (col = c0; col < c1; col++) {
     759                        ch = chargrid_charfield_at(term->frontbuf, col, row);
     760                        *ch = term->ubuf[row * term->ucols + col];
     761                }
     762        }
     763
     764        fibril_mutex_unlock(&term->mtx);
     765
     766        /* Update terminal */
     767        term_update(term);
     768        gfx_update(term->gc);
     769}
     770
    647771static void deinit_terminal(terminal_t *term)
    648772{
Note: See TracChangeset for help on using the changeset viewer.