Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/fb/kfb/port.c

    r8630748 r4f87a85a  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
    32 * Copyright (c) 2006 Jakub Vana
    43 * Copyright (c) 2006 Ondrej Palkovsky
     
    3938
    4039#include <abi/fb/visuals.h>
     40#include <stddef.h>
     41#include <stdint.h>
     42#include <errno.h>
     43
     44#include <stdlib.h>
     45#include <mem.h>
     46#include <as.h>
     47#include <align.h>
     48
     49#include <sysinfo.h>
     50#include <ddi.h>
     51
    4152#include <adt/list.h>
    42 #include <align.h>
    43 #include <as.h>
    44 #include <ddev_srv.h>
    45 #include <ddev/info.h>
    46 #include <ddi.h>
    47 #include <ddf/log.h>
    48 #include <errno.h>
    49 #include <gfx/bitmap.h>
    50 #include <gfx/color.h>
    51 #include <gfx/coord.h>
     53
    5254#include <io/mode.h>
    5355#include <io/pixelmap.h>
    54 #include <ipcgfx/server.h>
    55 #include <mem.h>
     56#include <io/chargrid.h>
     57
    5658#include <pixconv.h>
    57 #include <stddef.h>
    58 #include <stdint.h>
    59 #include <stdlib.h>
    60 #include <sysinfo.h>
     59
     60#include <graph.h>
    6161
    6262#include "kfb.h"
    6363#include "port.h"
    6464
    65 #define FB_POS(fb, x, y)  ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes)
     65#define FB_POS(x, y)  ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
    6666
    6767typedef struct {
    68         ddf_fun_t *fun;
    69 
    7068        sysarg_t paddr;
    71         gfx_rect_t rect;
     69        sysarg_t width;
     70        sysarg_t height;
    7271        size_t offset;
    7372        size_t scanline;
     
    8180        size_t size;
    8281        uint8_t *addr;
    83 
    84         /** Current drawing color */
    85         pixel_t color;
    8682} kfb_t;
    8783
    88 typedef struct {
    89         kfb_t *kfb;
    90         gfx_bitmap_alloc_t alloc;
    91         gfx_rect_t rect;
    92         gfx_bitmap_flags_t flags;
    93         pixel_t key_color;
    94         bool myalloc;
    95 } kfb_bitmap_t;
    96 
    97 static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    98 static errno_t kfb_ddev_get_info(void *, ddev_info_t *);
    99 
    100 static errno_t kfb_gc_set_color(void *, gfx_color_t *);
    101 static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *);
    102 static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    103     gfx_bitmap_alloc_t *, void **);
    104 static errno_t kfb_gc_bitmap_destroy(void *);
    105 static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    106 static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    107 
    108 static ddev_ops_t kfb_ddev_ops = {
    109         .get_gc = kfb_ddev_get_gc,
    110         .get_info = kfb_ddev_get_info
    111 };
    112 
    113 static gfx_context_ops_t kfb_gc_ops = {
    114         .set_color = kfb_gc_set_color,
    115         .fill_rect = kfb_gc_fill_rect,
    116         .bitmap_create = kfb_gc_bitmap_create,
    117         .bitmap_destroy = kfb_gc_bitmap_destroy,
    118         .bitmap_render = kfb_gc_bitmap_render,
    119         .bitmap_get_alloc = kfb_gc_bitmap_get_alloc
    120 };
    121 
    122 static errno_t kfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
    123 {
    124         kfb_t *kfb = (kfb_t *) arg;
    125 
    126         *arg2 = ddf_fun_get_handle(kfb->fun);
    127         *arg3 = 42;
    128         return EOK;
    129 }
    130 
    131 static errno_t kfb_ddev_get_info(void *arg, ddev_info_t *info)
    132 {
    133         kfb_t *kfb = (kfb_t *) arg;
    134 
    135         ddev_info_init(info);
    136         info->rect = kfb->rect;
    137         return EOK;
    138 }
    139 
    140 /** Set color on KFB.
    141  *
    142  * Set drawing color on KFB GC.
    143  *
    144  * @param arg KFB
    145  * @param color Color
    146  *
    147  * @return EOK on success or an error code
    148  */
    149 static errno_t kfb_gc_set_color(void *arg, gfx_color_t *color)
    150 {
    151         kfb_t *kfb = (kfb_t *) arg;
    152         uint16_t r, g, b;
    153 
    154         gfx_color_get_rgb_i16(color, &r, &g, &b);
    155         kfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
    156         return EOK;
    157 }
    158 
    159 /** Fill rectangle on KFB.
    160  *
    161  * @param arg KFB
    162  * @param rect Rectangle
    163  *
    164  * @return EOK on success or an error code
    165  */
    166 static errno_t kfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
    167 {
    168         kfb_t *kfb = (kfb_t *) arg;
    169         gfx_rect_t crect;
    170         gfx_coord_t x, y;
    171 
    172         /* Make sure we have a sorted, clipped rectangle */
    173         gfx_rect_clip(rect, &kfb->rect, &crect);
    174 
    175         for (y = crect.p0.y; y < crect.p1.y; y++) {
    176                 for (x = crect.p0.x; x < crect.p1.x; x++) {
    177                         kfb->pixel2visual(kfb->addr + FB_POS(kfb, x, y),
    178                             kfb->color);
    179                 }
    180         }
    181 
    182         return EOK;
    183 }
    184 
    185 /** Create bitmap in KFB GC.
    186  *
    187  * @param arg KFB
    188  * @param params Bitmap params
    189  * @param alloc Bitmap allocation info or @c NULL
    190  * @param rbm Place to store pointer to new bitmap
    191  * @return EOK on success or an error code
    192  */
    193 errno_t kfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
    194     gfx_bitmap_alloc_t *alloc, void **rbm)
    195 {
    196         kfb_t *kfb = (kfb_t *) arg;
    197         kfb_bitmap_t *kfbbm = NULL;
    198         gfx_coord2_t dim;
     84static kfb_t kfb;
     85
     86static vslmode_list_element_t pixel_mode;
     87
     88static errno_t kfb_claim(visualizer_t *vs)
     89{
     90        return physmem_map(kfb.paddr + kfb.offset,
     91            ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
     92            AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
     93}
     94
     95static errno_t kfb_yield(visualizer_t *vs)
     96{
    19997        errno_t rc;
    20098
    201         /* Check that we support all required flags */
    202         if ((params->flags & ~bmpf_color_key) != 0)
    203                 return ENOTSUP;
    204 
    205         kfbbm = calloc(1, sizeof(kfb_bitmap_t));
    206         if (kfbbm == NULL)
    207                 return ENOMEM;
    208 
    209         gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    210         kfbbm->rect = params->rect;
    211         kfbbm->flags = params->flags;
    212         kfbbm->key_color = params->key_color;
    213 
    214         if (alloc == NULL) {
    215                 kfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
    216                 kfbbm->alloc.off0 = 0;
    217                 kfbbm->alloc.pixels = malloc(kfbbm->alloc.pitch * dim.y);
    218                 kfbbm->myalloc = true;
    219 
    220                 if (kfbbm->alloc.pixels == NULL) {
    221                         rc = ENOMEM;
    222                         goto error;
    223                 }
    224         } else {
    225                 kfbbm->alloc = *alloc;
    226         }
    227 
    228         kfbbm->kfb = kfb;
    229         *rbm = (void *)kfbbm;
    230         return EOK;
    231 error:
    232         if (rbm != NULL)
    233                 free(kfbbm);
    234         return rc;
    235 }
    236 
    237 /** Destroy bitmap in KFB GC.
    238  *
    239  * @param bm Bitmap
    240  * @return EOK on success or an error code
    241  */
    242 static errno_t kfb_gc_bitmap_destroy(void *bm)
    243 {
    244         kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
    245         if (kfbbm->myalloc)
    246                 free(kfbbm->alloc.pixels);
    247         free(kfbbm);
    248         return EOK;
    249 }
    250 
    251 /** Render bitmap in KFB GC.
    252  *
    253  * @param bm Bitmap
    254  * @param srect0 Source rectangle or @c NULL
    255  * @param offs0 Offset or @c NULL
    256  * @return EOK on success or an error code
    257  */
    258 static errno_t kfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
    259     gfx_coord2_t *offs0)
    260 {
    261         kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
    262         kfb_t *kfb = kfbbm->kfb;
    263         gfx_rect_t srect;
    264         gfx_rect_t drect;
    265         gfx_rect_t skfbrect;
    266         gfx_rect_t crect;
    267         gfx_coord2_t offs;
    268         gfx_coord2_t bmdim;
    269         gfx_coord2_t dim;
    270         gfx_coord2_t sp;
    271         gfx_coord2_t dp;
    272         gfx_coord2_t pos;
    273         pixelmap_t pbm;
    274         pixel_t color;
    275 
    276         /* Clip source rectangle to bitmap bounds */
    277 
    278         if (srect0 != NULL)
    279                 gfx_rect_clip(srect0, &kfbbm->rect, &srect);
    280         else
    281                 srect = kfbbm->rect;
    282 
    283         if (offs0 != NULL) {
    284                 offs = *offs0;
    285         } else {
    286                 offs.x = 0;
    287                 offs.y = 0;
    288         }
    289 
    290         /* Destination rectangle */
    291         gfx_rect_translate(&offs, &srect, &drect);
    292         gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
    293         gfx_coord2_subtract(&kfbbm->rect.p1, &kfbbm->rect.p0, &bmdim);
    294 
    295         pbm.width = bmdim.x;
    296         pbm.height = bmdim.y;
    297         pbm.data = kfbbm->alloc.pixels;
    298 
    299         /* Transform KFB bounding rectangle back to bitmap coordinate system */
    300         gfx_rect_rtranslate(&offs, &kfb->rect, &skfbrect);
    301 
    302         /*
    303          * Make sure we have a sorted source rectangle, clipped so that
    304          * destination lies within KFB bounding rectangle
    305          */
    306         gfx_rect_clip(&srect, &skfbrect, &crect);
    307 
    308         if ((kfbbm->flags & bmpf_color_key) != 0) {
    309                 for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
    310                         for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
    311                                 gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
    312                                 gfx_coord2_add(&pos, &offs, &dp);
    313 
    314                                 color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
    315                                 if (color != kfbbm->key_color) {
    316                                         kfb->pixel2visual(kfb->addr +
    317                                             FB_POS(kfb, dp.x, dp.y), color);
    318                                 }
     99        if (vs->mode_set) {
     100                vs->ops.handle_damage = NULL;
     101        }
     102
     103        rc = physmem_unmap(kfb.addr);
     104        if (rc != EOK)
     105                return rc;
     106
     107        kfb.addr = NULL;
     108        return EOK;
     109}
     110
     111static errno_t kfb_handle_damage_pixels(visualizer_t *vs,
     112    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
     113    sysarg_t x_offset, sysarg_t y_offset)
     114{
     115        pixelmap_t *map = &vs->cells;
     116
     117        if (x_offset == 0 && y_offset == 0) {
     118                /* Faster damage routine ignoring offsets. */
     119                for (sysarg_t y = y0; y < height + y0; ++y) {
     120                        pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
     121                        for (sysarg_t x = x0; x < width + x0; ++x) {
     122                                kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
    319123                        }
    320124                }
    321125        } else {
    322                 for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
    323                         for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
    324                                 gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
    325                                 gfx_coord2_add(&pos, &offs, &dp);
    326 
    327                                 color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
    328                                 kfb->pixel2visual(kfb->addr +
    329                                     FB_POS(kfb, dp.x, dp.y), color);
     126                for (sysarg_t y = y0; y < height + y0; ++y) {
     127                        for (sysarg_t x = x0; x < width + x0; ++x) {
     128                                kfb.pixel2visual(kfb.addr + FB_POS(x, y),
     129                                    *pixelmap_pixel_at(map,
     130                                    (x + x_offset) % map->width,
     131                                    (y + y_offset) % map->height));
    330132                        }
    331133                }
     
    335137}
    336138
    337 /** Get allocation info for bitmap in KFB GC.
    338  *
    339  * @param bm Bitmap
    340  * @param alloc Place to store allocation info
    341  * @return EOK on success or an error code
    342  */
    343 static errno_t kfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    344 {
    345         kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
    346         *alloc = kfbbm->alloc;
    347         return EOK;
    348 }
    349 
    350 #include <stdio.h>
    351 static void kfb_client_conn(ipc_call_t *icall, void *arg)
    352 {
    353         kfb_t *kfb;
    354         ddev_srv_t srv;
    355         sysarg_t gc_id;
    356         gfx_context_t *gc;
     139static errno_t kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
     140{
     141        vs->ops.handle_damage = kfb_handle_damage_pixels;
     142        return EOK;
     143}
     144
     145static errno_t kfb_suspend(visualizer_t *vs)
     146{
     147        return EOK;
     148}
     149
     150static errno_t kfb_wakeup(visualizer_t *vs)
     151{
     152        return EOK;
     153}
     154
     155static visualizer_ops_t kfb_ops = {
     156        .claim = kfb_claim,
     157        .yield = kfb_yield,
     158        .change_mode = kfb_change_mode,
     159        .handle_damage = NULL,
     160        .suspend = kfb_suspend,
     161        .wakeup = kfb_wakeup
     162};
     163
     164static void graph_vsl_connection(ipc_call_t *icall, void *arg)
     165{
     166        visualizer_t *vsl;
    357167        errno_t rc;
    358168
    359         kfb = (kfb_t *) ddf_fun_data_get((ddf_fun_t *) arg);
    360 
    361         printf("kfb_client_conn arg2=%lu arg3=%lu arg4=%lu\n",
    362             (unsigned long) ipc_get_arg2(icall),
    363             (unsigned long) ipc_get_arg3(icall),
    364             (unsigned long) ipc_get_arg4(icall));
    365 
    366         gc_id = ipc_get_arg3(icall);
    367 
    368         if (gc_id == 0) {
    369                 /* Set up protocol structure */
    370                 ddev_srv_initialize(&srv);
    371                 srv.ops = &kfb_ddev_ops;
    372                 srv.arg = kfb;
    373 
    374                 /* Handle connection */
    375                 ddev_conn(icall, &srv);
    376         } else {
    377                 assert(gc_id == 42);
    378 
    379                 if (kfb->addr != AS_AREA_ANY) {
    380                         /* This means there already is a GC connection */
    381                         async_answer_0(icall, EBUSY);
    382                         return;
    383                 }
    384 
    385                 rc = physmem_map(kfb->paddr + kfb->offset,
    386                     ALIGN_UP(kfb->size, PAGE_SIZE) >> PAGE_WIDTH,
    387                     AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb->addr);
    388                 if (rc != EOK)
    389                         goto error;
    390 
    391                 rc = gfx_context_new(&kfb_gc_ops, kfb, &gc);
    392                 if (rc != EOK)
    393                         goto error;
    394 
    395                 /* GC connection */
    396                 gc_conn(icall, gc);
    397 
    398                 rc = physmem_unmap(kfb->addr);
     169        vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
     170        graph_visualizer_connection(vsl, icall, NULL);
     171
     172        if (kfb.addr != NULL) {
     173                rc = physmem_unmap(kfb.addr);
    399174                if (rc == EOK)
    400                         kfb->addr = AS_AREA_ANY;
    401         }
    402 
    403         return;
    404 error:
    405         if (kfb->addr != AS_AREA_ANY) {
    406                 if (physmem_unmap(kfb->addr) == EOK)
    407                         kfb->addr = AS_AREA_ANY;
    408         }
    409 
    410         async_answer_0(icall, rc);
     175                        kfb.addr = NULL;
     176        }
    411177}
    412178
    413179errno_t port_init(ddf_dev_t *dev)
    414180{
    415         ddf_fun_t *fun = NULL;
    416         kfb_t *kfb = NULL;
    417         errno_t rc;
    418 
    419         fun = ddf_fun_create(dev, fun_exposed, "kfb");
    420         if (fun == NULL) {
    421                 rc = ENOMEM;
    422                 goto error;
    423         }
    424 
    425         ddf_fun_set_conn_handler(fun, &kfb_client_conn);
    426 
    427         kfb = ddf_fun_data_alloc(fun, sizeof(kfb_t));
    428         if (kfb == NULL) {
    429                 rc = ENOMEM;
    430                 goto error;
    431         }
    432 
    433181        sysarg_t present;
    434         rc = sysinfo_get_value("fb", &present);
     182        errno_t rc = sysinfo_get_value("fb", &present);
    435183        if (rc != EOK)
    436184                present = false;
    437185
    438         if (!present) {
    439                 ddf_fun_destroy(fun);
    440                 rc = ENOENT;
    441                 goto error;
    442         }
     186        if (!present)
     187                return ENOENT;
    443188
    444189        sysarg_t kind;
     
    447192                kind = (sysarg_t) -1;
    448193
    449         if (kind != 1) {
    450                 rc = EINVAL;
    451                 goto error;
    452         }
     194        if (kind != 1)
     195                return EINVAL;
    453196
    454197        sysarg_t paddr;
    455198        rc = sysinfo_get_value("fb.address.physical", &paddr);
    456199        if (rc != EOK)
    457                 goto error;
     200                return rc;
    458201
    459202        sysarg_t offset;
     
    465208        rc = sysinfo_get_value("fb.width", &width);
    466209        if (rc != EOK)
    467                 goto error;
     210                return rc;
    468211
    469212        sysarg_t height;
    470213        rc = sysinfo_get_value("fb.height", &height);
    471214        if (rc != EOK)
    472                 goto error;
     215                return rc;
    473216
    474217        sysarg_t scanline;
    475218        rc = sysinfo_get_value("fb.scanline", &scanline);
    476219        if (rc != EOK)
    477                 goto error;
     220                return rc;
    478221
    479222        sysarg_t visual;
    480223        rc = sysinfo_get_value("fb.visual", &visual);
    481224        if (rc != EOK)
    482                 goto error;
    483 
    484         kfb->fun = fun;
    485 
    486         kfb->rect.p0.x = 0;
    487         kfb->rect.p0.y = 0;
    488         kfb->rect.p1.x = width;
    489         kfb->rect.p1.y = height;
    490 
    491         kfb->paddr = paddr;
    492         kfb->offset = offset;
    493         kfb->scanline = scanline;
    494         kfb->visual = visual;
     225                return rc;
     226
     227        kfb.width = width;
     228        kfb.height = height;
     229        kfb.paddr = paddr;
     230        kfb.offset = offset;
     231        kfb.scanline = scanline;
     232        kfb.visual = visual;
    495233
    496234        switch (visual) {
    497235        case VISUAL_INDIRECT_8:
    498                 kfb->pixel2visual = pixel2bgr_323;
    499                 kfb->visual2pixel = bgr_323_2pixel;
    500                 kfb->visual_mask = visual_mask_323;
    501                 kfb->pixel_bytes = 1;
     236                kfb.pixel2visual = pixel2bgr_323;
     237                kfb.visual2pixel = bgr_323_2pixel;
     238                kfb.visual_mask = visual_mask_323;
     239                kfb.pixel_bytes = 1;
    502240                break;
    503241        case VISUAL_RGB_5_5_5_LE:
    504                 kfb->pixel2visual = pixel2rgb_555_le;
    505                 kfb->visual2pixel = rgb_555_le_2pixel;
    506                 kfb->visual_mask = visual_mask_555;
    507                 kfb->pixel_bytes = 2;
     242                kfb.pixel2visual = pixel2rgb_555_le;
     243                kfb.visual2pixel = rgb_555_le_2pixel;
     244                kfb.visual_mask = visual_mask_555;
     245                kfb.pixel_bytes = 2;
    508246                break;
    509247        case VISUAL_RGB_5_5_5_BE:
    510                 kfb->pixel2visual = pixel2rgb_555_be;
    511                 kfb->visual2pixel = rgb_555_be_2pixel;
    512                 kfb->visual_mask = visual_mask_555;
    513                 kfb->pixel_bytes = 2;
     248                kfb.pixel2visual = pixel2rgb_555_be;
     249                kfb.visual2pixel = rgb_555_be_2pixel;
     250                kfb.visual_mask = visual_mask_555;
     251                kfb.pixel_bytes = 2;
    514252                break;
    515253        case VISUAL_RGB_5_6_5_LE:
    516                 kfb->pixel2visual = pixel2rgb_565_le;
    517                 kfb->visual2pixel = rgb_565_le_2pixel;
    518                 kfb->visual_mask = visual_mask_565;
    519                 kfb->pixel_bytes = 2;
     254                kfb.pixel2visual = pixel2rgb_565_le;
     255                kfb.visual2pixel = rgb_565_le_2pixel;
     256                kfb.visual_mask = visual_mask_565;
     257                kfb.pixel_bytes = 2;
    520258                break;
    521259        case VISUAL_RGB_5_6_5_BE:
    522                 kfb->pixel2visual = pixel2rgb_565_be;
    523                 kfb->visual2pixel = rgb_565_be_2pixel;
    524                 kfb->visual_mask = visual_mask_565;
    525                 kfb->pixel_bytes = 2;
     260                kfb.pixel2visual = pixel2rgb_565_be;
     261                kfb.visual2pixel = rgb_565_be_2pixel;
     262                kfb.visual_mask = visual_mask_565;
     263                kfb.pixel_bytes = 2;
    526264                break;
    527265        case VISUAL_RGB_8_8_8:
    528                 kfb->pixel2visual = pixel2rgb_888;
    529                 kfb->visual2pixel = rgb_888_2pixel;
    530                 kfb->visual_mask = visual_mask_888;
    531                 kfb->pixel_bytes = 3;
     266                kfb.pixel2visual = pixel2rgb_888;
     267                kfb.visual2pixel = rgb_888_2pixel;
     268                kfb.visual_mask = visual_mask_888;
     269                kfb.pixel_bytes = 3;
    532270                break;
    533271        case VISUAL_BGR_8_8_8:
    534                 kfb->pixel2visual = pixel2bgr_888;
    535                 kfb->visual2pixel = bgr_888_2pixel;
    536                 kfb->visual_mask = visual_mask_888;
    537                 kfb->pixel_bytes = 3;
     272                kfb.pixel2visual = pixel2bgr_888;
     273                kfb.visual2pixel = bgr_888_2pixel;
     274                kfb.visual_mask = visual_mask_888;
     275                kfb.pixel_bytes = 3;
    538276                break;
    539277        case VISUAL_RGB_8_8_8_0:
    540                 kfb->pixel2visual = pixel2rgb_8880;
    541                 kfb->visual2pixel = rgb_8880_2pixel;
    542                 kfb->visual_mask = visual_mask_8880;
    543                 kfb->pixel_bytes = 4;
     278                kfb.pixel2visual = pixel2rgb_8880;
     279                kfb.visual2pixel = rgb_8880_2pixel;
     280                kfb.visual_mask = visual_mask_8880;
     281                kfb.pixel_bytes = 4;
    544282                break;
    545283        case VISUAL_RGB_0_8_8_8:
    546                 kfb->pixel2visual = pixel2rgb_0888;
    547                 kfb->visual2pixel = rgb_0888_2pixel;
    548                 kfb->visual_mask = visual_mask_0888;
    549                 kfb->pixel_bytes = 4;
     284                kfb.pixel2visual = pixel2rgb_0888;
     285                kfb.visual2pixel = rgb_0888_2pixel;
     286                kfb.visual_mask = visual_mask_0888;
     287                kfb.pixel_bytes = 4;
    550288                break;
    551289        case VISUAL_BGR_0_8_8_8:
    552                 kfb->pixel2visual = pixel2bgr_0888;
    553                 kfb->visual2pixel = bgr_0888_2pixel;
    554                 kfb->visual_mask = visual_mask_0888;
    555                 kfb->pixel_bytes = 4;
     290                kfb.pixel2visual = pixel2bgr_0888;
     291                kfb.visual2pixel = bgr_0888_2pixel;
     292                kfb.visual_mask = visual_mask_0888;
     293                kfb.pixel_bytes = 4;
    556294                break;
    557295        case VISUAL_BGR_8_8_8_0:
    558                 kfb->pixel2visual = pixel2bgr_8880;
    559                 kfb->visual2pixel = bgr_8880_2pixel;
    560                 kfb->visual_mask = visual_mask_8880;
    561                 kfb->pixel_bytes = 4;
     296                kfb.pixel2visual = pixel2bgr_8880;
     297                kfb.visual2pixel = bgr_8880_2pixel;
     298                kfb.visual_mask = visual_mask_8880;
     299                kfb.pixel_bytes = 4;
    562300                break;
    563301        default:
     
    565303        }
    566304
    567         kfb->size = scanline * height;
    568         kfb->addr = AS_AREA_ANY;
    569 
    570         rc = ddf_fun_bind(fun);
    571         if (rc != EOK)
    572                 goto error;
    573 
    574         rc = ddf_fun_add_to_category(fun, "display-device");
     305        kfb.size = scanline * height;
     306        kfb.addr = AS_AREA_ANY;
     307
     308        ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
     309        if (fun_vs == NULL) {
     310                as_area_destroy(kfb.addr);
     311                return ENOMEM;
     312        }
     313        ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
     314
     315        visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
     316        if (vs == NULL) {
     317                as_area_destroy(kfb.addr);
     318                return ENOMEM;
     319        }
     320        graph_init_visualizer(vs);
     321
     322        pixel_mode.mode.index = 0;
     323        pixel_mode.mode.version = 0;
     324        pixel_mode.mode.refresh_rate = 0;
     325        pixel_mode.mode.screen_aspect.width = width;
     326        pixel_mode.mode.screen_aspect.height = height;
     327        pixel_mode.mode.screen_width = width;
     328        pixel_mode.mode.screen_height = height;
     329        pixel_mode.mode.cell_aspect.width = 1;
     330        pixel_mode.mode.cell_aspect.height = 1;
     331        pixel_mode.mode.cell_visual.pixel_visual = visual;
     332
     333        link_initialize(&pixel_mode.link);
     334        list_append(&pixel_mode.link, &vs->modes);
     335
     336        vs->def_mode_idx = 0;
     337
     338        vs->ops = kfb_ops;
     339        vs->dev_ctx = NULL;
     340
     341        rc = ddf_fun_bind(fun_vs);
    575342        if (rc != EOK) {
    576                 ddf_fun_unbind(fun);
    577                 goto error;
    578         }
    579 
    580         return EOK;
    581 error:
    582         if (fun != NULL)
    583                 ddf_fun_destroy(fun);
    584         return rc;
     343                list_remove(&pixel_mode.link);
     344                ddf_fun_destroy(fun_vs);
     345                as_area_destroy(kfb.addr);
     346                return rc;
     347        }
     348
     349        vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
     350        rc = ddf_fun_add_to_category(fun_vs, "visualizer");
     351        if (rc != EOK) {
     352                list_remove(&pixel_mode.link);
     353                ddf_fun_unbind(fun_vs);
     354                ddf_fun_destroy(fun_vs);
     355                as_area_destroy(kfb.addr);
     356                return rc;
     357        }
     358
     359        return EOK;
    585360}
    586361
Note: See TracChangeset for help on using the changeset viewer.