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

Changeset afcf704 in mainline


Ignore:
Timestamp:
2020-06-14T22:23:34Z (3 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
c45d8696
Parents:
28f8f6f2
Message:

Allow GUI direct access to window buffer

Files:
15 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r28f8f6f2 rafcf704  
    611611! [CONFIG_FB=y] CONFIG_DISP_DOUBLE_BUF (y/n)
    612612
     613% Window double buffering
     614! [CONFIG_FB=y] CONFIG_WIN_DOUBLE_BUF (n/y)
     615
    613616% Start AP processors by the loader
    614617! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c

    r28f8f6f2 rafcf704  
    382382        errno_t rc;
    383383
     384        /* Check that we support all required flags */
     385        if ((params->flags & ~bmpf_color_key) != 0)
     386                return ENOTSUP;
     387
    384388        dcbm = calloc(1, sizeof(amdm37x_bitmap_t));
    385389        if (dcbm == NULL)
     
    483487        gfx_rect_clip(&srect, &skfbrect, &crect);
    484488
     489        // XXX bmpf_color_key
    485490        for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
    486491                for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
  • uspace/drv/fb/kfb/port.c

    r28f8f6f2 rafcf704  
    199199        errno_t rc;
    200200
     201        /* Check that we support all required flags */
     202        if ((params->flags & ~bmpf_color_key) != 0)
     203                return ENOTSUP;
     204
    201205        kfbbm = calloc(1, sizeof(kfb_bitmap_t));
    202206        if (kfbbm == NULL)
  • uspace/lib/congfx/src/console.c

    r28f8f6f2 rafcf704  
    206206        errno_t rc;
    207207
     208        /* Check that we support all requested flags */
     209        if ((params->flags & ~bmpf_color_key) != 0)
     210                return ENOTSUP;
     211
    208212        cbm = calloc(1, sizeof(console_gc_bitmap_t));
    209213        if (cbm == NULL)
  • uspace/lib/gfx/include/gfx/coord.h

    r28f8f6f2 rafcf704  
    5555extern bool gfx_rect_is_empty(gfx_rect_t *);
    5656extern bool gfx_rect_is_incident(gfx_rect_t *, gfx_rect_t *);
     57extern bool gfx_rect_is_inside(gfx_rect_t *, gfx_rect_t *);
    5758extern bool gfx_pix_inside_rect(gfx_coord2_t *, gfx_rect_t *);
    5859
  • uspace/lib/gfx/include/types/gfx/bitmap.h

    r28f8f6f2 rafcf704  
    4848typedef enum {
    4949        /** Enable color key */
    50         bmpf_color_key = 0x1
     50        bmpf_color_key = 0x1,
     51        /** Directly map GC output into this bitmap */
     52        bmpf_direct_output = 0x2
    5153} gfx_bitmap_flags_t;
    5254
  • uspace/lib/gfx/src/coord.c

    r28f8f6f2 rafcf704  
    255255}
    256256
     257/** Return true if rectangle @a a is contained in rectangle @a b.
     258 *
     259 * @param a Inside rectangle
     260 * @param b Outside rectangle
     261 * @return @c true iff @a a is (non-strictly) inside @a b
     262 */
     263bool gfx_rect_is_inside(gfx_rect_t *a, gfx_rect_t *b)
     264{
     265        gfx_rect_t sa;
     266        gfx_rect_t sb;
     267
     268        gfx_rect_points_sort(a, &sa);
     269        gfx_rect_points_sort(b, &sb);
     270
     271        if (sa.p0.x < sb.p0.x || sa.p0.y < sb.p0.y)
     272                return false;
     273
     274        if (sa.p1.x > sb.p1.x || sa.p1.y > sb.p1.y)
     275                return false;
     276
     277        return true;
     278}
     279
    257280/** Get rectangle dimensions.
    258281 *
  • uspace/lib/gfx/test/coord.c

    r28f8f6f2 rafcf704  
    775775}
    776776
     777/** gfx_rect_is_inside is true for rectangle strictly inside */
     778PCUT_TEST(rect_is_inside_strict)
     779{
     780        gfx_rect_t a;
     781        gfx_rect_t b;
     782
     783        a.p0.x = 2;
     784        a.p0.y = 3;
     785        a.p1.x = 4;
     786        a.p1.y = 5;
     787
     788        b.p0.x = 1;
     789        b.p0.y = 2;
     790        b.p1.x = 5;
     791        b.p1.y = 6;
     792
     793        PCUT_ASSERT_TRUE(gfx_rect_is_inside(&a, &b));
     794}
     795
     796/** gfx_rect_is_inside is true for two equal rectangles */
     797PCUT_TEST(rect_is_inside_same)
     798{
     799        gfx_rect_t a;
     800        gfx_rect_t b;
     801
     802        a.p0.x = 1;
     803        a.p0.y = 2;
     804        a.p1.x = 3;
     805        a.p1.y = 4;
     806
     807        b.p0.x = 1;
     808        b.p0.y = 2;
     809        b.p1.x = 3;
     810        b.p1.y = 4;
     811
     812        PCUT_ASSERT_TRUE(gfx_rect_is_inside(&a, &b));
     813}
     814
     815/** gfx_rect_is_inside is false for @c a.p0 outside */
     816PCUT_TEST(rect_is_inside_p0_outside)
     817{
     818        gfx_rect_t a;
     819        gfx_rect_t b;
     820
     821        a.p0.x = 0;
     822        a.p0.y = 2;
     823        a.p1.x = 3;
     824        a.p1.y = 4;
     825
     826        b.p0.x = 1;
     827        b.p0.y = 2;
     828        b.p1.x = 3;
     829        b.p1.y = 4;
     830
     831        PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
     832
     833        a.p0.x = 1;
     834        a.p0.y = 1;
     835        a.p1.x = 3;
     836        a.p1.y = 4;
     837
     838        b.p0.x = 1;
     839        b.p0.y = 2;
     840        b.p1.x = 3;
     841        b.p1.y = 4;
     842
     843        PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
     844}
     845
     846/** gfx_rect_is_inside is false for @c a.p1 outside */
     847PCUT_TEST(rect_is_inside_p1_outside)
     848{
     849        gfx_rect_t a;
     850        gfx_rect_t b;
     851
     852        a.p0.x = 1;
     853        a.p0.y = 2;
     854        a.p1.x = 4;
     855        a.p1.y = 4;
     856
     857        b.p0.x = 1;
     858        b.p0.y = 2;
     859        b.p1.x = 3;
     860        b.p1.y = 4;
     861
     862        PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
     863
     864        a.p0.x = 1;
     865        a.p0.y = 2;
     866        a.p1.x = 3;
     867        a.p1.y = 5;
     868
     869        b.p0.x = 1;
     870        b.p0.y = 2;
     871        b.p1.x = 3;
     872        b.p1.y = 4;
     873
     874        PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
     875}
     876
    777877/** gfx_pix_inside_rect for  */
    778878PCUT_TEST(pix_inside_rect)
  • uspace/lib/gui/window.c

    r28f8f6f2 rafcf704  
    414414        }
    415415
    416         /* Allocate resources for new surface. */
    417         surface_t *new_surface = surface_create(width, height, NULL,
    418             SURFACE_FLAG_SHARED);
    419         if (!new_surface)
    420                 return;
    421 
    422         gfx_bitmap_params_init(&params);
    423         params.rect.p0.x = 0;
    424         params.rect.p0.y = 0;
    425         params.rect.p1.x = width;
    426         params.rect.p1.y = height;
    427 
    428         alloc.pitch = width * sizeof(uint32_t);
    429         alloc.off0 = 0;
    430         alloc.pixels = surface_direct_access(new_surface);
    431 
    432         rc = gfx_bitmap_create(win->gc, &params, &alloc, &new_bitmap);
    433         if (rc != EOK) {
    434                 surface_destroy(new_surface);
    435                 return;
    436         }
    437 
    438         /* Switch new and old surface. */
    439416        fibril_mutex_lock(&win->guard);
    440         surface_t *old_surface = win->surface;
    441         gfx_bitmap_t *old_bitmap = win->bitmap;
    442         win->surface = new_surface;
    443         win->bitmap = new_bitmap;
    444         fibril_mutex_unlock(&win->guard);
    445 
    446         /*
    447          * Let all widgets in the tree alter their position and size.
    448          * Widgets might also paint themselves onto the new surface.
    449          */
    450         win->root.rearrange(&win->root, 0, 0, width, height);
    451 
    452         fibril_mutex_lock(&win->guard);
    453         surface_reset_damaged_region(win->surface);
    454         fibril_mutex_unlock(&win->guard);
     417
     418        /* Deallocate old bitmap. */
     419        if (win->bitmap != NULL) {
     420                gfx_bitmap_destroy(win->bitmap);
     421                win->bitmap = NULL;
     422        }
     423
     424        /* Deallocate old surface. */
     425        if (win->surface != NULL) {
     426                surface_destroy(win->surface);
     427                win->surface = NULL;
     428        }
    455429
    456430        /* Resize the display window. */
     
    463437
    464438        rc = display_window_resize(win->dwindow, &offs, &nrect);
     439        if (rc != EOK)
     440                return;
     441
     442        gfx_bitmap_params_init(&params);
     443#ifndef CONFIG_WIN_DOUBLE_BUF
     444        params.flags = bmpf_direct_output;
     445#else
     446        params.flags = 0;
     447#endif
     448        params.rect.p0.x = 0;
     449        params.rect.p0.y = 0;
     450        params.rect.p1.x = width;
     451        params.rect.p1.y = height;
     452
     453        rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
    465454        if (rc != EOK) {
    466                 /* Rollback to old surface. Reverse all changes. */
    467 
    468                 sysarg_t old_width = 0;
    469                 sysarg_t old_height = 0;
    470                 if (old_surface)
    471                         surface_get_resolution(old_surface, &old_width, &old_height);
    472 
    473                 fibril_mutex_lock(&win->guard);
    474                 new_surface = win->surface;
    475                 win->surface = old_surface;
    476                 win->bitmap = old_bitmap;
     455                if (rc == ENOTSUP) {
     456                        /* Direct output is not supported */
     457                        params.flags &= ~bmpf_direct_output;
     458                        rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
     459                        if (rc != EOK) {
     460                                fibril_mutex_unlock(&win->guard);
     461                                return;
     462                        }
     463                }
     464        }
     465
     466        rc = gfx_bitmap_get_alloc(new_bitmap, &alloc);
     467        if (rc != EOK) {
    477468                fibril_mutex_unlock(&win->guard);
    478 
    479                 win->root.rearrange(&win->root, 0, 0, old_width, old_height);
    480 
    481                 if (win->surface) {
    482                         fibril_mutex_lock(&win->guard);
    483                         surface_reset_damaged_region(win->surface);
    484                         fibril_mutex_unlock(&win->guard);
    485                 }
    486 
    487                 surface_destroy(new_surface);
    488                 return;
    489         }
    490 
    491         if (old_bitmap != NULL)
    492                 gfx_bitmap_destroy(old_bitmap);
    493         /* Deallocate old surface. */
    494         if (old_surface)
    495                 surface_destroy(old_surface);
     469                return;
     470        }
     471
     472        /* Allocate new surface. */
     473        surface_t *new_surface = surface_create(width, height, alloc.pixels, 0);
     474        if (!new_surface) {
     475                gfx_bitmap_destroy(new_bitmap);
     476                fibril_mutex_unlock(&win->guard);
     477                return;
     478        }
     479
     480        /* Switch in new surface and bitmap. */
     481        win->surface = new_surface;
     482        win->bitmap = new_bitmap;
     483        fibril_mutex_unlock(&win->guard);
     484
     485        /*
     486         * Let all widgets in the tree alter their position and size.
     487         * Widgets might also paint themselves onto the new surface.
     488         */
     489        win->root.rearrange(&win->root, 0, 0, width, height);
     490
     491        fibril_mutex_lock(&win->guard);
     492        surface_reset_damaged_region(win->surface);
     493        fibril_mutex_unlock(&win->guard);
    496494
    497495        if (placement_flags != WINDOW_PLACEMENT_ANY) {
  • 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
  • uspace/lib/memgfx/src/memgc.c

    r28f8f6f2 rafcf704  
    3737 */
    3838
     39#include <as.h>
    3940#include <assert.h>
    4041#include <gfx/color.h>
     
    223224        errno_t rc;
    224225
     226        /* Check that we support all requested flags */
     227        if ((params->flags & ~(bmpf_color_key | bmpf_direct_output)) != 0)
     228                return ENOTSUP;
     229
    225230        mbm = calloc(1, sizeof(mem_gc_bitmap_t));
    226231        if (mbm == NULL)
     
    232237        mbm->key_color = params->key_color;
    233238
    234         if (alloc == NULL) {
     239        if ((params->flags & bmpf_direct_output) != 0) {
     240                /* Caller cannot specify allocation for direct output */
     241                if (alloc != NULL) {
     242                        rc = EINVAL;
     243                        goto error;
     244                }
     245
     246                /* Bounding rectangle must be within GC bounding rectangle */
     247                if (!gfx_rect_is_inside(&mbm->rect, &mgc->rect)) {
     248                        rc = EINVAL;
     249                        goto error;
     250                }
     251
     252                mbm->alloc = mgc->alloc;
     253
     254                /* Don't free pixel array when destroying bitmap */
     255                mbm->myalloc = false;
     256        } else if (alloc == NULL) {
     257#if 0
     258                /*
     259                 * TODO: If the bitmap is not required to be sharable,
     260                 * we could allocate it with a simple malloc.
     261                 * Need to have a bitmap flag specifying that the
     262                 * allocation should be sharable. IPC GC could
     263                 * automatically add this flag
     264                 */
    235265                mbm->alloc.pitch = dim.x * sizeof(uint32_t);
    236266                mbm->alloc.off0 = 0;
     
    242272                        goto error;
    243273                }
     274#endif
     275                mbm->alloc.pitch = dim.x * sizeof(uint32_t);
     276                mbm->alloc.off0 = 0;
     277                mbm->alloc.pixels = as_area_create(AS_AREA_ANY,
     278                    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
     279                    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     280                mbm->myalloc = true;
     281
     282                if (mbm->alloc.pixels == AS_MAP_FAILED) {
     283                        rc = ENOMEM;
     284                        goto error;
     285                }
    244286        } else {
    245287                mbm->alloc = *alloc;
     
    263305{
    264306        mem_gc_bitmap_t *mbm = (mem_gc_bitmap_t *)bm;
    265         if (mbm->myalloc)
     307        if (mbm->myalloc) {
     308#if 0
     309                /* TODO: if we alloc allocating the bitmap with malloc */
    266310                free(mbm->alloc.pixels);
     311#endif
     312                as_area_destroy(mbm->alloc.pixels);
     313        }
    267314
    268315        free(mbm);
     
    317364        dmap.data = mbm->mgc->alloc.pixels;
    318365
    319         if ((mbm->flags & bmpf_color_key) == 0) {
     366        if ((mbm->flags & bmpf_direct_output) != 0) {
     367                /* Nothing to do */
     368        } else if ((mbm->flags & bmpf_color_key) == 0) {
    320369                for (y = drect.p0.y; y < drect.p1.y; y++) {
    321370                        for (x = drect.p0.x; x < drect.p1.x; x++) {
  • uspace/srv/hid/rfb/main.c

    r28f8f6f2 rafcf704  
    195195        errno_t rc;
    196196
     197        /* Check that we support all required flags */
     198        if ((params->flags & ~bmpf_color_key) != 0)
     199                return ENOTSUP;
     200
    197201        rfbbm = calloc(1, sizeof(rfb_bitmap_t));
    198202        if (rfbbm == NULL)
Note: See TracChangeset for help on using the changeset viewer.