Changeset 2ab8ab3 in mainline


Ignore:
Timestamp:
2021-02-16T18:12:05Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
68a552f
Parents:
ef734b7
Message:

Client-side UI rendering

It is possible to turn on and off and if turned on, one can also
enable or disable window double buffering (currently both options
are build-time).

Files:
29 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    ref734b7 r2ab8ab3  
    614614! [CONFIG_FB=y] CONFIG_DISP_DOUBLE_BUF (y/n)
    615615
     616% Client-side UI rendering
     617! [CONFIG_FB=y] CONFIG_UI_CS_RENDER (y/n)
     618
    616619% Window double buffering
    617 ! [CONFIG_FB=y] CONFIG_WIN_DOUBLE_BUF (n/y)
     620! [CONFIG_UI_CS_RENDER=y] CONFIG_WIN_DOUBLE_BUF (n/y)
    618621
    619622% Start AP processors by the loader
  • uspace/app/terminal/terminal.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * Copyright (c) 2012 Petr Koupy
    44 * All rights reserved.
     
    4242#include <gfx/bitmap.h>
    4343#include <gfx/context.h>
     44#include <gfx/render.h>
    4445#include <io/con_srv.h>
    4546#include <io/concaps.h>
     
    524525                term_write_char(term, str_decode(data, &off, size));
    525526
     527        gfx_update(term->gc);
    526528        *nwritten = size;
    527529        return EOK;
     
    533535
    534536        term_update(term);
     537        gfx_update(term->gc);
    535538}
    536539
     
    544547
    545548        term_update(term);
     549        gfx_update(term->gc);
    546550}
    547551
     
    555559
    556560        term_update(term);
     561        gfx_update(term->gc);
    557562}
    558563
     
    626631
    627632        term_update(term);
     633        gfx_update(term->gc);
    628634}
    629635
     
    688694        term->is_focused = true;
    689695        term_update(term);
     696        gfx_update(term->gc);
    690697}
    691698
     
    731738        term->is_focused = false;
    732739        term_update(term);
     740        gfx_update(term->gc);
    733741}
    734742
  • uspace/lib/gfx/include/gfx/render.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4444extern errno_t gfx_set_color(gfx_context_t *, gfx_color_t *);
    4545extern errno_t gfx_fill_rect(gfx_context_t *, gfx_rect_t *);
     46extern errno_t gfx_update(gfx_context_t *);
    4647
    4748#endif
  • uspace/lib/gfx/include/types/gfx/ops/context.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151        /** Fill rectangle using the current drawing color */
    5252        errno_t (*fill_rect)(void *, gfx_rect_t *);
     53        /** Update display */
     54        errno_t (*update)(void *);
    5355        /** Create bitmap */
    5456        errno_t (*bitmap_create)(void *, gfx_bitmap_params_t *,
  • uspace/lib/gfx/src/render.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6363}
    6464
     65/** Update display.
     66 *
     67 * Finish any deferred rendering.
     68 *
     69 * @param gc Graphic context
     70 *
     71 * @return EOK on success, ENOMEM if insufficient resources,
     72 *         EIO if grahic device connection was lost
     73 */
     74errno_t gfx_update(gfx_context_t *gc)
     75{
     76        return gc->ops->update(gc->arg);
     77}
     78
    6579/** @}
    6680 */
  • uspace/lib/gfx/test/render.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3232#include <pcut/pcut.h>
    3333#include <mem.h>
     34#include <stdbool.h>
    3435
    3536PCUT_INIT;
     
    3940static errno_t testgc_set_color(void *, gfx_color_t *);
    4041static errno_t testgc_fill_rect(void *, gfx_rect_t *);
     42static errno_t testgc_update(void *);
    4143
    4244static gfx_context_ops_t ops = {
    4345        .set_color = testgc_set_color,
    44         .fill_rect = testgc_fill_rect
     46        .fill_rect = testgc_fill_rect,
     47        .update = testgc_update
    4548};
    4649
     
    4952        gfx_color_t *dclr;
    5053        gfx_rect_t *rect;
     54        bool updated;
    5155} test_gc_t;
    5256
     
    107111}
    108112
     113PCUT_TEST(update)
     114{
     115        errno_t rc;
     116        gfx_context_t *gc = NULL;
     117        test_gc_t tgc;
     118
     119        memset(&tgc, 0, sizeof(tgc));
     120
     121        rc = gfx_context_new(&ops, &tgc, &gc);
     122        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     123
     124        PCUT_ASSERT_FALSE(tgc.updated);
     125        gfx_update(gc);
     126        PCUT_ASSERT_TRUE(tgc.updated);
     127
     128        rc = gfx_context_delete(gc);
     129        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     130}
     131
    109132static errno_t testgc_set_color(void *arg, gfx_color_t *color)
    110133{
     
    125148}
    126149
     150static errno_t testgc_update(void *arg)
     151{
     152        test_gc_t *tgc = (test_gc_t *) arg;
     153
     154        tgc->updated = true;
     155        return EOK;
     156}
     157
    127158PCUT_EXPORT(render);
  • uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141        GC_SET_RGB_COLOR = IPC_FIRST_USER_METHOD,
    4242        GC_FILL_RECT,
     43        GC_UPDATE,
    4344        GC_BITMAP_CREATE,
    4445        GC_BITMAP_CREATE_DOUTPUT,
    4546        GC_BITMAP_DESTROY,
    4647        GC_BITMAP_RENDER,
    47         GC_BITMAP_GET_ALLOC
     48        GC_BITMAP_GET_ALLOC,
    4849} gc_request_t;
    4950
  • uspace/lib/ipcgfx/src/client.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4747static errno_t ipc_gc_set_color(void *, gfx_color_t *);
    4848static errno_t ipc_gc_fill_rect(void *, gfx_rect_t *);
     49static errno_t ipc_gc_update(void *);
    4950static errno_t ipc_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    5051    gfx_bitmap_alloc_t *, void **);
     
    5657        .set_color = ipc_gc_set_color,
    5758        .fill_rect = ipc_gc_fill_rect,
     59        .update = ipc_gc_update,
    5860        .bitmap_create = ipc_gc_bitmap_create,
    5961        .bitmap_destroy = ipc_gc_bitmap_destroy,
     
    103105        rc = async_req_4_0(exch, GC_FILL_RECT, rect->p0.x, rect->p0.y,
    104106            rect->p1.x, rect->p1.y);
     107        async_exchange_end(exch);
     108
     109        return rc;
     110}
     111
     112/** Update display on IPC GC.
     113 *
     114 * @param arg IPC GC
     115 *
     116 * @return EOK on success or an error code
     117 */
     118static errno_t ipc_gc_update(void *arg)
     119{
     120        ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
     121        async_exch_t *exch;
     122        errno_t rc;
     123
     124        exch = async_exchange_begin(ipcgc->sess);
     125        rc = async_req_0_0(exch, GC_UPDATE);
    105126        async_exchange_end(exch);
    106127
  • uspace/lib/ipcgfx/src/server.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    8686}
    8787
     88static void gc_update_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
     89{
     90        errno_t rc;
     91
     92        rc = gfx_update(srvgc->gc);
     93        async_answer_0(call, rc);
     94}
     95
    8896static void gc_bitmap_create_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
    8997{
     
    358366                case GC_FILL_RECT:
    359367                        gc_fill_rect_srv(&srvgc, &call);
     368                        break;
     369                case GC_UPDATE:
     370                        gc_update_srv(&srvgc, &call);
    360371                        break;
    361372                case GC_BITMAP_CREATE:
  • uspace/lib/ipcgfx/test/ipcgfx.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5252static errno_t test_gc_set_color(void *, gfx_color_t *);
    5353static errno_t test_gc_fill_rect(void *, gfx_rect_t *);
     54static errno_t test_gc_update(void *);
    5455static errno_t test_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    5556    gfx_bitmap_alloc_t *, void **);
     
    6162        .set_color = test_gc_set_color,
    6263        .fill_rect = test_gc_fill_rect,
     64        .update = test_gc_update,
    6365        .bitmap_create = test_gc_bitmap_create,
    6466        .bitmap_destroy = test_gc_bitmap_destroy,
     
    8082        bool fill_rect_called;
    8183        gfx_rect_t fill_rect_rect;
     84
     85        bool update_called;
    8286
    8387        bool bitmap_create_called;
     
    292296        PCUT_ASSERT_EQUALS(rect.p1.x, resp.fill_rect_rect.p1.x);
    293297        PCUT_ASSERT_EQUALS(rect.p1.y, resp.fill_rect_rect.p1.y);
     298
     299        ipc_gc_delete(ipcgc);
     300        async_hangup(sess);
     301
     302        rc = loc_service_unregister(sid);
     303        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     304}
     305
     306/** gfx_update with server returning failure */
     307PCUT_TEST(update_failure)
     308{
     309        errno_t rc;
     310        service_id_t sid;
     311        test_response_t resp;
     312        gfx_context_t *gc;
     313        async_sess_t *sess;
     314        ipc_gc_t *ipcgc;
     315
     316        async_set_fallback_port_handler(test_ipcgc_conn, &resp);
     317
     318        // FIXME This causes this test to be non-reentrant!
     319        rc = loc_server_register(test_ipcgfx_server);
     320        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     321
     322        rc = loc_service_register(test_ipcgfx_svc, &sid);
     323        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     324
     325        sess = loc_service_connect(sid, INTERFACE_GC, 0);
     326        PCUT_ASSERT_NOT_NULL(sess);
     327
     328        rc = ipc_gc_create(sess, &ipcgc);
     329        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     330
     331        gc = ipc_gc_get_ctx(ipcgc);
     332        PCUT_ASSERT_NOT_NULL(gc);
     333
     334        resp.rc = ENOMEM;
     335        resp.update_called = false;
     336        rc = gfx_update(gc);
     337        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     338        PCUT_ASSERT_TRUE(resp.update_called);
     339
     340        ipc_gc_delete(ipcgc);
     341        async_hangup(sess);
     342
     343        rc = loc_service_unregister(sid);
     344        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     345}
     346
     347/** gfx_update with server returning success */
     348PCUT_TEST(update_success)
     349{
     350        errno_t rc;
     351        service_id_t sid;
     352        test_response_t resp;
     353        gfx_context_t *gc;
     354        async_sess_t *sess;
     355        ipc_gc_t *ipcgc;
     356
     357        async_set_fallback_port_handler(test_ipcgc_conn, &resp);
     358
     359        // FIXME This causes this test to be non-reentrant!
     360        rc = loc_server_register(test_ipcgfx_server);
     361        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     362
     363        rc = loc_service_register(test_ipcgfx_svc, &sid);
     364        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     365
     366        sess = loc_service_connect(sid, INTERFACE_GC, 0);
     367        PCUT_ASSERT_NOT_NULL(sess);
     368
     369        rc = ipc_gc_create(sess, &ipcgc);
     370        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     371
     372        gc = ipc_gc_get_ctx(ipcgc);
     373        PCUT_ASSERT_NOT_NULL(gc);
     374
     375        resp.rc = EOK;
     376        resp.update_called = false;
     377        rc = gfx_update(gc);
     378        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     379        PCUT_ASSERT_TRUE(resp.update_called);
    294380
    295381        ipc_gc_delete(ipcgc);
     
    847933}
    848934
     935/** Update test GC.
     936 *
     937 * @param arg Test GC
     938 *
     939 * @return EOK on success or an error code
     940 */
     941static errno_t test_gc_update(void *arg)
     942{
     943        test_response_t *resp = (test_response_t *) arg;
     944
     945        resp->update_called = true;
     946        return resp->rc;
     947}
     948
    849949/** Create bitmap in test GC.
    850950 *
  • uspace/lib/memgfx/include/memgfx/memgc.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4646
    4747extern errno_t mem_gc_create(gfx_rect_t *, gfx_bitmap_alloc_t *,
    48     mem_gc_update_cb_t, void *, mem_gc_t **);
     48    mem_gc_invalidate_cb_t, mem_gc_update_cb_t, void *, mem_gc_t **);
    4949extern errno_t mem_gc_delete(mem_gc_t *);
    5050extern void mem_gc_retarget(mem_gc_t *, gfx_rect_t *, gfx_bitmap_alloc_t *);
  • uspace/lib/memgfx/include/types/memgfx/memgc.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242typedef struct mem_gc mem_gc_t;
    4343
    44 typedef void (*mem_gc_update_cb_t)(void *, gfx_rect_t *);
     44typedef void (*mem_gc_invalidate_cb_t)(void *, gfx_rect_t *);
     45typedef void (*mem_gc_update_cb_t)(void *);
    4546
    4647#endif
  • uspace/lib/memgfx/private/memgc.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151        /** Allocation info */
    5252        gfx_bitmap_alloc_t alloc;
     53        /** Invalidate callback */
     54        mem_gc_invalidate_cb_t invalidate;
    5355        /** Update callback */
    5456        mem_gc_update_cb_t update;
  • uspace/lib/memgfx/src/memgc.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5050static errno_t mem_gc_set_color(void *, gfx_color_t *);
    5151static errno_t mem_gc_fill_rect(void *, gfx_rect_t *);
     52static errno_t mem_gc_update(void *);
    5253static errno_t mem_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    5354    gfx_bitmap_alloc_t *, void **);
     
    6061        .set_color = mem_gc_set_color,
    6162        .fill_rect = mem_gc_fill_rect,
     63        .update = mem_gc_update,
    6264        .bitmap_create = mem_gc_bitmap_create,
    6365        .bitmap_destroy = mem_gc_bitmap_destroy,
     
    119121}
    120122
     123/** Update memory GC.
     124 *
     125 * @param arg Memory GC
     126 *
     127 * @return EOK on success or an error code
     128 */
     129static errno_t mem_gc_update(void *arg)
     130{
     131        mem_gc_t *mgc = (mem_gc_t *) arg;
     132
     133        mgc->update(mgc->cb_arg);
     134        return EOK;
     135}
     136
    121137/** Create memory GC.
    122138 *
     
    132148 */
    133149errno_t mem_gc_create(gfx_rect_t *rect, gfx_bitmap_alloc_t *alloc,
    134     mem_gc_update_cb_t update_cb, void *cb_arg, mem_gc_t **rgc)
     150    mem_gc_invalidate_cb_t invalidate_cb, mem_gc_update_cb_t update_cb,
     151    void *cb_arg, mem_gc_t **rgc)
    135152{
    136153        mem_gc_t *mgc = NULL;
     
    152169        mgc->alloc = *alloc;
    153170
     171        mgc->invalidate = invalidate_cb;
    154172        mgc->update = update_cb;
    155173        mgc->cb_arg = cb_arg;
     
    205223static void mem_gc_invalidate_rect(mem_gc_t *mgc, gfx_rect_t *rect)
    206224{
    207         mgc->update(mgc->cb_arg, rect);
     225        mgc->invalidate(mgc->cb_arg, rect);
    208226}
    209227
  • uspace/lib/memgfx/test/memgfx.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242PCUT_TEST_SUITE(memgfx);
    4343
    44 static void test_update_rect(void *arg, gfx_rect_t *rect);
     44static void test_invalidate_rect(void *arg, gfx_rect_t *rect);
     45static void test_update(void *arg);
    4546
    4647typedef struct {
     48        /** True if invalidate was called */
     49        bool invalidate_called;
     50        /** Invalidate rectangle */
     51        gfx_rect_t inv_rect;
    4752        /** True if update was called */
    4853        bool update_called;
    49         /** Update rectangle */
    50         gfx_rect_t rect;
    51 } test_update_t;
     54} test_resp_t;
    5255
    5356/** Test creating and deleting a memory GC */
     
    6972        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    7073
    71         rc = mem_gc_create(&rect, &alloc, NULL, NULL, &mgc);
     74        rc = mem_gc_create(&rect, &alloc, NULL, NULL, NULL, &mgc);
    7275        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    7376
     
    8992        pixel_t pixel;
    9093        pixel_t expected;
    91         test_update_t update;
     94        test_resp_t resp;
    9295        errno_t rc;
    9396
     
    103106        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    104107
    105         rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
     108        rc = mem_gc_create(&rect, &alloc, test_invalidate_rect,
     109            test_update, &resp, &mgc);
    106110        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    107111
     
    122126        frect.p1.y = 5;
    123127
    124         memset(&update, 0, sizeof(update));
     128        memset(&resp, 0, sizeof(resp));
    125129
    126130        rc = gfx_fill_rect(gc, &frect);
     
    141145        }
    142146
    143         /* Check that the update rect is equal to the filled rect */
    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);
     147        /* Check that the invalidate rect is equal to the filled rect */
     148        PCUT_ASSERT_TRUE(resp.invalidate_called);
     149        PCUT_ASSERT_INT_EQUALS(frect.p0.x, resp.inv_rect.p0.x);
     150        PCUT_ASSERT_INT_EQUALS(frect.p0.y, resp.inv_rect.p0.y);
     151        PCUT_ASSERT_INT_EQUALS(frect.p1.x, resp.inv_rect.p1.x);
     152        PCUT_ASSERT_INT_EQUALS(frect.p1.y, resp.inv_rect.p1.y);
    149153
    150154        /* TODO: Check clipping once memgc can support pitch != width etc. */
     
    169173        pixel_t pixel;
    170174        pixel_t expected;
    171         test_update_t update;
     175        test_resp_t resp;
    172176        errno_t rc;
    173177
     
    183187        PCUT_ASSERT_NOT_NULL(alloc.pixels);
    184188
    185         rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
     189        rc = mem_gc_create(&rect, &alloc, test_invalidate_rect,
     190            test_update, &resp, &mgc);
    186191        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    187192
     
    191196        /* Create bitmap */
    192197
     198        gfx_bitmap_params_init(&params);
    193199        params.rect.p0.x = 0;
    194200        params.rect.p0.y = 0;
     
    219225        dpmap.data = alloc.pixels;
    220226
    221         memset(&update, 0, sizeof(update));
     227        memset(&resp, 0, sizeof(resp));
    222228
    223229        /* Render the bitmap */
     
    237243        }
    238244
    239         /* Check that the update rect is equal to the filled rect */
    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);
     245        /* Check that the invalidate rect is equal to the filled rect */
     246        PCUT_ASSERT_TRUE(resp.invalidate_called);
     247        PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, resp.inv_rect.p0.x);
     248        PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, resp.inv_rect.p0.y);
     249        PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, resp.inv_rect.p1.x);
     250        PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, resp.inv_rect.p1.y);
    245251
    246252        /* TODO: Check clipping once memgc can support pitch != width etc. */
     
    250256}
    251257
    252 /** Called by memory GC when a rectangle is updated. */
    253 static 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;
     258/** Test gfx_update() on a memory GC */
     259PCUT_TEST(gfx_update)
     260{
     261        mem_gc_t *mgc;
     262        gfx_rect_t rect;
     263        gfx_bitmap_alloc_t alloc;
     264        gfx_context_t *gc;
     265        test_resp_t resp;
     266        errno_t rc;
     267
     268        /* Bounding rectangle for memory GC */
     269        rect.p0.x = 0;
     270        rect.p0.y = 0;
     271        rect.p1.x = 10;
     272        rect.p1.y = 10;
     273
     274        alloc.pitch = (rect.p1.x - rect.p0.x) * sizeof(uint32_t);
     275        alloc.off0 = 0;
     276        alloc.pixels = calloc(1, alloc.pitch * (rect.p1.y - rect.p0.y));
     277        PCUT_ASSERT_NOT_NULL(alloc.pixels);
     278
     279        rc = mem_gc_create(&rect, &alloc, test_invalidate_rect,
     280            test_update, &resp, &mgc);
     281        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     282
     283        gc = mem_gc_get_ctx(mgc);
     284        PCUT_ASSERT_NOT_NULL(gc);
     285
     286        memset(&resp, 0, sizeof(resp));
     287        PCUT_ASSERT_FALSE(resp.update_called);
     288
     289        gfx_update(gc);
     290        PCUT_ASSERT_TRUE(resp.update_called);
     291
     292        mem_gc_delete(mgc);
     293        free(alloc.pixels);
     294}
     295
     296/** Called by memory GC when a rectangle is modified. */
     297static void test_invalidate_rect(void *arg, gfx_rect_t *rect)
     298{
     299        test_resp_t *resp = (test_resp_t *)arg;
     300
     301        resp->invalidate_called = true;
     302        resp->inv_rect = *rect;
     303}
     304
     305/** Called by memory GC when update is called. */
     306static void test_update(void *arg)
     307{
     308        test_resp_t *resp = (test_resp_t *)arg;
     309
     310        resp->update_called = true;
    259311}
    260312
  • uspace/lib/ui/private/window.h

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6060        /** Window GC */
    6161        gfx_context_t *gc;
     62        /** Window bitmap (if client-side rendering) */
     63        gfx_bitmap_t *bmp;
     64        /** Window memory GC (if client-side rendering) */
     65        mem_gc_t *mgc;
     66        /** Real window GC (if client-side rendering) */
     67        gfx_context_t *realgc;
    6268        /** Window rectangle */
    6369        gfx_rect_t rect;
     
    6874        /** Application area GC */
    6975        gfx_context_t *app_gc;
     76        /** Dirty rectangle */
     77        gfx_rect_t dirty_rect;
    7078        /** UI resource. Ideally this would be in ui_t. */
    7179        struct ui_resource *res;
  • uspace/lib/ui/src/checkbox.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    220220
    221221        rc = gfx_puttext(checkbox->res->font, &pos, &fmt, checkbox->caption);
     222        if (rc != EOK)
     223                goto error;
     224
     225        rc = gfx_update(checkbox->res->gc);
    222226        if (rc != EOK)
    223227                goto error;
  • uspace/lib/ui/src/dummygc.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    199199{
    200200        dummygc_bitmap_t *tbm = (dummygc_bitmap_t *)bm;
     201
    201202        tbm->dgc->bm_rendered = true;
    202         tbm->dgc->bm_srect = *srect;
    203         tbm->dgc->bm_offs = *offs;
     203
     204        tbm->dgc->bm_srect.p0.x = 0;
     205        tbm->dgc->bm_srect.p0.y = 0;
     206        tbm->dgc->bm_srect.p1.x = 0;
     207        tbm->dgc->bm_srect.p1.y = 0;
     208
     209        tbm->dgc->bm_offs.x = 0;
     210        tbm->dgc->bm_offs.y = 0;
     211
     212        if (srect != NULL)
     213                tbm->dgc->bm_srect = *srect;
     214
     215        if (offs != NULL)
     216                tbm->dgc->bm_offs = *offs;
     217
    204218        return EOK;
    205219}
  • uspace/lib/ui/src/entry.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    219219                goto error;
    220220
     221        rc = gfx_update(entry->res->gc);
     222        if (rc != EOK)
     223                goto error;
     224
    221225        return EOK;
    222226error:
  • uspace/lib/ui/src/image.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3737#include <gfx/bitmap.h>
    3838#include <gfx/context.h>
     39#include <gfx/render.h>
    3940#include <gfx/text.h>
    4041#include <stdlib.h>
     
    177178         */
    178179        gfx_rect_rtranslate(&offs, &irect, &srect);
    179         return gfx_bitmap_render(image->bitmap, &srect, &offs);
    180 
     180        rc = gfx_bitmap_render(image->bitmap, &srect, &offs);
     181        if (rc != EOK)
     182                return rc;
     183
     184        return gfx_update(image->res->gc);
    181185}
    182186
  • uspace/lib/ui/src/label.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    204204                goto error;
    205205
     206        rc = gfx_update(label->res->gc);
     207        if (rc != EOK)
     208                goto error;
     209
    206210        return EOK;
    207211error:
  • uspace/lib/ui/src/pbutton.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    303303                        goto error;
    304304        }
     305
     306        rc = gfx_update(pbutton->res->gc);
     307        if (rc != EOK)
     308                goto error;
    305309
    306310        return EOK;
  • uspace/lib/ui/src/rbutton.c

    ref734b7 r2ab8ab3  
    289289        rc = gfx_puttext(rbutton->group->res->font, &pos, &fmt,
    290290            rbutton->caption);
     291        if (rc != EOK)
     292                goto error;
     293
     294        rc = gfx_update(rbutton->group->res->gc);
    291295        if (rc != EOK)
    292296                goto error;
  • uspace/lib/ui/src/slider.c

    ref734b7 r2ab8ab3  
    303303
    304304        rc = gfx_fill_rect(slider->res->gc, &irect);
     305        if (rc != EOK)
     306                goto error;
     307
     308        rc = gfx_update(slider->res->gc);
    305309        if (rc != EOK)
    306310                goto error;
  • uspace/lib/ui/src/wdecor.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    236236        }
    237237
     238        rc = gfx_update(wdecor->res->gc);
     239        if (rc != EOK)
     240                return rc;
     241
    238242        return EOK;
    239243}
  • uspace/lib/ui/src/window.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    8484};
    8585
    86 static void ui_window_app_update(void *, gfx_rect_t *);
     86static void ui_window_invalidate(void *, gfx_rect_t *);
     87static void ui_window_update(void *);
     88static void ui_window_app_invalidate(void *, gfx_rect_t *);
     89static void ui_window_app_update(void *);
    8790
    8891/** Initialize window parameters structure.
     
    123126        ui_wdecor_t *wdecor = NULL;
    124127        dummy_gc_t *dgc = NULL;
     128        gfx_bitmap_params_t bparams;
     129        gfx_bitmap_alloc_t alloc;
     130        gfx_bitmap_t *bmp = NULL;
     131        mem_gc_t *memgc = NULL;
    125132        errno_t rc;
    126133
     
    196203        }
    197204
    198         rc = ui_resource_create(gc, &res);
     205#ifdef CONFIG_UI_CS_RENDER
     206        /* Create window bitmap */
     207        gfx_bitmap_params_init(&bparams);
     208#ifndef CONFIG_WIN_DOUBLE_BUF
     209        bparams.flags |= bmpf_direct_output;
     210#endif
     211
     212        /* Move rectangle so that top-left corner is 0,0 */
     213        gfx_rect_rtranslate(&params->rect.p0, &params->rect, &bparams.rect);
     214
     215        rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
     216        if (rc != EOK)
     217                goto error;
     218
     219        /* Create memory GC */
     220        rc = gfx_bitmap_get_alloc(bmp, &alloc);
     221        if (rc != EOK) {
     222                gfx_bitmap_destroy(window->app_bmp);
     223                return rc;
     224        }
     225
     226        rc = mem_gc_create(&bparams.rect, &alloc, ui_window_invalidate,
     227            ui_window_update, (void *) window, &memgc);
     228        if (rc != EOK) {
     229                gfx_bitmap_destroy(window->app_bmp);
     230                return rc;
     231        }
     232
     233        window->bmp = bmp;
     234        window->mgc = memgc;
     235        window->gc = mem_gc_get_ctx(memgc);
     236        window->realgc = gc;
     237#else
     238        (void) ui_window_update;
     239        (void) ui_window_invalidate;
     240        (void) alloc;
     241        (void) bparams;
     242        window->gc = gc;
     243#endif
     244        rc = ui_resource_create(window->gc, &res);
    199245        if (rc != EOK)
    200246                goto error;
     
    211257        window->dwindow = dwindow;
    212258        window->rect = dparams.rect;
    213         window->gc = gc;
     259
    214260        window->res = res;
    215261        window->wdecor = wdecor;
     
    222268        if (res != NULL)
    223269                ui_resource_destroy(res);
     270        if (memgc != NULL)
     271                mem_gc_delete(memgc);
     272        if (bmp != NULL)
     273                gfx_bitmap_destroy(bmp);
    224274        if (dgc != NULL)
    225275                dummygc_destroy(dgc);
     
    242292        ui_wdecor_destroy(window->wdecor);
    243293        ui_resource_destroy(window->res);
     294        if (0 && window->app_mgc != NULL)
     295                mem_gc_delete(window->app_mgc);
     296        if (0 && window->app_bmp != NULL)
     297                gfx_bitmap_destroy(window->app_bmp);
     298        if (window->mgc != NULL) {
     299                mem_gc_delete(window->mgc);
     300                window->gc = NULL;
     301        }
     302        if (window->bmp != NULL)
     303                gfx_bitmap_destroy(window->bmp);
    244304        gfx_context_delete(window->gc);
    245305        display_window_destroy(window->dwindow);
     
    294354        gfx_rect_t arect;
    295355        gfx_bitmap_t *app_bmp = NULL;
    296         gfx_bitmap_params_t params;
    297         gfx_bitmap_alloc_t alloc;
     356        gfx_bitmap_t *win_bmp = NULL;
     357        gfx_bitmap_params_t app_params;
     358        gfx_bitmap_params_t win_params;
     359        gfx_bitmap_alloc_t app_alloc;
     360        gfx_bitmap_alloc_t win_alloc;
    298361        errno_t rc;
    299362
     
    305368        gfx_rect_rtranslate(&offs, rect, &nrect);
    306369
     370        /* mgc != NULL iff client-side rendering */
     371        if (window->mgc != NULL) {
     372                /* Resize window bitmap */
     373                assert(window->bmp != NULL);
     374
     375                gfx_bitmap_params_init(&win_params);
     376#ifndef CONFIG_WIN_DOUBLE_BUF
     377                win_params.flags |= bmpf_direct_output;
     378#endif
     379                win_params.rect = nrect;
     380
     381                rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
     382                    &win_bmp);
     383                if (rc != EOK)
     384                        goto error;
     385
     386                rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
     387                if (rc != EOK)
     388                        goto error;
     389        }
     390
     391        /* Application area GC? */
    307392        if (window->app_gc != NULL) {
     393                /* Resize application bitmap */
    308394                assert(window->app_bmp != NULL);
    309395
    310                 gfx_bitmap_params_init(&params);
     396                gfx_bitmap_params_init(&app_params);
    311397
    312398                /*
     
    315401                 */
    316402                ui_wdecor_app_from_rect(window->wdecor->style, &nrect, &arect);
    317                 gfx_rect_rtranslate(&arect.p0, &arect, &params.rect);
    318 
    319                 rc = gfx_bitmap_create(window->gc, &params, NULL,
     403                gfx_rect_rtranslate(&arect.p0, &arect, &app_params.rect);
     404
     405                rc = gfx_bitmap_create(window->gc, &app_params, NULL,
    320406                    &app_bmp);
    321407                if (rc != EOK)
    322408                        goto error;
    323409
    324                 rc = gfx_bitmap_get_alloc(app_bmp, &alloc);
     410                rc = gfx_bitmap_get_alloc(app_bmp, &app_alloc);
    325411                if (rc != EOK)
    326412                        goto error;
     
    334420        }
    335421
     422        /* CLient side rendering? */
     423        if (window->mgc != NULL) {
     424                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
     425
     426                gfx_bitmap_destroy(window->bmp);
     427                window->bmp = win_bmp;
     428        }
     429
    336430        ui_wdecor_set_rect(window->wdecor, &nrect);
    337431        ui_wdecor_paint(window->wdecor);
    338 
     432        gfx_update(window->gc);
     433
     434        /* Application area GC? */
    339435        if (window->app_gc != NULL) {
    340                 mem_gc_retarget(window->app_mgc, &params.rect, &alloc);
     436                mem_gc_retarget(window->app_mgc, &app_params.rect, &app_alloc);
    341437
    342438                gfx_bitmap_destroy(window->app_bmp);
     
    348444        if (app_bmp != NULL)
    349445                gfx_bitmap_destroy(app_bmp);
     446        if (win_bmp != NULL)
     447                gfx_bitmap_destroy(win_bmp);
    350448        return rc;
    351449}
     
    420518                }
    421519
    422                 rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
    423                     (void *) window, &memgc);
     520                rc = mem_gc_create(&params.rect, &alloc, ui_window_app_invalidate,
     521                    ui_window_app_update, (void *) window, &memgc);
    424522                if (rc != EOK) {
    425523                        gfx_bitmap_destroy(window->app_bmp);
     
    696794                return ui_control_paint(window->control);
    697795
     796        rc = gfx_update(window->res->gc);
     797        if (rc != EOK)
     798                return rc;
     799
    698800        return EOK;
    699801}
     
    710812}
    711813
    712 /** Application area update callback
     814/** Window invalidate callback
    713815 *
    714816 * @param arg Argument (ui_window_t *)
    715817 * @param rect Rectangle to update
    716818 */
    717 static void ui_window_app_update(void *arg, gfx_rect_t *rect)
     819static void ui_window_invalidate(void *arg, gfx_rect_t *rect)
     820{
     821        ui_window_t *window = (ui_window_t *) arg;
     822        gfx_rect_t env;
     823
     824        gfx_rect_envelope(&window->dirty_rect, rect, &env);
     825        window->dirty_rect = env;
     826}
     827
     828/** Window update callback
     829 *
     830 * @param arg Argument (ui_window_t *)
     831 */
     832static void ui_window_update(void *arg)
     833{
     834        ui_window_t *window = (ui_window_t *) arg;
     835
     836        if (!gfx_rect_is_empty(&window->dirty_rect))
     837                (void) gfx_bitmap_render(window->bmp, &window->dirty_rect, NULL);
     838
     839        window->dirty_rect.p0.x = 0;
     840        window->dirty_rect.p0.y = 0;
     841        window->dirty_rect.p1.x = 0;
     842        window->dirty_rect.p1.y = 0;
     843}
     844
     845/** Application area invalidate callback
     846 *
     847 * @param arg Argument (ui_window_t *)
     848 * @param rect Rectangle to update
     849 */
     850static void ui_window_app_invalidate(void *arg, gfx_rect_t *rect)
    718851{
    719852        ui_window_t *window = (ui_window_t *) arg;
     
    724857        /* Render bitmap rectangle inside the application area */
    725858        (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
     859        /*
     860         * TODO Update applications to call gfx_update(), then
     861         * we can defer update to ui_window_app_update().
     862         */
     863        (void) gfx_update(window->res->gc);
     864}
     865
     866/** Application area update callback
     867 *
     868 * @param arg Argument (ui_window_t *)
     869 */
     870static void ui_window_app_update(void *arg)
     871{
     872        ui_window_t *window = (ui_window_t *) arg;
     873
     874        /*
     875         * Not used since display is updated immediately
     876         * in ui_window_app_invalidate
     877         */
     878        (void) window;
    726879}
    727880
  • uspace/lib/ui/test/window.c

    ref734b7 r2ab8ab3  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    258258        params.rect.p0.x = 0;
    259259        params.rect.p0.y = 0;
    260         params.rect.p0.x = 10;
    261         params.rect.p0.y = 10;
     260        params.rect.p0.x = 100;
     261        params.rect.p0.y = 100;
    262262
    263263        rc = ui_window_create(ui, &params, &window);
  • uspace/srv/hid/display/display.c

    ref734b7 r2ab8ab3  
    5050
    5151static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *);
    52 static void ds_display_update_cb(void *, gfx_rect_t *);
     52static void ds_display_invalidate_cb(void *, gfx_rect_t *);
     53static void ds_display_update_cb(void *);
    5354
    5455/** Create display.
     
    459460
    460461        rc = mem_gc_create(&disp->rect, &alloc,
    461             ds_display_update_cb, (void *) disp, &disp->bbgc);
     462            ds_display_invalidate_cb, ds_display_update_cb, (void *) disp,
     463            &disp->bbgc);
    462464        if (rc != EOK)
    463465                goto error;
     
    732734}
    733735
    734 /** Display update callback.
     736/** Display invalidate callback.
    735737 *
    736738 * Called by backbuffer memory GC when something is rendered into it.
     
    740742 * @param rect Rectangle to update
    741743 */
    742 static void ds_display_update_cb(void *arg, gfx_rect_t *rect)
     744static void ds_display_invalidate_cb(void *arg, gfx_rect_t *rect)
    743745{
    744746        ds_display_t *disp = (ds_display_t *) arg;
     
    749751}
    750752
     753/** Display update callback.
     754 *
     755 * @param arg Argument (display cast as void *)
     756 */
     757static void ds_display_update_cb(void *arg)
     758{
     759        ds_display_t *disp = (ds_display_t *) arg;
     760
     761        (void) disp;
     762}
     763
    751764/** @}
    752765 */
  • uspace/srv/hid/display/window.c

    ref734b7 r2ab8ab3  
    4949#include "window.h"
    5050
    51 static void ds_window_update_cb(void *, gfx_rect_t *);
     51static void ds_window_invalidate_cb(void *, gfx_rect_t *);
     52static void ds_window_update_cb(void *);
    5253static void ds_window_get_preview_rect(ds_window_t *, gfx_rect_t *);
    5354
     
    106107        }
    107108
    108         rc = mem_gc_create(&params->rect, &alloc, ds_window_update_cb,
    109             (void *)wnd, &wnd->mgc);
     109        rc = mem_gc_create(&params->rect, &alloc, ds_window_invalidate_cb,
     110            ds_window_update_cb, (void *)wnd, &wnd->mgc);
    110111        if (rc != EOK)
    111112                goto error;
     
    789790}
    790791
    791 /** Window memory GC update callback.
    792  *
    793  * This is called by the window's memory GC when a rectangle us updated.
    794  */
    795 static void ds_window_update_cb(void *arg, gfx_rect_t *rect)
     792/** Window memory GC invalidate callback.
     793 *
     794 * This is called by the window's memory GC when a rectangle is modified.
     795 */
     796static void ds_window_invalidate_cb(void *arg, gfx_rect_t *rect)
    796797{
    797798        ds_window_t *wnd = (ds_window_t *)arg;
     
    806807}
    807808
     809/** Window memory GC update callback.
     810 *
     811 * This is called by the window's memory GC when it is to be updated.
     812 */
     813static void ds_window_update_cb(void *arg)
     814{
     815        ds_window_t *wnd = (ds_window_t *)arg;
     816
     817        (void) wnd;
     818}
     819
    808820/** @}
    809821 */
Note: See TracChangeset for help on using the changeset viewer.