Changeset a2c4445 in mainline for genarch/src/fb/fb.c


Ignore:
Timestamp:
2006-03-25T22:48:51Z (19 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc27ae48
Parents:
c715e9b
Message:

framebuffer code cleanup, support for non-standard scanline sizes
ppc32: get framebuffer parameters from boot loader

File:
1 edited

Legend:

Unmodified
Added
Removed
  • genarch/src/fb/fb.c

    rc715e9b ra2c4445  
    3838SPINLOCK_INITIALIZE(fb_lock);
    3939
    40 static __u8 *fbaddress=NULL;
    41 static int xres,yres;
    42 static int position=0;
    43 static int columns=0;
    44 static int rows=0;
    45 static int pixelbytes=0;
    46 
    47 #define COL_WIDTH   8
    48 #define ROW_HEIGHT  (FONT_SCANLINES)
    49 #define ROW_PIX     (xres*ROW_HEIGHT*pixelbytes)
    50 
    51 #define BGCOLOR   0x000080
    52 #define FGCOLOR   0xffff00
    53 #define LOGOCOLOR 0x2020b0
    54 
    55 #define RED(x,bits)    ((x >> (16+8-bits)) & ((1<<bits)-1))
    56 #define GREEN(x,bits)  ((x >> (8+8-bits)) & ((1<<bits)-1))
    57 #define BLUE(x,bits)   ((x >> (8-bits)) & ((1<<bits)-1))
    58 
    59 #define POINTPOS(x,y)   ((y*xres+x)*pixelbytes)
     40static __u8 *fbaddress = NULL;
     41
     42static unsigned int xres = 0;
     43static unsigned int yres = 0;
     44static unsigned int scanline = 0;
     45static unsigned int pixelbytes = 0;
     46
     47static unsigned int position = 0;
     48static unsigned int columns = 0;
     49static unsigned int rows = 0;
     50
     51
     52#define COL_WIDTH       8
     53#define ROW_BYTES       (scanline * FONT_SCANLINES)
     54
     55#define BGCOLOR         0x000080
     56#define FGCOLOR         0xffff00
     57#define LOGOCOLOR       0x2020b0
     58
     59#define RED(x, bits)    ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
     60#define GREEN(x, bits)  ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
     61#define BLUE(x, bits)   ((x >> (8 - bits)) & ((1 << bits) - 1))
     62
     63#define POINTPOS(x, y)  (y * scanline + x * pixelbytes)
    6064
    6165/***************************************************************/
    6266/* Pixel specific fuctions */
    6367
    64 static void (*putpixel)(int x,int y,int color);
    65 static int (*getpixel)(int x,int y);
     68static void (*putpixel)(unsigned int x, unsigned int y, int color);
     69static int (*getpixel)(unsigned int x, unsigned int y);
    6670
    6771/** Put pixel - 24-bit depth, 1 free byte */
    68 static void putpixel_4byte(int x,int y,int color)
    69 {
    70         int startbyte = POINTPOS(x,y);
    71 
    72         *((__u32 *)(fbaddress+startbyte)) = color;
    73 }
    74 
    75 /** Return pixel color */
    76 static int getpixel_4byte(int x,int y)
    77 {
    78         int startbyte = POINTPOS(x,y);
    79 
    80         return *((__u32 *)(fbaddress+startbyte)) & 0xffffff;
    81 }
    82 
    83 /** Draw pixel of given color on screen - 24-bit depth */
    84 static void putpixel_3byte(int x,int y,int color)
    85 {
    86         int startbyte = POINTPOS(x,y);
    87 
    88         fbaddress[startbyte] = RED(color,8);
    89         fbaddress[startbyte+1] = GREEN(color,8);
    90         fbaddress[startbyte+2] = BLUE(color,8);
    91 }
    92 
    93 static int getpixel_3byte(int x,int y)
    94 {
    95         int startbyte = POINTPOS(x,y);
    96         int result;
    97 
    98         result = fbaddress[startbyte] << 16 \
    99                 | fbaddress[startbyte+1] << 8 \
    100                 | fbaddress[startbyte+2];
    101         return result;
     72static void putpixel_4byte(unsigned int x, unsigned int y, int color)
     73{
     74        *((__u32 *)(fbaddress + POINTPOS(x, y))) = color;
     75}
     76
     77/** Return pixel color - 24-bit depth, 1 free byte */
     78static int getpixel_4byte(unsigned int x, unsigned int y)
     79{
     80        return *((__u32 *)(fbaddress + POINTPOS(x, y))) & 0xffffff;
     81}
     82
     83/** Put pixel - 24-bit depth */
     84static void putpixel_3byte(unsigned int x, unsigned int y, int color)
     85{
     86        unsigned int startbyte = POINTPOS(x, y);
     87
     88        fbaddress[startbyte] = RED(color, 8);
     89        fbaddress[startbyte + 1] = GREEN(color, 8);
     90        fbaddress[startbyte + 2] = BLUE(color, 8);
     91}
     92
     93/** Return pixel color - 24-bit depth */
     94static int getpixel_3byte(unsigned int x, unsigned int y)
     95{
     96        unsigned int startbyte = POINTPOS(x, y);
     97
     98        return fbaddress[startbyte] << 16 | fbaddress[startbyte + 1] << 8 | fbaddress[startbyte + 2];
    10299}
    103100
    104101/** Put pixel - 16-bit depth (5:6:6) */
    105 static void putpixel_2byte(int x,int y,int color)
    106 {
    107         int startbyte = POINTPOS(x,y);
    108         int compcolor;
    109 
     102static void putpixel_2byte(unsigned int x, unsigned int y, int color)
     103{
    110104        /* 5-bit, 5-bits, 5-bits */
    111         compcolor = RED(color,5) << 11 \
    112                 | GREEN(color,6) << 5 \
    113                 | BLUE(color,5);
    114         *((__u16 *)(fbaddress+startbyte)) = compcolor;
    115 }
    116 
    117 static int getpixel_2byte(int x,int y)
    118 {
    119         int startbyte = POINTPOS(x,y);
    120         int color;
    121         int red,green,blue;
    122 
    123         color = *((__u16 *)(fbaddress+startbyte));
    124         red = (color >> 11) & 0x1f;
    125         green = (color >> 5) & 0x3f;
    126         blue = color & 0x1f;
    127         return (red << (16+3)) | (green << (8+2)) | (blue << 3);
     105        *((__u16 *)(fbaddress + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5);
     106}
     107
     108/** Return pixel color - 16-bit depth (5:6:6) */
     109static int getpixel_2byte(unsigned int x, unsigned int y)
     110{
     111        int color = *((__u16 *)(fbaddress + POINTPOS(x, y)));
     112        return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
    128113}
    129114
    130115/** Put pixel - 8-bit depth (3:2:3) */
    131 static void putpixel_1byte(int x,int y,int color)
    132 {
    133         int compcolor;
    134 
    135         /* 3-bit, 2-bits, 3-bits */
    136         compcolor = RED(color,3) << 5 \
    137                 | GREEN(color,2) << 3 \
    138                 | BLUE(color,3);
    139         fbaddress[POINTPOS(x,y)] = compcolor;
    140 }
    141 
    142 
    143 static int getpixel_1byte(int x,int y)
    144 {
    145         int color;
    146         int red,green,blue;
    147 
    148         color = fbaddress[POINTPOS(x,y)];
    149         red = (color >> 5) & 0x7;
    150         green = (color >> 3) & 0x3;
    151         blue = color & 0x7;
    152         return (red << (16+5)) | (green << (8+6)) | blue << 5;
    153 }
    154 
    155 static void clear_line(int y);
     116static void putpixel_1byte(unsigned int x, unsigned int y, int color)
     117{
     118        fbaddress[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3);
     119}
     120
     121/** Return pixel color - 8-bit depth (3:2:3) */
     122static int getpixel_1byte(unsigned int x, unsigned int y)
     123{
     124        int color = fbaddress[POINTPOS(x, y)];
     125        return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
     126}
     127
     128/** Fill line with color BGCOLOR */
     129static void clear_line(unsigned int y)
     130{
     131        unsigned int x;
     132       
     133        for (x = 0; x < xres; x++)
     134                (*putpixel)(x, y, BGCOLOR);
     135}
     136
     137
     138/** Fill screen with background color */
     139static void clear_screen(void)
     140{
     141        unsigned int y;
     142
     143        for (y = 0; y < yres; y++)
     144                clear_line(y);
     145}
     146
     147
    156148/** Scroll screen one row up */
    157149static void scroll_screen(void)
    158150{
    159         int i;
    160 
    161         memcpy((void *) fbaddress, (void *) &fbaddress[ROW_PIX], (xres*yres*pixelbytes)-ROW_PIX);
     151        unsigned int i;
     152
     153        memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES], scanline * yres - ROW_BYTES);
    162154
    163155        /* Clear last row */
    164         for (i=0; i < ROW_HEIGHT;i++)
    165                 clear_line((rows-1)*ROW_HEIGHT+i);
    166        
    167 }
    168 
    169 
    170 /***************************************************************/
    171 /* Screen specific function */
    172 
    173 /** Fill line with color BGCOLOR */
    174 static void clear_line(int y)
    175 {
    176         int x;
    177         for (x=0; x<xres;x++)
    178                 (*putpixel)(x,y,BGCOLOR);
    179 }
    180 
    181 /** Fill screen with background color */
    182 static void clear_screen(void)
    183 {
    184         int y;
    185 
    186         for (y=0; y<yres;y++)
    187                 clear_line(y);
    188 }
    189 
    190 static void invert_pixel(int x, int y)
    191 {
    192         (*putpixel)(x,y, ~(*getpixel)(x,y));
     156        for (i = 0; i < FONT_SCANLINES; i++)
     157                clear_line((rows - 1) * FONT_SCANLINES + i);
     158}
     159
     160
     161static void invert_pixel(unsigned int x, unsigned int y)
     162{
     163        (*putpixel)(x, y, ~(*getpixel)(x, y));
    193164}
    194165
    195166
    196167/** Draw one line of glyph at a given position */
    197 static void draw_glyph_line(int glline, int x, int y)
    198 {
    199         int i;
    200 
    201         for (i=0; i < 8; i++)
    202                 if (glline & (1 << (7-i))) {
    203                         (*putpixel)(x+i,y,FGCOLOR);
     168static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
     169{
     170        unsigned int i;
     171
     172        for (i = 0; i < 8; i++)
     173                if (glline & (1 << (7 - i))) {
     174                        (*putpixel)(x + i, y, FGCOLOR);
    204175                } else
    205                         (*putpixel)(x+i,y,BGCOLOR);
     176                        (*putpixel)(x + i, y, BGCOLOR);
    206177}
    207178
     
    210181
    211182/** Draw character at given position */
    212 static void draw_glyph(__u8 glyph, int col, int row)
    213 {
    214         int y;
    215 
    216         for (y=0; y < FONT_SCANLINES; y++)
    217                 draw_glyph_line(fb_font[glyph*FONT_SCANLINES+y],
    218                                 col*COL_WIDTH, row*ROW_HEIGHT+y);
     183static void draw_glyph(__u8 glyph, unsigned int col, unsigned int row)
     184{
     185        unsigned int y;
     186
     187        for (y = 0; y < FONT_SCANLINES; y++)
     188                draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y], col * COL_WIDTH, row * FONT_SCANLINES + y);
    219189}
    220190
    221191/** Invert character at given position */
    222 static void invert_char(int col, int row)
    223 {
    224         int x,y;
    225 
    226         for (x=0; x < COL_WIDTH; x++)
    227                 for (y=0; y < FONT_SCANLINES; y++)
    228                         invert_pixel(col*COL_WIDTH+x,row*ROW_HEIGHT+y);
     192static void invert_char(unsigned int col, unsigned int row)
     193{
     194        unsigned int x;
     195        unsigned int y;
     196
     197        for (x = 0; x < COL_WIDTH; x++)
     198                for (y = 0; y < FONT_SCANLINES; y++)
     199                        invert_pixel(col * COL_WIDTH + x, row * FONT_SCANLINES + y);
    229200}
    230201
     
    232203static void draw_char(char chr)
    233204{
    234         draw_glyph(chr, position % columns, position/columns);
    235 }
    236 
    237 static void draw_logo(int startx, int starty)
    238 {
    239         int x,y;
    240         int byte;
    241         int rowbytes;
    242 
    243         rowbytes = (helenos_width-1)/8 + 1;
    244 
    245         for (y=0;y < helenos_height;y++)
    246                 for (x=0;x < helenos_width; x++ ) {
    247                         byte = helenos_bits[rowbytes*y + x/8];
     205        draw_glyph(chr, position % columns, position / columns);
     206}
     207
     208static void draw_logo(unsigned int startx, unsigned int starty)
     209{
     210        unsigned int x;
     211        unsigned int y;
     212        unsigned int byte;
     213        unsigned int rowbytes;
     214
     215        rowbytes = (helenos_width - 1) / 8 + 1;
     216
     217        for (y = 0; y < helenos_height; y++)
     218                for (x = 0; x < helenos_width; x++) {
     219                        byte = helenos_bits[rowbytes * y + x / 8];
    248220                        byte >>= x % 8;
    249221                        if (byte & 1)
    250                                 (*putpixel)(startx+x,starty+y,LOGOCOLOR);
     222                                (*putpixel)(startx + x, starty + y, LOGOCOLOR);
    251223                }
    252224}
     
    257229static void invert_cursor(void)
    258230{
    259         invert_char(position % columns, position/columns);
     231        invert_char(position % columns, position / columns);
    260232}
    261233
     
    267239{
    268240        spinlock_lock(&fb->lock);
    269 
    270         if (ch == '\n') {
    271                 invert_cursor();
    272                 position += columns;
    273                 position -= position % columns;
    274         } else if (ch == '\r') {
    275                 invert_cursor();
    276                 position -= position % columns;
    277         } else if (ch == '\b') {
    278                 invert_cursor();
    279                 if (position % columns)
    280                         position--;
    281         } else if (ch == '\t') {
    282                 invert_cursor();
    283                 do {
    284                         draw_char(' ');
     241       
     242        switch (ch) {
     243                case '\n':
     244                        invert_cursor();
     245                        position += columns;
     246                        position -= position % columns;
     247                        break;
     248                case '\r':
     249                        invert_cursor();
     250                        position -= position % columns;
     251                        break;
     252                case '\b':
     253                        invert_cursor();
     254                        if (position % columns)
     255                                position--;
     256                        break;
     257                case '\t':
     258                        invert_cursor();
     259                        do {
     260                                draw_char(' ');
     261                                position++;
     262                        } while (position % 8);
     263                        break;
     264                default:
     265                        draw_char(ch);
    285266                        position++;
    286                 } while (position % 8);
    287         } else {
    288                 draw_char(ch);
    289                 position++;
    290267        }
    291         if (position >= columns*rows) {
     268       
     269        if (position >= columns * rows) {
    292270                position -= columns;
    293271                scroll_screen();
    294272        }
     273       
    295274        invert_cursor();
     275       
    296276        spinlock_unlock(&fb->lock);
    297277}
     
    305285/** Initialize framebuffer as a chardev output device
    306286 *
    307  * @param addr Address of framebuffer
    308  * @param x X resolution
    309  * @param y Y resolution
    310  * @param bytes Bytes per pixel (2,3,4)
     287 * @param addr Address of theframebuffer
     288 * @param x    Screen width in pixels
     289 * @param y    Screen height in pixels
     290 * @param bpp  Bits per pixel (8, 16, 24, 32)
     291 * @param scan Bytes per one scanline
     292 *
    311293 */
    312 void fb_init(__address addr, int x, int y, int bytes)
    313 {
    314         fbaddress = (unsigned char *)addr;
    315 
    316         switch (bytes) {
    317         case 1:
    318                 putpixel = putpixel_1byte;
    319                 getpixel = getpixel_1byte;
    320                 break;
    321         case 2:
    322                 putpixel = putpixel_2byte;
    323                 getpixel = getpixel_2byte;
    324                 break;
    325         case 3:
    326                 putpixel = putpixel_3byte;
    327                 getpixel = getpixel_3byte;
    328                 break;
    329         case 4:
    330                 putpixel = putpixel_4byte;
    331                 getpixel = getpixel_4byte;
    332                 break;
    333         default:
    334                 panic("Unsupported color depth");
     294void fb_init(__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan)
     295{
     296        switch (bpp) {
     297                case 8:
     298                        putpixel = putpixel_1byte;
     299                        getpixel = getpixel_1byte;
     300                        pixelbytes = 1;
     301                        break;
     302                case 16:
     303                        putpixel = putpixel_2byte;
     304                        getpixel = getpixel_2byte;
     305                        pixelbytes = 2;
     306                        break;
     307                case 24:
     308                        putpixel = putpixel_3byte;
     309                        getpixel = getpixel_3byte;
     310                        pixelbytes = 3;
     311                        break;
     312                case 32:
     313                        putpixel = putpixel_4byte;
     314                        getpixel = getpixel_4byte;
     315                        pixelbytes = 4;
     316                        break;
     317                default:
     318                        panic("Unsupported bpp");
    335319        }
    336        
     320               
     321        fbaddress = (unsigned char *) addr;
    337322        xres = x;
    338323        yres = y;
    339         pixelbytes = bytes;
    340        
    341         rows = y/ROW_HEIGHT;
    342         columns = x/COL_WIDTH;
     324        scanline = scan;
     325       
     326        rows = y / FONT_SCANLINES;
     327        columns = x / COL_WIDTH;
    343328
    344329        clear_screen();
    345         draw_logo(xres-helenos_width, 0);
     330        draw_logo(xres - helenos_width, 0);
    346331        invert_cursor();
    347332
     
    349334        stdout = &framebuffer;
    350335}
    351 
Note: See TracChangeset for help on using the changeset viewer.