Changeset dbef30f in mainline for uspace/srv/hid/display/window.c


Ignore:
Timestamp:
2020-06-03T16:36:35Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
978c9bc5
Parents:
f8375f7
Message:

Use memory GC to render window in display server

File:
1 edited

Legend:

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

    rf8375f7 rdbef30f  
    4242#include <io/pixelmap.h>
    4343#include <macros.h>
     44#include <memgfx/memgc.h>
    4445#include <stdlib.h>
    4546#include "client.h"
     
    4849#include "window.h"
    4950
    50 static errno_t ds_window_set_color(void *, gfx_color_t *);
    51 static errno_t ds_window_fill_rect(void *, gfx_rect_t *);
    52 static errno_t ds_window_bitmap_create(void *, gfx_bitmap_params_t *,
    53     gfx_bitmap_alloc_t *, void **);
    54 static errno_t ds_window_bitmap_destroy(void *);
    55 static errno_t ds_window_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    56 static errno_t ds_window_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    57 
    58 gfx_context_ops_t ds_window_ops = {
    59         .set_color = ds_window_set_color,
    60         .fill_rect = ds_window_fill_rect,
    61         .bitmap_create = ds_window_bitmap_create,
    62         .bitmap_destroy = ds_window_bitmap_destroy,
    63         .bitmap_render = ds_window_bitmap_render,
    64         .bitmap_get_alloc = ds_window_bitmap_get_alloc
    65 };
    66 
    67 /** Set color on window GC.
    68  *
    69  * Set drawing color on window GC.
    70  *
    71  * @param arg Console GC
    72  * @param color Color
    73  *
    74  * @return EOK on success or an error code
    75  */
    76 static errno_t ds_window_set_color(void *arg, gfx_color_t *color)
    77 {
    78         ds_window_t *wnd = (ds_window_t *) arg;
    79         uint16_t r, g, b;
    80 
    81         log_msg(LOG_DEFAULT, LVL_NOTE, "gc_set_color gc=%p",
    82             ds_display_get_gc(wnd->display));
    83 
    84         gfx_color_get_rgb_i16(color, &r, &g, &b);
    85         wnd->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
    86 
    87         return gfx_set_color(ds_display_get_gc(wnd->display), color);
    88 }
    89 
    90 /** Fill rectangle on window GC.
    91  *
    92  * @param arg Window GC
    93  * @param rect Rectangle
    94  *
    95  * @return EOK on success or an error code
    96  */
    97 static errno_t ds_window_fill_rect(void *arg, gfx_rect_t *rect)
    98 {
    99         ds_window_t *wnd = (ds_window_t *) arg;
    100         gfx_rect_t crect;
    101         gfx_rect_t drect;
    102         gfx_coord_t x, y;
    103 
    104         log_msg(LOG_DEFAULT, LVL_NOTE, "gc_fill_rect");
    105 
    106         gfx_rect_clip(rect, &wnd->rect, &crect);
    107         gfx_rect_translate(&wnd->dpos, &crect, &drect);
    108 
    109         /* Render into the backbuffer */
    110         for (y = crect.p0.y; y < crect.p1.y; y++) {
    111                 for (x = crect.p0.x; x < crect.p1.x; x++) {
    112                         pixelmap_put_pixel(&wnd->pixelmap, x - wnd->rect.p0.x,
    113                             y - wnd->rect.p0.y, wnd->color);
    114                 }
    115         }
    116 
    117         /* Repaint this area of the display */
    118         return ds_display_paint(wnd->display, &drect);
    119 }
    120 
    121 /** Create bitmap in window GC.
    122  *
    123  * @param arg Window GC
    124  * @param params Bitmap params
    125  * @param alloc Bitmap allocation info or @c NULL
    126  * @param rbm Place to store pointer to new bitmap
    127  * @return EOK on success or an error code
    128  */
    129 errno_t ds_window_bitmap_create(void *arg, gfx_bitmap_params_t *params,
    130     gfx_bitmap_alloc_t *alloc, void **rbm)
    131 {
    132         ds_window_t *wnd = (ds_window_t *) arg;
    133         ds_window_bitmap_t *wbm = NULL;
    134         errno_t rc;
    135 
    136         wbm = calloc(1, sizeof(ds_window_bitmap_t));
    137         if (wbm == NULL)
    138                 return ENOMEM;
    139 
    140         rc = gfx_bitmap_create(ds_display_get_gc(wnd->display), params, alloc,
    141             &wbm->bitmap);
    142         if (rc != EOK)
    143                 goto error;
    144 
    145         wbm->wnd = wnd;
    146         wbm->rect = params->rect;
    147         wbm->flags = params->flags;
    148         wbm->key_color = params->key_color;
    149         *rbm = (void *)wbm;
    150         return EOK;
    151 error:
    152         if (wbm != NULL)
    153                 free(wbm);
    154         return rc;
    155 }
    156 
    157 /** Destroy bitmap in window GC.
    158  *
    159  * @param bm Bitmap
    160  * @return EOK on success or an error code
    161  */
    162 static errno_t ds_window_bitmap_destroy(void *bm)
    163 {
    164         ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
    165 
    166         gfx_bitmap_destroy(wbm->bitmap);
    167         free(wbm);
    168         return EOK;
    169 }
    170 
    171 /** Render bitmap in window GC.
    172  *
    173  * @param bm Bitmap
    174  * @param srect0 Source rectangle or @c NULL
    175  * @param offs0 Offset or @c NULL
    176  * @return EOK on success or an error code
    177  */
    178 static errno_t ds_window_bitmap_render(void *bm, gfx_rect_t *srect0,
    179     gfx_coord2_t *offs0)
    180 {
    181         ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
    182         gfx_coord2_t doffs;
    183         gfx_coord2_t offs;
    184         gfx_rect_t srect;
    185         gfx_rect_t swrect;
    186         gfx_rect_t crect;
    187         gfx_rect_t drect;
    188         gfx_coord_t x, y;
    189         pixelmap_t pixelmap;
    190         gfx_bitmap_alloc_t alloc;
    191         pixel_t pixel;
    192         errno_t rc;
    193 
    194         if (srect0 != NULL) {
    195                 /* Clip source rectangle to bitmap rectangle */
    196                 gfx_rect_clip(srect0, &wbm->rect, &srect);
    197         } else {
    198                 /* Source is entire bitmap rectangle */
    199                 srect = wbm->rect;
    200         }
    201 
    202         if (offs0 != NULL) {
    203                 offs = *offs0;
    204         } else {
    205                 offs.x = 0;
    206                 offs.y = 0;
    207         }
    208 
    209         /* Transform window rectangle back to bitmap coordinate system */
    210         gfx_rect_rtranslate(&offs, &wbm->wnd->rect, &swrect);
    211 
    212         /* Clip so that transformed rectangle will be inside the window */
    213         gfx_rect_clip(&srect, &swrect, &crect);
    214 
    215         /* Offset for rendering on screen = window pos + offs */
    216         gfx_coord2_add(&wbm->wnd->dpos, &offs, &doffs);
    217 
    218         /* Resulting rectangle on the screen we are drawing into */
    219         gfx_rect_translate(&doffs, &crect, &drect);
    220 
    221         rc = gfx_bitmap_get_alloc(wbm->bitmap, &alloc);
    222         if (rc != EOK)
    223                 return rc;
    224 
    225         pixelmap.width = wbm->rect.p1.x - wbm->rect.p0.x;
    226         pixelmap.height = wbm->rect.p1.y - wbm->rect.p0.y;
    227         pixelmap.data = alloc.pixels;
    228 
    229         /* Render a copy to the backbuffer */
    230         if ((wbm->flags & bmpf_color_key) == 0) {
    231                 for (y = crect.p0.y; y < crect.p1.y; y++) {
    232                         for (x = crect.p0.x; x < crect.p1.x; x++) {
    233                                 pixel = pixelmap_get_pixel(&pixelmap,
    234                                     x - wbm->rect.p0.x, y - wbm->rect.p0.y);
    235                                 pixelmap_put_pixel(&wbm->wnd->pixelmap,
    236                                     x + offs.x - wbm->rect.p0.x + wbm->wnd->rect.p0.x,
    237                                     y + offs.y - wbm->rect.p0.y + wbm->wnd->rect.p0.y,
    238                                     pixel);
    239                         }
    240                 }
    241         } else {
    242                 for (y = crect.p0.y; y < crect.p1.y; y++) {
    243                         for (x = crect.p0.x; x < crect.p1.x; x++) {
    244                                 pixel = pixelmap_get_pixel(&pixelmap,
    245                                     x - wbm->rect.p0.x, y - wbm->rect.p0.y);
    246                                 if (pixel != wbm->key_color) {
    247                                         pixelmap_put_pixel(&wbm->wnd->pixelmap,
    248                                             x + offs.x - wbm->rect.p0.x +
    249                                             wbm->wnd->rect.p0.x,
    250                                             y + offs.y - wbm->rect.p0.y +
    251                                             wbm->wnd->rect.p0.y,
    252                                             pixel);
    253                                 }
    254                         }
    255                 }
    256         }
    257 
    258         /* Repaint this area of the display */
    259         return ds_display_paint(wbm->wnd->display, &drect);
    260 }
    261 
    262 /** Get allocation info for bitmap in window GC.
    263  *
    264  * @param bm Bitmap
    265  * @param alloc Place to store allocation info
    266  * @return EOK on success or an error code
    267  */
    268 static errno_t ds_window_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    269 {
    270         ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
    271 
    272         return gfx_bitmap_get_alloc(wbm->bitmap, alloc);
    273 }
     51static void ds_window_update_cb(void *, gfx_rect_t *);
    27452
    27553/** Create window.
     
    28765{
    28866        ds_window_t *wnd = NULL;
    289         gfx_context_t *gc = NULL;
    29067        gfx_context_t *dgc;
    29168        gfx_coord2_t dims;
     
    30077        }
    30178
    302         rc = gfx_context_new(&ds_window_ops, wnd, &gc);
    303         if (rc != EOK)
    304                 goto error;
    305 
    30679        ds_client_add_window(client, wnd);
    30780        ds_display_add_window(client->display, wnd);
     
    32497                wnd->pixelmap.height = dims.y;
    32598                wnd->pixelmap.data = alloc.pixels;
    326         }
     99        } else {
     100                /* This is just for unit tests */
     101                gfx_rect_dims(&params->rect, &dims);
     102                alloc.pitch = dims.x * sizeof(uint32_t);
     103                alloc.off0 = 0;
     104                alloc.pixels = calloc(1, alloc.pitch * dims.y);
     105        }
     106
     107        rc = mem_gc_create(&params->rect, &alloc, ds_window_update_cb,
     108            (void *)wnd, &wnd->mgc);
     109        if (rc != EOK)
     110                goto error;
    327111
    328112        wnd->rect = params->rect;
    329113        wnd->min_size = params->min_size;
    330         wnd->gc = gc;
     114        wnd->gc = mem_gc_get_ctx(wnd->mgc);
    331115        wnd->cursor = wnd->display->cursor[dcurs_arrow];
    332116        *rgc = wnd;
     
    339123        }
    340124
    341         gfx_context_delete(gc);
    342125        return rc;
    343126}
     
    356139        ds_display_remove_window(wnd);
    357140
    358         (void) gfx_context_delete(wnd->gc);
     141        mem_gc_delete(wnd->mgc);
     142
    359143        if (wnd->bitmap != NULL)
    360144                gfx_bitmap_destroy(wnd->bitmap);
     
    818602                wnd->bitmap = nbitmap;
    819603                wnd->pixelmap = npixelmap;
     604
     605                /* Point memory GC to the new bitmap */
     606                mem_gc_retarget(wnd->mgc, nrect, &alloc);
    820607        }
    821608
     
    884671}
    885672
     673/** Window memory GC update callbac.
     674 *
     675 * This is called by the window's memory GC when a rectangle us updated.
     676 */
     677static void ds_window_update_cb(void *arg, gfx_rect_t *rect)
     678{
     679        ds_window_t *wnd = (ds_window_t *)arg;
     680        gfx_rect_t drect;
     681
     682        /* Repaint the corresponding part of the display */
     683        gfx_rect_translate(&wnd->dpos, rect, &drect);
     684        (void) ds_display_paint(wnd->display, &drect);
     685}
     686
    886687/** @}
    887688 */
Note: See TracChangeset for help on using the changeset viewer.