Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c

    rafcf704 r09ab0a9a  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
    32 * Copyright (c) 2013 Jan Vesely
    43 * All rights reserved.
     
    3635
    3736#include <align.h>
    38 #include <as.h>
    3937#include <assert.h>
    4038#include <errno.h>
    41 #include <ddev_srv.h>
    42 #include <ddev/info.h>
    43 #include <ddf/driver.h>
    4439#include <ddf/log.h>
    4540#include <ddi.h>
    46 #include <gfx/color.h>
    47 #include <io/pixelmap.h>
     41#include <as.h>
    4842
    4943#include "amdm37x_dispc.h"
     
    6155#endif
    6256
    63 static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
    64     visual_t);
    65 
    66 static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    67 static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
    68 
    69 static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
    70 static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
    71 static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    72     gfx_bitmap_alloc_t *, void **);
    73 static errno_t amdm37x_gc_bitmap_destroy(void *);
    74 static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    75 static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    76 
    77 ddev_ops_t amdm37x_ddev_ops = {
    78         .get_gc = amdm37x_ddev_get_gc,
    79         .get_info = amdm37x_ddev_get_info
    80 };
    81 
    82 gfx_context_ops_t amdm37x_gc_ops = {
    83         .set_color = amdm37x_gc_set_color,
    84         .fill_rect = amdm37x_gc_fill_rect,
    85         .bitmap_create = amdm37x_gc_bitmap_create,
    86         .bitmap_destroy = amdm37x_gc_bitmap_destroy,
    87         .bitmap_render = amdm37x_gc_bitmap_render,
    88         .bitmap_get_alloc = amdm37x_gc_bitmap_get_alloc
     57static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
     58static errno_t handle_damage(visualizer_t *vs,
     59    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
     60    sysarg_t x_offset, sysarg_t y_offset);
     61static errno_t dummy(visualizer_t *vs)
     62{
     63        return EOK;
     64}
     65
     66static const visualizer_ops_t amdm37x_dispc_vis_ops = {
     67        .change_mode = change_mode,
     68        .handle_damage = handle_damage,
     69        .claim = dummy,
     70        .yield = dummy,
     71        .suspend = dummy,
     72        .wakeup = dummy,
    8973};
    9074
     
    11094};
    11195
    112 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
    113 {
    114         instance->fun = fun;
     96static void mode_init(vslmode_list_element_t *mode,
     97    unsigned width, unsigned height, visual_t visual)
     98{
     99        mode->mode.index = 0;
     100        mode->mode.version = 0;
     101        mode->mode.refresh_rate = 0;
     102        mode->mode.screen_aspect.width = width;
     103        mode->mode.screen_aspect.height = height;
     104        mode->mode.screen_width = width;
     105        mode->mode.screen_height = height;
     106        mode->mode.cell_aspect.width = 1;
     107        mode->mode.cell_aspect.height = 1;
     108        mode->mode.cell_visual.pixel_visual = visual;
     109
     110        link_initialize(&mode->link);
     111
     112}
     113
     114errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
     115{
     116        assert(instance);
     117        assert(vis);
     118
    115119        instance->fb_data = NULL;
    116120        instance->size = 0;
     
    141145        }
    142146
    143         ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
    144             CONFIG_BFB_HEIGHT, visual);
    145         if (ret != EOK)
    146                 return EIO;
     147        mode_init(&instance->modes[0],
     148            CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, visual);
     149
     150        /* Handle vis stuff */
     151        vis->dev_ctx = instance;
     152        vis->def_mode_idx = 0;
     153        vis->ops = amdm37x_dispc_vis_ops;
     154        list_append(&instance->modes[0].link, &vis->modes);
    147155
    148156        return EOK;
     
    261269}
    262270
    263 static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
    264     unsigned y, visual_t visual)
    265 {
     271static errno_t change_mode(visualizer_t *vis, vslmode_t mode)
     272{
     273        assert(vis);
     274        assert(vis->dev_ctx);
     275
     276        amdm37x_dispc_t *dispc = vis->dev_ctx;
     277        const visual_t visual = mode.cell_visual.pixel_visual;
    266278        assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
    267279        const unsigned bpp = pixel2visual_table[visual].bpp;
    268280        pixel2visual_t p2v = pixel2visual_table[visual].func;
     281        const unsigned x = mode.screen_width;
     282        const unsigned y = mode.screen_height;
    269283        ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
    270284        const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
     
    282296        dispc->fb_data = buffer;
    283297        amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
     298        dispc->active_fb.idx = mode.index;
    284299        dispc->active_fb.width = x;
    285300        dispc->active_fb.height = y;
     
    287302        dispc->active_fb.bpp = bpp;
    288303        dispc->active_fb.pixel2visual = p2v;
    289         dispc->rect.p0.x = 0;
    290         dispc->rect.p0.y = 0;
    291         dispc->rect.p1.x = x;
    292         dispc->rect.p1.y = y;
    293304        dispc->size = size;
    294 
    295         return EOK;
    296 }
    297 
    298 #define FB_POS(d, x, y) \
    299     (((y) * ((d)->active_fb.width + (d)->active_fb.pitch) + (x)) \
    300     * (d)->active_fb.bpp)
    301 
    302 static errno_t amdm37x_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
    303 {
    304         amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
    305 
    306         *arg2 = ddf_fun_get_handle(dispc->fun);
    307         *arg3 = 42;
    308         return EOK;
    309 }
    310 
    311 static errno_t amdm37x_ddev_get_info(void *arg, ddev_info_t *info)
    312 {
    313         amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
    314 
    315         ddev_info_init(info);
    316         info->rect.p0.x = 0;
    317         info->rect.p0.y = 0;
    318         info->rect.p1.x = dispc->active_fb.width;
    319         info->rect.p1.y = dispc->active_fb.height;
    320         return EOK;
    321 }
    322 
    323 /** Set color on AMDM37x display controller.
    324  *
    325  * Set drawing color on AMDM37x GC.
    326  *
    327  * @param arg AMDM37x display controller
    328  * @param color Color
    329  *
    330  * @return EOK on success or an error code
    331  */
    332 static errno_t amdm37x_gc_set_color(void *arg, gfx_color_t *color)
    333 {
    334         amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
    335         uint16_t r, g, b;
    336 
    337         gfx_color_get_rgb_i16(color, &r, &g, &b);
    338         dispc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
    339         return EOK;
    340 }
    341 
    342 /** Fill rectangle on AMDM37x display controller.
    343  *
    344  * @param arg AMDM37x display controller
    345  * @param rect Rectangle
    346  *
    347  * @return EOK on success or an error code
    348  */
    349 static errno_t amdm37x_gc_fill_rect(void *arg, gfx_rect_t *rect)
    350 {
    351         amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
    352         gfx_rect_t crect;
    353         gfx_coord_t x, y;
    354 
    355         /* Make sure we have a sorted, clipped rectangle */
    356         gfx_rect_clip(rect, &dispc->rect, &crect);
    357 
    358         for (y = crect.p0.y; y < crect.p1.y; y++) {
    359                 for (x = crect.p0.x; x < crect.p1.x; x++) {
    360                         dispc->active_fb.pixel2visual(dispc->fb_data +
    361                             FB_POS(dispc, x, y), dispc->color);
    362                 }
    363         }
    364 
    365         return EOK;
    366 }
    367 
    368 /** Create bitmap in AMDM37x GC.
    369  *
    370  * @param arg AMDM37x display controller
    371  * @param params Bitmap params
    372  * @param alloc Bitmap allocation info or @c NULL
    373  * @param rbm Place to store pointer to new bitmap
    374  * @return EOK on success or an error code
    375  */
    376 errno_t amdm37x_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
    377     gfx_bitmap_alloc_t *alloc, void **rbm)
    378 {
    379         amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
    380         amdm37x_bitmap_t *dcbm = NULL;
    381         gfx_coord2_t dim;
    382         errno_t rc;
    383 
    384         /* Check that we support all required flags */
    385         if ((params->flags & ~bmpf_color_key) != 0)
    386                 return ENOTSUP;
    387 
    388         dcbm = calloc(1, sizeof(amdm37x_bitmap_t));
    389         if (dcbm == NULL)
    390                 return ENOMEM;
    391 
    392         gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    393         dcbm->rect = params->rect;
    394 
    395         if (alloc == NULL) {
    396                 dcbm->alloc.pitch = dim.x * sizeof(uint32_t);
    397                 dcbm->alloc.off0 = 0;
    398                 dcbm->alloc.pixels = malloc(dcbm->alloc.pitch * dim.y);
    399                 dcbm->myalloc = true;
    400 
    401                 if (dcbm->alloc.pixels == NULL) {
    402                         rc = ENOMEM;
    403                         goto error;
     305        assert(mode.index < 1);
     306
     307        return EOK;
     308}
     309
     310static errno_t handle_damage(visualizer_t *vs,
     311    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
     312    sysarg_t x_offset, sysarg_t y_offset)
     313{
     314        assert(vs);
     315        assert(vs->dev_ctx);
     316        amdm37x_dispc_t *dispc = vs->dev_ctx;
     317        pixelmap_t *map = &vs->cells;
     318
     319#define FB_POS(x, y) \
     320        (((y) * (dispc->active_fb.width + dispc->active_fb.pitch) + (x)) \
     321            * dispc->active_fb.bpp)
     322        if (x_offset == 0 && y_offset == 0) {
     323                /* Faster damage routine ignoring offsets. */
     324                for (sysarg_t y = y0; y < height + y0; ++y) {
     325                        pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
     326                        for (sysarg_t x = x0; x < width + x0; ++x) {
     327                                dispc->active_fb.pixel2visual(
     328                                    dispc->fb_data + FB_POS(x, y), *pixel++);
     329                        }
    404330                }
    405331        } else {
    406                 dcbm->alloc = *alloc;
    407         }
    408 
    409         dcbm->dispc = dispc;
    410         *rbm = (void *)dcbm;
    411         return EOK;
    412 error:
    413         if (rbm != NULL)
    414                 free(dcbm);
    415         return rc;
    416 }
    417 
    418 /** Destroy bitmap in AMDM37x GC.
    419  *
    420  * @param bm Bitmap
    421  * @return EOK on success or an error code
    422  */
    423 static errno_t amdm37x_gc_bitmap_destroy(void *bm)
    424 {
    425         amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
    426         if (dcbm->myalloc)
    427                 free(dcbm->alloc.pixels);
    428         free(dcbm);
    429         return EOK;
    430 }
    431 
    432 /** Render bitmap in AMDM37x GC.
    433  *
    434  * @param bm Bitmap
    435  * @param srect0 Source rectangle or @c NULL
    436  * @param offs0 Offset or @c NULL
    437  * @return EOK on success or an error code
    438  */
    439 static errno_t amdm37x_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
    440     gfx_coord2_t *offs0)
    441 {
    442         amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
    443         amdm37x_dispc_t *dispc = dcbm->dispc;
    444         gfx_rect_t srect;
    445         gfx_rect_t drect;
    446         gfx_rect_t skfbrect;
    447         gfx_rect_t crect;
    448         gfx_coord2_t offs;
    449         gfx_coord2_t bmdim;
    450         gfx_coord2_t dim;
    451         gfx_coord2_t sp;
    452         gfx_coord2_t dp;
    453         gfx_coord2_t pos;
    454         pixelmap_t pbm;
    455         pixel_t color;
    456 
    457         /* Clip source rectangle to bitmap bounds */
    458 
    459         if (srect0 != NULL)
    460                 gfx_rect_clip(srect0, &dcbm->rect, &srect);
    461         else
    462                 srect = dcbm->rect;
    463 
    464         if (offs0 != NULL) {
    465                 offs = *offs0;
    466         } else {
    467                 offs.x = 0;
    468                 offs.y = 0;
    469         }
    470 
    471         /* Destination rectangle */
    472         gfx_rect_translate(&offs, &srect, &drect);
    473         gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
    474         gfx_coord2_subtract(&dcbm->rect.p1, &dcbm->rect.p0, &bmdim);
    475 
    476         pbm.width = bmdim.x;
    477         pbm.height = bmdim.y;
    478         pbm.data = dcbm->alloc.pixels;
    479 
    480         /* Transform AMDM37x bounding rectangle back to bitmap coordinate system */
    481         gfx_rect_rtranslate(&offs, &dispc->rect, &skfbrect);
    482 
    483         /*
    484          * Make sure we have a sorted source rectangle, clipped so that
    485          * destination lies within AMDM37x bounding rectangle
    486          */
    487         gfx_rect_clip(&srect, &skfbrect, &crect);
    488 
    489         // XXX bmpf_color_key
    490         for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
    491                 for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
    492                         gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
    493                         gfx_coord2_add(&pos, &offs, &dp);
    494 
    495                         color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
    496                         dispc->active_fb.pixel2visual(dispc->fb_data +
    497                             FB_POS(dispc, dp.x, dp.y), color);
     332                for (sysarg_t y = y0; y < height + y0; ++y) {
     333                        for (sysarg_t x = x0; x < width + x0; ++x) {
     334                                dispc->active_fb.pixel2visual(
     335                                    dispc->fb_data + FB_POS(x, y),
     336                                    *pixelmap_pixel_at(map,
     337                                    (x + x_offset) % map->width,
     338                                    (y + y_offset) % map->height));
     339                        }
    498340                }
    499341        }
    500342
    501         return EOK;
    502 }
    503 
    504 /** Get allocation info for bitmap in AMDM37x GC.
    505  *
    506  * @param bm Bitmap
    507  * @param alloc Place to store allocation info
    508  * @return EOK on success or an error code
    509  */
    510 static errno_t amdm37x_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    511 {
    512         amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
    513         *alloc = dcbm->alloc;
    514343        return EOK;
    515344}
Note: See TracChangeset for help on using the changeset viewer.