سؤال

This code appears in a framebuffer driver..

static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
{
        unsigned int mask = (1 << bf->length) - 1;

        return (val >> (16 - bf->length) & mask) << bf->offset;
}

Judging from how it is used as below,

if (regno < 15) {
        fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
                          convert_bitfield(blue, &fb->fb.var.blue) |
                          convert_bitfield(green, &fb->fb.var.green) |
                          convert_bitfield(red, &fb->fb.var.red);
        return 0;
}

I thought this function moves the value to its position in a 16 bit value. For example if a 16 bit value is composed of 5-bit R, 6-bit G, and 5-bit B and if R=1,G=2,B=3, the 16-bit value will become 0x0843. (no alpha bits) 00001 000010 00011 = 0000 1000 0100 0011 = 0x0843.

But above code doesn't seem to work as it is supposed to. Because of the (16 - bf->length) term, the value is shifted out to zero before being masked. Somebody please explain how this works? ( found 3 framebuffer drivers so people seem happy with it..)

Thanks in advance. Chan

EDIT : walter, Here's the fb_bitfied.

struct fb_bitfield {
        __u32 offset;                   /* beginning of bitfield        */
        __u32 length;                   /* length of bitfield           */
        __u32 msb_right;                /* != 0 : Most significant bit is */
                                        /* right */ 
};
هل كانت مفيدة؟

المحلول

I will try to explain what the function does:

Fisrt the values transp, blue green red are 16bit and reversed eg

blue = 28 = 0b0000000000011100 is actually 0b0011100000000000

Lets assume RGB565 so blue length is 5:

val >> (16 - bf->length) shifts blue 11 places blue = 0b0000000000000111

Then masks 5 - 1 = 4bits,

(val >> (16 - bf->length) & mask) translates to 0b0000000000000111 & 0b0000000000001111

and lastly it shifts where blue is supposed to be in the R G B format

valter

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top