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

Changeset 8aef01c in mainline


Ignore:
Timestamp:
2020-06-07T10:18:14Z (4 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
a65b0c8
Parents:
6301a24f
git-author:
Jiri Svoboda <jiri@…> (2020-06-07 10:11:32)
git-committer:
Jiri Svoboda <jiri@…> (2020-06-07 10:18:14)
Message:

Configurable display double-buffering

On by default (since turning off creates flicker in the absence of
front-to-back rendering). This is the quick and dirty way: display
server renders locally to a bitmap (using mem GC) and renders the
bitmap when ready.

The more sophisticated way would be to implement buffering in the
display device. That would require, however, enhancing the protocols
to communicate frame boundaries.

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r6301a24f r8aef01c  
    608608! [(PLATFORM=ia32|PLATFORM=amd64|MACHINE=beagleboardxm)&CONFIG_HID_OUT!=none&CONFIG_FB=y] CONFIG_BFB_BPP (choice)
    609609
     610% Display double buffering
     611! [CONFIG_FB=y] CONFIG_DISP_DOUBLE_BUF (y/n)
     612
    610613% Start AP processors by the loader
    611614! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
  • uspace/lib/memgfx/src/memgc.c

    r6301a24f r8aef01c  
    284284        gfx_rect_t drect;
    285285        gfx_coord2_t offs;
    286         gfx_coord2_t dim;
    287286        gfx_coord_t x, y;
    288287        pixelmap_t smap;
     
    305304        gfx_rect_translate(&offs, &srect, &drect);
    306305
    307         gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
    308 
    309         assert(mbm->rect.p0.x == 0);
    310         assert(mbm->rect.p0.y == 0);
    311         assert(mbm->alloc.pitch == mbm->rect.p1.x * (int)sizeof(uint32_t));
    312         smap.width = mbm->rect.p1.x;
    313         smap.height = mbm->rect.p1.y;
     306        assert(mbm->alloc.pitch == (mbm->rect.p1.x - mbm->rect.p0.x) *
     307            (int)sizeof(uint32_t));
     308        smap.width = mbm->rect.p1.x - mbm->rect.p0.x;
     309        smap.height = mbm->rect.p1.y - mbm->rect.p0.y;
    314310        smap.data = mbm->alloc.pixels;
    315311
     
    324320                for (y = drect.p0.y; y < drect.p1.y; y++) {
    325321                        for (x = drect.p0.x; x < drect.p1.x; x++) {
    326                                 pixel = pixelmap_get_pixel(&smap, x - offs.x,
    327                                     y - offs.y);
     322                                pixel = pixelmap_get_pixel(&smap,
     323                                    x - mbm->rect.p0.x - offs.x,
     324                                    y - mbm->rect.p0.y - offs.y);
    328325                                pixelmap_put_pixel(&dmap, x, y, pixel);
    329326                        }
     
    332329                for (y = drect.p0.y; y < drect.p1.y; y++) {
    333330                        for (x = drect.p0.x; x < drect.p1.x; x++) {
    334                                 pixel = pixelmap_get_pixel(&smap, x - offs.x,
    335                                     y - offs.y);
     331                                pixel = pixelmap_get_pixel(&smap,
     332                                    x - mbm->rect.p0.x - offs.x,
     333                                    y - mbm->rect.p0.y - offs.y);
    336334                                if (pixel != mbm->key_color)
    337335                                        pixelmap_put_pixel(&dmap, x, y, pixel);
  • uspace/srv/hid/display/ddev.c

    r6301a24f r8aef01c  
    5959{
    6060        ds_ddev_t *ddev;
     61        errno_t rc;
    6162
    6263        ddev = calloc(1, sizeof(ds_ddev_t));
     
    7071        ddev->info = *info;
    7172
    72         ds_display_add_ddev(display, ddev);
     73        rc = ds_display_add_ddev(display, ddev);
     74        if (rc != EOK) {
     75                free(ddev);
     76                return rc;
     77        }
    7378
    7479        *rddev = ddev;
  • uspace/srv/hid/display/display.c

    r6301a24f r8aef01c  
    3535
    3636#include <errno.h>
     37#include <gfx/bitmap.h>
    3738#include <gfx/context.h>
    3839#include <gfx/render.h>
    3940#include <io/log.h>
     41#include <memgfx/memgc.h>
    4042#include <stdlib.h>
    4143#include "client.h"
     
    4648#include "display.h"
    4749
     50static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *);
     51static void ds_display_update_cb(void *, gfx_rect_t *);
     52
    4853/** Create display.
    4954 *
    5055 * @param gc Graphics context for displaying output
     56 * @param flags Display flags
    5157 * @param rdisp Place to store pointer to new display.
    5258 * @return EOK on success, ENOMEM if out of memory
    5359 */
    54 errno_t ds_display_create(gfx_context_t *gc, ds_display_t **rdisp)
     60errno_t ds_display_create(gfx_context_t *gc, ds_display_flags_t flags,
     61    ds_display_t **rdisp)
    5562{
    5663        ds_display_t *disp;
     
    8693        list_initialize(&disp->seats);
    8794        list_initialize(&disp->windows);
     95        disp->flags = flags;
    8896        *rdisp = disp;
    8997        return EOK;
     
    423431}
    424432
     433/** Allocate back buffer for display.
     434 *
     435 * @param disp Display
     436 * @return EOK on success or if no back buffer is required, otherwise
     437 *         an error code.
     438 */
     439static errno_t ds_display_alloc_backbuf(ds_display_t *disp)
     440{
     441        gfx_context_t *ugc;
     442        gfx_bitmap_params_t params;
     443        gfx_bitmap_alloc_t alloc;
     444        errno_t rc;
     445
     446        /* Allocate backbuffer */
     447        if ((disp->flags & df_disp_double_buf) == 0) {
     448                /* Not double buffering. Nothing to do. */
     449                return EOK;
     450        }
     451
     452        ugc = ds_display_get_unbuf_gc(disp);
     453
     454        gfx_bitmap_params_init(&params);
     455        params.rect = disp->rect;
     456
     457        rc = gfx_bitmap_create(ugc, &params, NULL,
     458            &disp->backbuf);
     459        if (rc != EOK)
     460                goto error;
     461
     462        rc = gfx_bitmap_get_alloc(disp->backbuf, &alloc);
     463        if (rc != EOK)
     464                goto error;
     465
     466        rc = mem_gc_create(&disp->rect, &alloc,
     467            ds_display_update_cb, (void *) disp, &disp->bbgc);
     468        if (rc != EOK)
     469                goto error;
     470
     471        disp->dirty_rect.p0.x = 0;
     472        disp->dirty_rect.p0.y = 0;
     473        disp->dirty_rect.p1.x = 0;
     474        disp->dirty_rect.p1.y = 0;
     475
     476        return EOK;
     477error:
     478        if (disp->backbuf != NULL) {
     479                gfx_bitmap_destroy(disp->backbuf);
     480                disp->backbuf = NULL;
     481        }
     482
     483        return rc;
     484}
     485
    425486/** Add display device to display.
    426487 *
    427488 * @param disp Display
    428489 * @param ddev Display device
    429  */
    430 void ds_display_add_ddev(ds_display_t *disp, ds_ddev_t *ddev)
    431 {
     490 * @return EOK on success, or an error code
     491 */
     492errno_t ds_display_add_ddev(ds_display_t *disp, ds_ddev_t *ddev)
     493{
     494        errno_t rc;
     495
    432496        assert(ddev->display == NULL);
    433497        assert(!link_used(&ddev->lddevs));
    434498
    435         /* Set display dimensions to dimensions of first display device */
    436         if (gfx_rect_is_empty(&disp->rect))
    437                 disp->rect = ddev->info.rect;
    438 
    439499        ddev->display = disp;
    440500        list_append(&ddev->lddevs, &disp->ddevs);
     501
     502        /* First display device */
     503        if (gfx_rect_is_empty(&disp->rect)) {
     504                /* Set screen dimensions */
     505                disp->rect = ddev->info.rect;
     506
     507                /* Allocate backbuffer */
     508                rc = ds_display_alloc_backbuf(disp);
     509                if (rc != EOK)
     510                        goto error;
     511        }
     512
     513        return EOK;
     514error:
     515        disp->rect.p0.x = 0;
     516        disp->rect.p0.y = 0;
     517        disp->rect.p1.x = 0;
     518        disp->rect.p1.y = 0;
     519        list_remove(&ddev->lddevs);
     520        return rc;
    441521}
    442522
     
    506586
    507587// XXX
    508 gfx_context_t *ds_display_get_gc(ds_display_t *display)
     588static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *display)
    509589{
    510590        ds_ddev_t *ddev;
     
    515595
    516596        return ddev->gc;
     597}
     598
     599// XXX
     600gfx_context_t *ds_display_get_gc(ds_display_t *display)
     601{
     602        if ((display->flags & df_disp_double_buf) != 0)
     603                return mem_gc_get_ctx(display->bbgc);
     604        else
     605                return ds_display_get_unbuf_gc(display);
    517606}
    518607
     
    542631
    543632        return gfx_fill_rect(gc, &crect);
     633}
     634
     635/** Update front buffer from back buffer.
     636 *
     637 * If the display is not double-buffered, no action is taken.
     638 *
     639 * @param disp Display
     640 * @return EOK on success, or an error code
     641 */
     642static errno_t ds_display_update(ds_display_t *disp)
     643{
     644        errno_t rc;
     645
     646        if (disp->backbuf == NULL) {
     647                /* Not double-buffered, nothing to do. */
     648                return EOK;
     649        }
     650
     651        rc = gfx_bitmap_render(disp->backbuf, &disp->dirty_rect, NULL);
     652        if (rc != EOK)
     653                return rc;
     654
     655        disp->dirty_rect.p0.x = 0;
     656        disp->dirty_rect.p0.y = 0;
     657        disp->dirty_rect.p1.x = 0;
     658        disp->dirty_rect.p1.y = 0;
     659
     660        return EOK;
    544661}
    545662
     
    590707        }
    591708
    592         return EOK;
     709        return ds_display_update(disp);
     710}
     711
     712/** Display update callback.
     713 *
     714 * Called by backbuffer memory GC when something is rendered into it.
     715 * Updates the display's dirty rectangle.
     716 *
     717 * @param arg Argument (display cast as void *)
     718 * @param rect Rectangle to update
     719 */
     720static void ds_display_update_cb(void *arg, gfx_rect_t *rect)
     721{
     722        ds_display_t *disp = (ds_display_t *) arg;
     723        gfx_rect_t env;
     724
     725        gfx_rect_envelope(&disp->dirty_rect, rect, &env);
     726        disp->dirty_rect = env;
    593727}
    594728
  • uspace/srv/hid/display/display.h

    r6301a24f r8aef01c  
    4949#include "types/display/seat.h"
    5050
    51 extern errno_t ds_display_create(gfx_context_t *, ds_display_t **);
     51extern errno_t ds_display_create(gfx_context_t *, ds_display_flags_t,
     52    ds_display_t **);
    5253extern void ds_display_destroy(ds_display_t *);
    5354extern void ds_display_lock(ds_display_t *);
     
    7273extern ds_seat_t *ds_display_first_seat(ds_display_t *);
    7374extern ds_seat_t *ds_display_next_seat(ds_seat_t *);
    74 extern void ds_display_add_ddev(ds_display_t *, ds_ddev_t *);
     75extern errno_t ds_display_add_ddev(ds_display_t *, ds_ddev_t *);
    7576extern void ds_display_remove_ddev(ds_ddev_t *);
    7677extern ds_ddev_t *ds_display_first_ddev(ds_display_t *);
  • uspace/srv/hid/display/main.c

    r6301a24f r8aef01c  
    5959static void display_client_ev_pending(void *);
    6060
     61#ifdef CONFIG_DISP_DOUBLE_BUF
     62/*
     63 * Double buffering is one way to provide flicker-free display.
     64 */
     65static ds_display_flags_t disp_flags = df_disp_double_buf;
     66#else
     67/*
     68 * With double buffering disabled, wet screen flicker since front-to-back
     69 * rendering is not implemented.
     70 */
     71static ds_display_flags_t disp_flags = df_none;
     72#endif
     73
    6174static ds_client_cb_t display_client_cb = {
    6275        .ev_pending = display_client_ev_pending
     
    8194        log_msg(LOG_DEFAULT, LVL_DEBUG, "display_srv_init()");
    8295
    83         rc = ds_display_create(NULL, &disp);
     96        rc = ds_display_create(NULL, disp_flags, &disp);
    8497        if (rc != EOK)
    8598                goto error;
  • uspace/srv/hid/display/test/client.c

    r6301a24f r8aef01c  
    6262        errno_t rc;
    6363
    64         rc = ds_display_create(NULL, &disp);
     64        rc = ds_display_create(NULL, df_none, &disp);
    6565        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6666
     
    8787        errno_t rc;
    8888
    89         rc = ds_display_create(NULL, &disp);
     89        rc = ds_display_create(NULL, df_none, &disp);
    9090        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    9191
     
    132132        errno_t rc;
    133133
    134         rc = ds_display_create(NULL, &disp);
     134        rc = ds_display_create(NULL, df_none, &disp);
    135135        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    136136
     
    175175        errno_t rc;
    176176
    177         rc = ds_display_create(NULL, &disp);
     177        rc = ds_display_create(NULL, df_none, &disp);
    178178        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    179179
     
    222222        errno_t rc;
    223223
    224         rc = ds_display_create(NULL, &disp);
     224        rc = ds_display_create(NULL, df_none, &disp);
    225225        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    226226
     
    270270        errno_t rc;
    271271
    272         rc = ds_display_create(NULL, &disp);
     272        rc = ds_display_create(NULL, df_none, &disp);
    273273        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    274274
     
    327327        errno_t rc;
    328328
    329         rc = ds_display_create(NULL, &disp);
     329        rc = ds_display_create(NULL, df_none, &disp);
    330330        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    331331
     
    382382        errno_t rc;
    383383
    384         rc = ds_display_create(NULL, &disp);
     384        rc = ds_display_create(NULL, df_none, &disp);
    385385        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    386386
     
    438438        errno_t rc;
    439439
    440         rc = ds_display_create(NULL, &disp);
     440        rc = ds_display_create(NULL, df_none, &disp);
    441441        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    442442
     
    486486        errno_t rc;
    487487
    488         rc = ds_display_create(NULL, &disp);
     488        rc = ds_display_create(NULL, df_none, &disp);
    489489        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    490490
  • uspace/srv/hid/display/test/cursor.c

    r6301a24f r8aef01c  
    7171        errno_t rc;
    7272
    73         rc = ds_display_create(NULL, &disp);
     73        rc = ds_display_create(NULL, df_none, &disp);
    7474        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    7575
     
    9797        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    9898
    99         rc = ds_display_create(gc, &disp);
     99        rc = ds_display_create(gc, df_none, &disp);
    100100        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    101101
     
    130130        errno_t rc;
    131131
    132         rc = ds_display_create(NULL, &disp);
     132        rc = ds_display_create(NULL, df_none, &disp);
    133133        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    134134
  • uspace/srv/hid/display/test/display.c

    r6301a24f r8aef01c  
    6161        errno_t rc;
    6262
    63         rc = ds_display_create(NULL, &disp);
     63        rc = ds_display_create(NULL, df_none, &disp);
    6464        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6565
     
    7575        errno_t rc;
    7676
    77         rc = ds_display_create(NULL, &disp);
     77        rc = ds_display_create(NULL, df_none, &disp);
    7878        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    7979
     
    102102        errno_t rc;
    103103
    104         rc = ds_display_create(NULL, &disp);
     104        rc = ds_display_create(NULL, df_none, &disp);
    105105        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    106106
     
    166166        errno_t rc;
    167167
    168         rc = ds_display_create(NULL, &disp);
     168        rc = ds_display_create(NULL, df_none, &disp);
    169169        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    170170
     
    212212        errno_t rc;
    213213
    214         rc = ds_display_create(NULL, &disp);
     214        rc = ds_display_create(NULL, df_none, &disp);
    215215        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    216216
     
    241241        errno_t rc;
    242242
    243         rc = ds_display_create(NULL, &disp);
     243        rc = ds_display_create(NULL, df_none, &disp);
    244244        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    245245
     
    289289        errno_t rc;
    290290
    291         rc = ds_display_create(NULL, &disp);
     291        rc = ds_display_create(NULL, df_none, &disp);
    292292        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    293293
     
    357357        errno_t rc;
    358358
    359         rc = ds_display_create(NULL, &disp);
     359        rc = ds_display_create(NULL, df_none, &disp);
    360360        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    361361
  • uspace/srv/hid/display/test/seat.c

    r6301a24f r8aef01c  
    6666        errno_t rc;
    6767
    68         rc = ds_display_create(NULL, &disp);
     68        rc = ds_display_create(NULL, df_none, &disp);
    6969        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    7070
     
    104104        errno_t rc;
    105105
    106         rc = ds_display_create(NULL, &disp);
     106        rc = ds_display_create(NULL, df_none, &disp);
    107107        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    108108
     
    152152        errno_t rc;
    153153
    154         rc = ds_display_create(NULL, &disp);
     154        rc = ds_display_create(NULL, df_none, &disp);
    155155        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    156156
     
    205205        errno_t rc;
    206206
    207         rc = ds_display_create(NULL, &disp);
     207        rc = ds_display_create(NULL, df_none, &disp);
    208208        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    209209
     
    272272        errno_t rc;
    273273
    274         rc = ds_display_create(NULL, &disp);
     274        rc = ds_display_create(NULL, df_none, &disp);
    275275        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    276276
     
    362362        errno_t rc;
    363363
    364         rc = ds_display_create(NULL, &disp);
     364        rc = ds_display_create(NULL, df_none, &disp);
    365365        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    366366
  • uspace/srv/hid/display/test/window.c

    r6301a24f r8aef01c  
    6363        errno_t rc;
    6464
    65         rc = ds_display_create(NULL, &disp);
     65        rc = ds_display_create(NULL, df_none, &disp);
    6666        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6767
     
    109109        errno_t rc;
    110110
    111         rc = ds_display_create(NULL, &disp);
     111        rc = ds_display_create(NULL, df_none, &disp);
    112112        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    113113
     
    146146        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    147147
    148         rc = ds_display_create(gc, &disp);
     148        rc = ds_display_create(gc, df_none, &disp);
    149149        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    150150
     
    192192        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    193193
    194         rc = ds_display_create(gc, &disp);
     194        rc = ds_display_create(gc, df_none, &disp);
    195195        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    196196
     
    260260        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    261261
    262         rc = ds_display_create(gc, &disp);
     262        rc = ds_display_create(gc, df_none, &disp);
    263263        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    264264
     
    303303        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    304304
    305         rc = ds_display_create(gc, &disp);
     305        rc = ds_display_create(gc, df_none, &disp);
    306306        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    307307
     
    349349        errno_t rc;
    350350
    351         rc = ds_display_create(NULL, &disp);
     351        rc = ds_display_create(NULL, df_none, &disp);
    352352        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    353353
     
    614614        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    615615
    616         rc = ds_display_create(gc, &disp);
     616        rc = ds_display_create(gc, df_none, &disp);
    617617        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    618618
  • uspace/srv/hid/display/types/display/display.h

    r6301a24f r8aef01c  
    4242#include <gfx/coord.h>
    4343#include <io/input.h>
     44#include <memgfx/memgc.h>
    4445#include <types/display/cursor.h>
    4546#include "cursor.h"
    4647#include "window.h"
     48
     49/** Display flags */
     50typedef enum {
     51        /** No flags enabled */
     52        df_none = 0,
     53        /** Use double buffer for display */
     54        df_disp_double_buf = 0x1
     55} ds_display_flags_t;
    4756
    4857/** Display server display */
     
    8493        /** Bounding rectangle */
    8594        gfx_rect_t rect;
     95
     96        /** Backbuffer bitmap or @c NULL if not double-buffering */
     97        gfx_bitmap_t *backbuf;
     98
     99        /** Backbuffer GC or @c NULL if not double-buffering */
     100        mem_gc_t *bbgc;
     101
     102        /** Backbuffer dirty rectangle */
     103        gfx_rect_t dirty_rect;
     104
     105        /** Display flags */
     106        ds_display_flags_t flags;
    86107} ds_display_t;
    87108
Note: See TracChangeset for help on using the changeset viewer.