Ignore:
Timestamp:
2020-07-03T23:41:46Z (4 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fd11144
Parents:
edb57bc6 (diff), ddb844e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
jxsvoboda <5887334+jxsvoboda@…> (2020-07-03 23:41:46)
git-committer:
GitHub <noreply@…> (2020-07-03 23:41:46)
Message:

Merge pull request #200 from jxsvoboda/gfx

Display server

File:
1 edited

Legend:

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

    redb57bc6 re79a025  
    11/*
     2 * Copyright (c) 2020 Jiri Svoboda
    23 * Copyright (c) 2013 Jan Vesely
    34 * All rights reserved.
     
    3536
    3637#include <align.h>
     38#include <as.h>
    3739#include <assert.h>
    3840#include <errno.h>
     41#include <ddev_srv.h>
     42#include <ddev/info.h>
     43#include <ddf/driver.h>
    3944#include <ddf/log.h>
    4045#include <ddi.h>
    41 #include <as.h>
     46#include <gfx/color.h>
     47#include <io/pixelmap.h>
    4248
    4349#include "amdm37x_dispc.h"
     
    5561#endif
    5662
    57 static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
    58 static 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);
    61 static errno_t dummy(visualizer_t *vs)
    62 {
    63         return EOK;
    64 }
    65 
    66 static 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,
     63static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
     64    visual_t);
     65
     66static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     67static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
     68
     69static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
     70static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
     71static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     72    gfx_bitmap_alloc_t *, void **);
     73static errno_t amdm37x_gc_bitmap_destroy(void *);
     74static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     75static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     76
     77ddev_ops_t amdm37x_ddev_ops = {
     78        .get_gc = amdm37x_ddev_get_gc,
     79        .get_info = amdm37x_ddev_get_info
     80};
     81
     82gfx_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
    7389};
    7490
     
    94110};
    95111
    96 static 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 
    114 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
    115 {
    116         assert(instance);
    117         assert(vis);
    118 
     112errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
     113{
     114        instance->fun = fun;
    119115        instance->fb_data = NULL;
    120116        instance->size = 0;
     
    145141        }
    146142
    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);
     143        ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
     144            CONFIG_BFB_HEIGHT, visual);
     145        if (ret != EOK)
     146                return EIO;
    155147
    156148        return EOK;
     
    269261}
    270262
    271 static 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;
     263static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
     264    unsigned y, visual_t visual)
     265{
    278266        assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
    279267        const unsigned bpp = pixel2visual_table[visual].bpp;
    280268        pixel2visual_t p2v = pixel2visual_table[visual].func;
    281         const unsigned x = mode.screen_width;
    282         const unsigned y = mode.screen_height;
    283269        ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
    284270        const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
     
    296282        dispc->fb_data = buffer;
    297283        amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
    298         dispc->active_fb.idx = mode.index;
    299284        dispc->active_fb.width = x;
    300285        dispc->active_fb.height = y;
     
    302287        dispc->active_fb.bpp = bpp;
    303288        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;
    304293        dispc->size = size;
    305         assert(mode.index < 1);
    306 
    307         return EOK;
    308 }
    309 
    310 static 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                         }
     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
     302static 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
     311static 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 */
     332static 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 */
     349static 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 */
     376errno_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;
    330404                }
    331405        } else {
    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                         }
     406                dcbm->alloc = *alloc;
     407        }
     408
     409        dcbm->dispc = dispc;
     410        *rbm = (void *)dcbm;
     411        return EOK;
     412error:
     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 */
     423static 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 */
     439static 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);
    340498                }
    341499        }
    342500
     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 */
     510static 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;
    343514        return EOK;
    344515}
Note: See TracChangeset for help on using the changeset viewer.