Changeset f8375f7 in mainline


Ignore:
Timestamp:
2020-05-30T17:16:39Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
dbef30f
Parents:
cea9f0c
Message:

Communicate memory GC updates via callback function

This is what we want in most use cases. Allows us to expose memory GC
ops directly without interposing on them (greatly simplifying the code).
The previous behavior is easily achieved by supplying the right callback
function.

Location:
uspace/lib
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/guigfx/private/canvas.h

    rcea9f0c rf8375f7  
    4848/** Actual structure of canvas GC. */
    4949struct canvas_gc {
     50        /** Memory GC */
     51        mem_gc_t *mgc;
    5052        /** Base graphic context */
    5153        gfx_context_t *gc;
     
    5456        /** Surface */
    5557        surface_t *surface;
    56         /** Memory GC */
    57         mem_gc_t *mgc;
    58         /** Base GC for memory GC */
    59         gfx_context_t *mbgc;
    6058};
    61 
    62 /** Bitmap in canvas GC */
    63 typedef struct {
    64         /** Containing canvas GC */
    65         struct canvas_gc *cgc;
    66         /** Memory GC bitmap */
    67         gfx_bitmap_t *mbitmap;
    68 } canvas_gc_bitmap_t;
    6959
    7060#endif
  • uspace/lib/guigfx/src/canvas.c

    rcea9f0c rf8375f7  
    4949//#include "../../private/color.h"
    5050
    51 static errno_t canvas_gc_set_color(void *, gfx_color_t *);
    52 static errno_t canvas_gc_fill_rect(void *, gfx_rect_t *);
    53 static errno_t canvas_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    54     gfx_bitmap_alloc_t *, void **);
    55 static errno_t canvas_gc_bitmap_destroy(void *);
    56 static errno_t canvas_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    57 static errno_t canvas_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    58 
    59 gfx_context_ops_t canvas_gc_ops = {
    60         .set_color = canvas_gc_set_color,
    61         .fill_rect = canvas_gc_fill_rect,
    62         .bitmap_create = canvas_gc_bitmap_create,
    63         .bitmap_destroy = canvas_gc_bitmap_destroy,
    64         .bitmap_render = canvas_gc_bitmap_render,
    65         .bitmap_get_alloc = canvas_gc_bitmap_get_alloc
    66 };
    67 
    68 /** Set color on canvas GC.
    69  *
    70  * Set drawing color on canvas GC.
    71  *
    72  * @param arg Canvas GC
    73  * @param color Color
    74  *
    75  * @return EOK on success or an error code
    76  */
    77 static errno_t canvas_gc_set_color(void *arg, gfx_color_t *color)
    78 {
    79         canvas_gc_t *cgc = (canvas_gc_t *) arg;
    80 
    81         return gfx_set_color(cgc->mbgc, color);
    82 }
    83 
    84 /** Fill rectangle on canvas GC.
    85  *
    86  * @param arg Canvas GC
    87  * @param rect Rectangle
    88  *
    89  * @return EOK on success or an error code
    90  */
    91 static errno_t canvas_gc_fill_rect(void *arg, gfx_rect_t *rect)
    92 {
    93         canvas_gc_t *cgc = (canvas_gc_t *) arg;
    94         errno_t rc;
    95 
    96         rc = gfx_fill_rect(cgc->mbgc, rect);
    97         if (rc == EOK)
    98                 update_canvas(cgc->canvas, cgc->surface);
    99 
    100         return rc;
    101 }
     51static void canvas_gc_update_cb(void *, gfx_rect_t *);
    10252
    10353/** Create canvas GC.
     
    11565{
    11666        canvas_gc_t *cgc = NULL;
    117         gfx_context_t *gc = NULL;
    11867        surface_coord_t w, h;
    11968        gfx_rect_t rect;
     
    12978        }
    13079
    131         rc = gfx_context_new(&canvas_gc_ops, cgc, &gc);
    132         if (rc != EOK)
    133                 goto error;
    134 
    13580        rect.p0.x = 0;
    13681        rect.p0.y = 0;
     
    14287        alloc.pixels = surface_direct_access(surface);
    14388
    144         rc = mem_gc_create(&rect, &alloc, &cgc->mgc);
     89        rc = mem_gc_create(&rect, &alloc, canvas_gc_update_cb,
     90            (void *)cgc, &cgc->mgc);
    14591        if (rc != EOK)
    14692                goto error;
    14793
    148         cgc->mbgc = mem_gc_get_ctx(cgc->mgc);
     94        cgc->gc = mem_gc_get_ctx(cgc->mgc);
    14995
    150         cgc->gc = gc;
    15196        cgc->canvas = canvas;
    15297        cgc->surface = surface;
     
    15499        return EOK;
    155100error:
    156         if (gc != NULL)
    157                 gfx_context_delete(gc);
    158101        if (cgc != NULL)
    159102                free(cgc);
     
    189132}
    190133
    191 /** Create bitmap in canvas GC.
     134/** Canvas GC update callback called by memory GC.
    192135 *
    193136 * @param arg Canvas GC
    194  * @param params Bitmap params
    195  * @param alloc Bitmap allocation info or @c NULL
    196  * @param rbm Place to store pointer to new bitmap
    197  * @return EOK on success or an error code
     137 * @param rect Rectangle to update
    198138 */
    199 errno_t canvas_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
    200     gfx_bitmap_alloc_t *alloc, void **rbm)
     139static void canvas_gc_update_cb(void *arg, gfx_rect_t *rect)
    201140{
    202         canvas_gc_t *cgc = (canvas_gc_t *) arg;
    203         canvas_gc_bitmap_t *cbm = NULL;
    204         errno_t rc;
     141        canvas_gc_t *cgc = (canvas_gc_t *)arg;
    205142
    206         cbm = calloc(1, sizeof(canvas_gc_bitmap_t));
    207         if (cbm == NULL)
    208                 return ENOMEM;
    209 
    210         rc = gfx_bitmap_create(cgc->mbgc, params, alloc, &cbm->mbitmap);
    211         if (rc != EOK)
    212                 goto error;
    213 
    214         cbm->cgc = cgc;
    215         *rbm = (void *)cbm;
    216         return EOK;
    217 error:
    218         if (cbm != NULL)
    219                 free(cbm);
    220         return rc;
    221 }
    222 
    223 /** Destroy bitmap in canvas GC.
    224  *
    225  * @param bm Bitmap
    226  * @return EOK on success or an error code
    227  */
    228 static errno_t canvas_gc_bitmap_destroy(void *bm)
    229 {
    230         canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
    231         errno_t rc;
    232 
    233         rc = gfx_bitmap_destroy(cbm->mbitmap);
    234         if (rc != EOK)
    235                 return rc;
    236 
    237         free(cbm);
    238         return EOK;
    239 }
    240 
    241 /** Render bitmap in canvas GC.
    242  *
    243  * @param bm Bitmap
    244  * @param srect0 Source rectangle or @c NULL
    245  * @param offs0 Offset or @c NULL
    246  * @return EOK on success or an error code
    247  */
    248 static errno_t canvas_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
    249     gfx_coord2_t *offs0)
    250 {
    251         canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
    252         errno_t rc;
    253 
    254         rc = gfx_bitmap_render(cbm->mbitmap, srect0, offs0);
    255         if (rc == EOK)
    256                 update_canvas(cbm->cgc->canvas, cbm->cgc->surface);
    257 
    258         return rc;
    259 }
    260 
    261 /** Get allocation info for bitmap in canvas GC.
    262  *
    263  * @param bm Bitmap
    264  * @param alloc Place to store allocation info
    265  * @return EOK on success or an error code
    266  */
    267 static errno_t canvas_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    268 {
    269         canvas_gc_bitmap_t *cbm = (canvas_gc_bitmap_t *)bm;
    270 
    271         return gfx_bitmap_get_alloc(cbm->mbitmap, alloc);
     143        update_canvas(cgc->canvas, cgc->surface);
    272144}
    273145
  • uspace/lib/memgfx/include/memgfx/memgc.h

    rcea9f0c rf8375f7  
    4040#include <types/gfx/bitmap.h>
    4141#include <types/gfx/context.h>
    42 #include <types/gfx/coord.h>
    4342#include <types/gfx/ops/context.h>
    4443#include <types/memgfx/memgc.h>
     
    4645extern gfx_context_ops_t mem_gc_ops;
    4746
    48 extern errno_t mem_gc_create(gfx_rect_t *, gfx_bitmap_alloc_t *, mem_gc_t **);
     47extern errno_t mem_gc_create(gfx_rect_t *, gfx_bitmap_alloc_t *,
     48    mem_gc_update_cb_t, void *, mem_gc_t **);
    4949extern errno_t mem_gc_delete(mem_gc_t *);
    5050extern gfx_context_t *mem_gc_get_ctx(mem_gc_t *);
    51 extern void mem_gc_get_update_rect(mem_gc_t *, gfx_rect_t *);
    52 extern void mem_gc_clear_update_rect(mem_gc_t *);
    5351
    5452#endif
  • uspace/lib/memgfx/include/types/memgfx/memgc.h

    rcea9f0c rf8375f7  
    3737#define _MEMGFX_TYPES_MEMGC_H
    3838
     39#include <types/gfx/coord.h>
     40
    3941struct mem_gc;
    4042typedef struct mem_gc mem_gc_t;
     43
     44typedef void (*mem_gc_update_cb_t)(void *, gfx_rect_t *);
    4145
    4246#endif
  • uspace/lib/memgfx/private/memgc.h

    rcea9f0c rf8375f7  
    4949        /** Bounding rectangle */
    5050        gfx_rect_t rect;
    51         /** Update rectangle */
    52         gfx_rect_t upd_rect;
    5351        /** Allocation info */
    5452        gfx_bitmap_alloc_t alloc;
     53        /** Update callback */
     54        mem_gc_update_cb_t update;
     55        /** Argument to callback */
     56        void *cb_arg;
    5557        /** Current drawing color */
    5658        pixel_t color;
  • uspace/lib/memgfx/src/memgc.c

    rcea9f0c rf8375f7  
    123123 * @param rect Bounding rectangle
    124124 * @param alloc Allocation info
     125 * @param update_cb Function called to update a rectangle
     126 * @param cb_arg Argument to callback function
    125127 * @param rgc Place to store pointer to new memory GC
    126128 *
     
    128130 */
    129131errno_t mem_gc_create(gfx_rect_t *rect, gfx_bitmap_alloc_t *alloc,
    130     mem_gc_t **rgc)
     132    mem_gc_update_cb_t update_cb, void *cb_arg, mem_gc_t **rgc)
    131133{
    132134        mem_gc_t *mgc = NULL;
     
    159161        assert(alloc->pitch == rect->p1.x * (int)sizeof(uint32_t));
    160162
    161         mem_gc_clear_update_rect(mgc);
     163        mgc->update = update_cb;
     164        mgc->cb_arg = cb_arg;
    162165
    163166        *rgc = mgc;
     
    198201static void mem_gc_invalidate_rect(mem_gc_t *mgc, gfx_rect_t *rect)
    199202{
    200         gfx_rect_t nrect;
    201 
    202         gfx_rect_envelope(&mgc->upd_rect, rect, &nrect);
    203         mgc->upd_rect = nrect;
    204 }
    205 
    206 void mem_gc_get_update_rect(mem_gc_t *mgc, gfx_rect_t *rect)
    207 {
    208         *rect = mgc->upd_rect;
    209 }
    210 
    211 void mem_gc_clear_update_rect(mem_gc_t *mgc)
    212 {
    213         mgc->upd_rect.p0.x = 0;
    214         mgc->upd_rect.p0.y = 0;
    215         mgc->upd_rect.p1.x = 0;
    216         mgc->upd_rect.p1.y = 0;
     203        mgc->update(mgc->cb_arg, rect);
    217204}
    218205
  • uspace/lib/memgfx/test/memgfx.c

    rcea9f0c rf8375f7  
    3434#include <gfx/render.h>
    3535#include <io/pixelmap.h>
     36#include <mem.h>
    3637#include <memgfx/memgc.h>
    3738#include <pcut/pcut.h>
     
    4041
    4142PCUT_TEST_SUITE(memgfx);
     43
     44static void test_update_rect(void *arg, gfx_rect_t *rect);
     45
     46typedef struct {
     47        /** True if update was called */
     48        bool update_called;
     49        /** Update rectangle */
     50        gfx_rect_t rect;
     51} test_update_t;
    4252
    4353/** Test creating and deleting a memory GC */
     
    5969        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    6070
    61         rc = mem_gc_create(&rect, &alloc, &mgc);
     71        rc = mem_gc_create(&rect, &alloc, NULL, NULL, &mgc);
    6272        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6373
     
    7282        gfx_rect_t rect;
    7383        gfx_rect_t frect;
    74         gfx_rect_t urect;
    7584        gfx_bitmap_alloc_t alloc;
    7685        gfx_context_t *gc;
     
    8089        pixel_t pixel;
    8190        pixel_t expected;
     91        test_update_t update;
    8292        errno_t rc;
    8393
     
    93103        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    94104
    95         rc = mem_gc_create(&rect, &alloc, &mgc);
     105        rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
    96106        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    97107
     
    111121        frect.p1.x = 5;
    112122        frect.p1.y = 5;
     123
     124        memset(&update, 0, sizeof(update));
    113125
    114126        rc = gfx_fill_rect(gc, &frect);
     
    130142
    131143        /* Check that the update rect is equal to the filled rect */
    132         mem_gc_get_update_rect(mgc, &urect);
    133         PCUT_ASSERT_INT_EQUALS(frect.p0.x, urect.p0.x);
    134         PCUT_ASSERT_INT_EQUALS(frect.p0.y, urect.p0.y);
    135         PCUT_ASSERT_INT_EQUALS(frect.p1.x, urect.p1.x);
    136         PCUT_ASSERT_INT_EQUALS(frect.p1.y, urect.p1.y);
    137 
    138         /* Check that mem_gc_clear_update_rect() clears the update rect */
    139         mem_gc_clear_update_rect(mgc);
    140         mem_gc_get_update_rect(mgc, &urect);
    141         PCUT_ASSERT_TRUE(gfx_rect_is_empty(&urect));
     144        PCUT_ASSERT_TRUE(update.update_called);
     145        PCUT_ASSERT_INT_EQUALS(frect.p0.x, update.rect.p0.x);
     146        PCUT_ASSERT_INT_EQUALS(frect.p0.y, update.rect.p0.y);
     147        PCUT_ASSERT_INT_EQUALS(frect.p1.x, update.rect.p1.x);
     148        PCUT_ASSERT_INT_EQUALS(frect.p1.y, update.rect.p1.y);
    142149
    143150        /* TODO: Check clipping once memgc can support pitch != width etc. */
     
    152159        mem_gc_t *mgc;
    153160        gfx_rect_t rect;
    154         gfx_rect_t urect;
    155161        gfx_bitmap_alloc_t alloc;
    156162        gfx_context_t *gc;
     
    163169        pixel_t pixel;
    164170        pixel_t expected;
     171        test_update_t update;
    165172        errno_t rc;
    166173
     
    176183        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    177184
    178         rc = mem_gc_create(&rect, &alloc, &mgc);
     185        rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
    179186        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    180187
     
    211218        dpmap.height = rect.p1.y - rect.p0.y;
    212219        dpmap.data = alloc.pixels;
     220
     221        memset(&update, 0, sizeof(update));
    213222
    214223        /* Render the bitmap */
     
    229238
    230239        /* Check that the update rect is equal to the filled rect */
    231         mem_gc_get_update_rect(mgc, &urect);
    232         PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, urect.p0.x);
    233         PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, urect.p0.y);
    234         PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, urect.p1.x);
    235         PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, urect.p1.y);
    236 
    237         /* Check that mem_gc_clear_update_rect() clears the update rect */
    238         mem_gc_clear_update_rect(mgc);
    239         mem_gc_get_update_rect(mgc, &urect);
    240         PCUT_ASSERT_TRUE(gfx_rect_is_empty(&urect));
     240        PCUT_ASSERT_TRUE(update.update_called);
     241        PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, update.rect.p0.x);
     242        PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, update.rect.p0.y);
     243        PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, update.rect.p1.x);
     244        PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, update.rect.p1.y);
    241245
    242246        /* TODO: Check clipping once memgc can support pitch != width etc. */
     
    246250}
    247251
     252/** Called by memory GC when a rectangle is updated. */
     253static void test_update_rect(void *arg, gfx_rect_t *rect)
     254{
     255        test_update_t *update = (test_update_t *)arg;
     256
     257        update->update_called = true;
     258        update->rect = *rect;
     259}
     260
    248261PCUT_EXPORT(memgfx);
Note: See TracChangeset for help on using the changeset viewer.