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

Changeset dbef30f in mainline


Ignore:
Timestamp:
2020-06-03T16:36:35Z (5 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
978c9bc5
Parents:
f8375f7
Message:

Use memory GC to render window in display server

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/memgfx/include/memgfx/memgc.h

    rf8375f7 rdbef30f  
    4848    mem_gc_update_cb_t, void *, mem_gc_t **);
    4949extern errno_t mem_gc_delete(mem_gc_t *);
     50extern void mem_gc_retarget(mem_gc_t *, gfx_rect_t *, gfx_bitmap_alloc_t *);
    5051extern gfx_context_t *mem_gc_get_ctx(mem_gc_t *);
    5152
  • uspace/lib/memgfx/src/memgc.c

    rf8375f7 rdbef30f  
    9595        mem_gc_t *mgc = (mem_gc_t *) arg;
    9696        gfx_rect_t crect;
    97         gfx_coord2_t dims;
    9897        gfx_coord_t x, y;
    9998        pixelmap_t pixelmap;
     
    102101        gfx_rect_clip(rect, &mgc->rect, &crect);
    103102
    104         gfx_rect_dims(&mgc->rect, &dims);
    105         pixelmap.width = dims.x;
    106         pixelmap.height = dims.y;
     103        assert(mgc->rect.p0.x == 0);
     104        assert(mgc->rect.p0.y == 0);
     105        assert(mgc->alloc.pitch == mgc->rect.p1.x * (int)sizeof(uint32_t));
     106        pixelmap.width = mgc->rect.p1.x;
     107        pixelmap.height = mgc->rect.p1.y;
    107108        pixelmap.data = mgc->alloc.pixels;
    108109
     
    150151        mgc->alloc = *alloc;
    151152
    152         /*
    153          * These are the limitations of pixelmap which we are using.
    154          * Rather than falling back to an ad-hoc method of pixel access
    155          * (which is not searchable), use pixelmap for now and switch
    156          * to a better, more universal method later (e.g. supporting
    157          * different color depths).
    158          */
    159         assert(rect->p0.x == 0);
    160         assert(rect->p0.y == 0);
    161         assert(alloc->pitch == rect->p1.x * (int)sizeof(uint32_t));
    162 
    163153        mgc->update = update_cb;
    164154        mgc->cb_arg = cb_arg;
     
    187177        free(mgc);
    188178        return EOK;
     179}
     180
     181/** Retarget memory GC to a different block of memory.
     182 *
     183 * @param mgc Memory GC
     184 * @param rect New bounding rectangle
     185 * @param alloc Allocation info of the new block
     186 */
     187void mem_gc_retarget(mem_gc_t *mgc, gfx_rect_t *rect,
     188    gfx_bitmap_alloc_t *alloc)
     189{
     190        mgc->rect = *rect;
     191        mgc->alloc = *alloc;
    189192}
    190193
     
    283286        gfx_coord2_t dim;
    284287        gfx_coord_t x, y;
    285         gfx_coord2_t sdims;
    286         gfx_coord2_t ddims;
    287288        pixelmap_t smap;
    288289        pixelmap_t dmap;
     
    306307        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
    307308
    308         gfx_rect_dims(&mbm->rect, &sdims);
    309         smap.width = sdims.x;
    310         smap.height = sdims.y;
     309        assert(mbm->rect.p0.x == 0);
     310        assert(mbm->rect.p0.y == 0);
     311        assert(mbm->alloc.pitch == mbm->rect.p1.x * (int)sizeof(uint32_t));
     312        smap.width = mbm->rect.p1.x;
     313        smap.height = mbm->rect.p1.y;
    311314        smap.data = mbm->alloc.pixels;
    312315
    313         gfx_rect_dims(&mbm->mgc->rect, &ddims);
    314         dmap.width = ddims.x;
    315         dmap.height = ddims.y;
     316        assert(mbm->mgc->rect.p0.x == 0);
     317        assert(mbm->mgc->rect.p0.y == 0);
     318        assert(mbm->mgc->alloc.pitch == mbm->mgc->rect.p1.x * (int)sizeof(uint32_t));
     319        dmap.width = mbm->mgc->rect.p1.x;
     320        dmap.height = mbm->mgc->rect.p1.y;
    316321        dmap.data = mbm->mgc->alloc.pixels;
    317322
  • uspace/srv/hid/display/meson.build

    rf8375f7 rdbef30f  
    2727#
    2828
    29 deps = [ 'ipcgfx', 'display', 'ddev' ]
     29deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev' ]
    3030
    3131src = files(
  • uspace/srv/hid/display/types/display/window.h

    rf8375f7 rdbef30f  
    4444#include <io/pixel.h>
    4545#include <io/pixelmap.h>
     46#include <memgfx/memgc.h>
    4647
    4748typedef sysarg_t ds_wnd_id_t;
     
    7980        /** Window ID */
    8081        ds_wnd_id_t id;
     82        /** Memory GC */
     83        mem_gc_t *mgc;
    8184        /** Graphic context */
    8285        gfx_context_t *gc;
  • 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.