Changeset afcf704 in mainline for uspace/lib/ipcgfx


Ignore:
Timestamp:
2020-06-14T22:23:34Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c45d8696
Parents:
28f8f6f2
Message:

Allow GUI direct access to window buffer

Location:
uspace/lib/ipcgfx
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h

    r28f8f6f2 rafcf704  
    4242        GC_FILL_RECT,
    4343        GC_BITMAP_CREATE,
     44        GC_BITMAP_CREATE_DOUTPUT,
    4445        GC_BITMAP_DESTROY,
    4546        GC_BITMAP_RENDER,
  • uspace/lib/ipcgfx/src/client.c

    r28f8f6f2 rafcf704  
    108108}
    109109
    110 /** Create bitmap in IPC GC.
     110/** Create normal bitmap in IPC GC.
    111111 *
    112112 * @param arg IPC GC
     
    116116 * @return EOK on success or an error code
    117117 */
    118 errno_t ipc_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     118static errno_t ipc_gc_bitmap_create_normal(void *arg,
     119    gfx_bitmap_params_t *params,
    119120    gfx_bitmap_alloc_t *alloc, void **rbm)
    120121{
     
    209210}
    210211
     212/** Create direct output bitmap in IPC GC.
     213 *
     214 * @param arg IPC GC
     215 * @param params Bitmap params
     216 * @param alloc Bitmap allocation info or @c NULL
     217 * @param rbm Place to store pointer to new bitmap
     218 * @return EOK on success or an error code
     219 */
     220static errno_t ipc_gc_bitmap_create_direct_output(void *arg,
     221    gfx_bitmap_params_t *params,
     222    gfx_bitmap_alloc_t *alloc, void **rbm)
     223{
     224        ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
     225        ipc_gc_bitmap_t *ipcbm = NULL;
     226        gfx_coord2_t dim;
     227        async_exch_t *exch = NULL;
     228        void *pixels;
     229        ipc_call_t answer;
     230        size_t asize;
     231        aid_t req;
     232        errno_t rc;
     233
     234        /* Cannot specify allocation for direct output bitmap */
     235        if (alloc != NULL)
     236                return EINVAL;
     237
     238        ipcbm = calloc(1, sizeof(ipc_gc_bitmap_t));
     239        if (ipcbm == NULL)
     240                return ENOMEM;
     241
     242        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     243        ipcbm->rect = params->rect;
     244
     245        ipcbm->alloc.pitch = dim.x * sizeof(uint32_t);
     246        ipcbm->alloc.off0 = 0;
     247        ipcbm->myalloc = true;
     248
     249        asize = PAGES2SIZE(SIZE2PAGES(ipcbm->alloc.pitch * dim.y));
     250
     251        exch = async_exchange_begin(ipcgc->sess);
     252        req = async_send_0(exch, GC_BITMAP_CREATE_DOUTPUT, &answer);
     253        rc = async_data_write_start(exch, params, sizeof (gfx_bitmap_params_t));
     254        if (rc != EOK) {
     255                async_forget(req);
     256                goto error;
     257        }
     258
     259        rc = async_share_in_start_0_0(exch, asize, &pixels);
     260        if (rc != EOK) {
     261                async_forget(req);
     262                goto error;
     263        }
     264        async_exchange_end(exch);
     265        exch = NULL;
     266
     267        async_wait_for(req, &rc);
     268        if (rc != EOK)
     269                goto error;
     270
     271        ipcbm->ipcgc = ipcgc;
     272        ipcbm->bmp_id = ipc_get_arg1(&answer);
     273        ipcbm->alloc.pixels = pixels;
     274        *rbm = (void *)ipcbm;
     275        return EOK;
     276error:
     277        if (exch != NULL)
     278                async_exchange_end(exch);
     279        if (ipcbm != NULL) {
     280                if (ipcbm->alloc.pixels != NULL)
     281                        as_area_destroy(ipcbm->alloc.pixels);
     282                free(ipcbm);
     283        }
     284        return rc;
     285}
     286
     287/** Create bitmap in IPC GC.
     288 *
     289 * @param arg IPC GC
     290 * @param params Bitmap params
     291 * @param alloc Bitmap allocation info or @c NULL
     292 * @param rbm Place to store pointer to new bitmap
     293 * @return EOK on success or an error code
     294 */
     295errno_t ipc_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     296    gfx_bitmap_alloc_t *alloc, void **rbm)
     297{
     298        if ((params->flags & bmpf_direct_output) != 0) {
     299                return ipc_gc_bitmap_create_direct_output(arg, params, alloc,
     300                    rbm);
     301        } else {
     302                return ipc_gc_bitmap_create_normal(arg, params, alloc, rbm);
     303        }
     304}
     305
    211306/** Destroy bitmap in IPC GC.
    212307 *
  • uspace/lib/ipcgfx/src/server.c

    r28f8f6f2 rafcf704  
    128128        /* Check size */
    129129        if (size != PAGES2SIZE(SIZE2PAGES(dim.x * dim.y * sizeof(uint32_t)))) {
    130                 printf("size=%zu, expected=%zu\n", size, dim.x * dim.y * sizeof(uint32_t));
    131130                async_answer_0(icall, EINVAL);
    132131                return;
     
    168167}
    169168
     169static void gc_bitmap_create_doutput_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
     170{
     171        gfx_bitmap_params_t params;
     172        gfx_bitmap_alloc_t alloc;
     173        gfx_bitmap_t *bitmap;
     174        gfx_coord2_t dim;
     175        ipc_gc_srv_bitmap_t *srvbmp = NULL;
     176        ipc_call_t call;
     177        size_t size;
     178        errno_t rc;
     179
     180        if (!async_data_write_receive(&call, &size)) {
     181                async_answer_0(&call, EREFUSED);
     182                async_answer_0(icall, EREFUSED);
     183                return;
     184        }
     185
     186        if (size != sizeof(gfx_bitmap_params_t)) {
     187                async_answer_0(&call, EINVAL);
     188                async_answer_0(icall, EINVAL);
     189                return;
     190        }
     191
     192        rc = async_data_write_finalize(&call, &params, size);
     193        if (rc != EOK) {
     194                async_answer_0(&call, rc);
     195                async_answer_0(icall, rc);
     196                return;
     197        }
     198
     199        /* Bitmap dimensions */
     200        gfx_coord2_subtract(&params.rect.p1, &params.rect.p0, &dim);
     201
     202        if (!async_share_in_receive(&call, &size)) {
     203                async_answer_0(icall, EINVAL);
     204                return;
     205        }
     206
     207        /* Check size */
     208        if (size != PAGES2SIZE(SIZE2PAGES(dim.x * dim.y * sizeof(uint32_t)))) {
     209                async_answer_0(&call, EINVAL);
     210                async_answer_0(icall, EINVAL);
     211                return;
     212        }
     213
     214        rc = gfx_bitmap_create(srvgc->gc, &params, NULL, &bitmap);
     215        if (rc != EOK) {
     216                async_answer_0(&call, rc);
     217                async_answer_0(icall, rc);
     218                return;
     219        }
     220
     221        rc = gfx_bitmap_get_alloc(bitmap, &alloc);
     222        if (rc != EOK) {
     223                gfx_bitmap_destroy(bitmap);
     224                async_answer_0(&call, rc);
     225                async_answer_0(icall, rc);
     226                return;
     227        }
     228
     229        rc = async_share_in_finalize(&call, alloc.pixels, AS_AREA_READ |
     230            AS_AREA_WRITE | AS_AREA_CACHEABLE);
     231        if (rc != EOK) {
     232                gfx_bitmap_destroy(bitmap);
     233                async_answer_0(icall, EIO);
     234                return;
     235        }
     236
     237        srvbmp = calloc(1, sizeof(ipc_gc_srv_bitmap_t));
     238        if (srvbmp == NULL) {
     239                gfx_bitmap_destroy(bitmap);
     240                async_answer_0(icall, ENOMEM);
     241                return;
     242        }
     243
     244        srvbmp->srvgc = srvgc;
     245        list_append(&srvbmp->lbitmaps, &srvgc->bitmaps);
     246        srvbmp->bmp = bitmap;
     247        srvbmp->bmp_id = srvgc->next_bmp_id++;
     248        printf("gc_bitmap_create_doutput_srv: storing bmp_id=%u\n",
     249            (unsigned) srvbmp->bmp_id);
     250
     251        async_answer_1(icall, EOK, srvbmp->bmp_id);
     252}
     253
    170254static void gc_bitmap_destroy_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
    171255{
     
    270354                        gc_bitmap_create_srv(&srvgc, &call);
    271355                        break;
     356                case GC_BITMAP_CREATE_DOUTPUT:
     357                        gc_bitmap_create_doutput_srv(&srvgc, &call);
     358                        break;
    272359                case GC_BITMAP_DESTROY:
    273360                        gc_bitmap_destroy_srv(&srvgc, &call);
  • uspace/lib/ipcgfx/test/ipcgfx.c

    r28f8f6f2 rafcf704  
    2727 */
    2828
     29#include <as.h>
    2930#include <async.h>
    3031#include <errno.h>
     
    9697typedef struct {
    9798        test_response_t *resp;
     99        gfx_bitmap_alloc_t alloc;
    98100} test_bitmap_t;
    99101
     
    474476}
    475477
     478/** gfx_bitmap_create direct output bitmap with server returning failure */
     479PCUT_TEST(bitmap_create_dout_failure)
     480{
     481        errno_t rc;
     482        service_id_t sid;
     483        test_response_t resp;
     484        gfx_context_t *gc;
     485        gfx_bitmap_params_t params;
     486        gfx_bitmap_t *bitmap;
     487        async_sess_t *sess;
     488        ipc_gc_t *ipcgc;
     489
     490        async_set_fallback_port_handler(test_ipcgc_conn, &resp);
     491
     492        // FIXME This causes this test to be non-reentrant!
     493        rc = loc_server_register(test_ipcgfx_server);
     494        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     495
     496        rc = loc_service_register(test_ipcgfx_svc, &sid);
     497        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     498
     499        sess = loc_service_connect(sid, INTERFACE_GC, 0);
     500        PCUT_ASSERT_NOT_NULL(sess);
     501
     502        rc = ipc_gc_create(sess, &ipcgc);
     503        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     504
     505        gc = ipc_gc_get_ctx(ipcgc);
     506        PCUT_ASSERT_NOT_NULL(gc);
     507
     508        resp.rc = ENOMEM;
     509        resp.bitmap_create_called = false;
     510
     511        gfx_bitmap_params_init(&params);
     512        params.flags = bmpf_direct_output;
     513        params.rect.p0.x = 1;
     514        params.rect.p0.y = 2;
     515        params.rect.p1.x = 3;
     516        params.rect.p1.y = 4;
     517        bitmap = NULL;
     518        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     519        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     520        PCUT_ASSERT_TRUE(resp.bitmap_create_called);
     521        PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
     522        PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
     523        PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
     524        PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
     525        PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
     526            sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
     527        PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
     528        PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
     529        PCUT_ASSERT_NULL(bitmap);
     530
     531        ipc_gc_delete(ipcgc);
     532        async_hangup(sess);
     533
     534        rc = loc_service_unregister(sid);
     535        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     536}
     537
     538/** gfx_bitmap_create direct output bitmap with server returning success */
     539PCUT_TEST(bitmap_create_dout_success)
     540{
     541        errno_t rc;
     542        service_id_t sid;
     543        test_response_t resp;
     544        gfx_context_t *gc;
     545        gfx_bitmap_params_t params;
     546        gfx_bitmap_t *bitmap;
     547        async_sess_t *sess;
     548        ipc_gc_t *ipcgc;
     549
     550        async_set_fallback_port_handler(test_ipcgc_conn, &resp);
     551
     552        // FIXME This causes this test to be non-reentrant!
     553        rc = loc_server_register(test_ipcgfx_server);
     554        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     555
     556        rc = loc_service_register(test_ipcgfx_svc, &sid);
     557        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     558
     559        sess = loc_service_connect(sid, INTERFACE_GC, 0);
     560        PCUT_ASSERT_NOT_NULL(sess);
     561
     562        rc = ipc_gc_create(sess, &ipcgc);
     563        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     564
     565        gc = ipc_gc_get_ctx(ipcgc);
     566        PCUT_ASSERT_NOT_NULL(gc);
     567
     568        resp.rc = EOK;
     569        resp.bitmap_create_called = false;
     570
     571        gfx_bitmap_params_init(&params);
     572        params.flags = bmpf_direct_output;
     573        params.rect.p0.x = 1;
     574        params.rect.p0.y = 2;
     575        params.rect.p1.x = 3;
     576        params.rect.p1.y = 4;
     577        bitmap = NULL;
     578        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     579        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     580        PCUT_ASSERT_TRUE(resp.bitmap_create_called);
     581        PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
     582        PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
     583        PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
     584        PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
     585        PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
     586            sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
     587        PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
     588        PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
     589        PCUT_ASSERT_NOT_NULL(bitmap);
     590
     591        resp.bitmap_destroy_called = false;
     592        rc = gfx_bitmap_destroy(bitmap);
     593        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     594        PCUT_ASSERT_TRUE(resp.bitmap_destroy_called);
     595
     596        ipc_gc_delete(ipcgc);
     597        async_hangup(sess);
     598
     599        rc = loc_service_unregister(sid);
     600        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     601}
     602
    476603/** gfx_bitmap_render with server returning failure */
    477604PCUT_TEST(bitmap_render_failure)
     
    733860        test_response_t *resp = (test_response_t *) arg;
    734861        test_bitmap_t *bitmap;
     862        gfx_coord2_t dim;
    735863
    736864        resp->bitmap_create_called = true;
    737865        resp->bitmap_create_params = *params;
    738         resp->bitmap_create_alloc = *alloc;
     866
     867        if ((params->flags & bmpf_direct_output) != 0) {
     868                gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     869
     870                resp->bitmap_create_alloc.pitch = dim.x * sizeof(uint32_t);
     871                resp->bitmap_create_alloc.off0 = 0;
     872                resp->bitmap_create_alloc.pixels = as_area_create(AS_AREA_ANY,
     873                    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
     874                    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     875                if (resp->bitmap_create_alloc.pixels == AS_MAP_FAILED)
     876                        return ENOMEM;
     877        } else {
     878                resp->bitmap_create_alloc = *alloc;
     879        }
    739880
    740881        if (resp->rc != EOK)
     
    746887
    747888        bitmap->resp = resp;
     889        bitmap->alloc = resp->bitmap_create_alloc;
    748890        *rbm = (void *) bitmap;
    749891        return EOK;
     
    763905        if (resp->rc != EOK)
    764906                return resp->rc;
     907
     908        if ((resp->bitmap_create_params.flags & bmpf_direct_output) != 0)
     909                as_area_destroy(resp->bitmap_create_alloc.pixels);
    765910
    766911        free(bitmap);
     
    795940static errno_t test_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    796941{
    797         /* Currently IPC GC does not pass this method to the server */
    798         return ENOTSUP;
     942        test_bitmap_t *bitmap = (test_bitmap_t *) bm;
     943
     944        *alloc = bitmap->alloc;
     945        return EOK;
    799946}
    800947
Note: See TracChangeset for help on using the changeset viewer.