Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fbdev driver doesn't work when the device only supports 24 bits per pixel #230

Closed
Johennes opened this issue Aug 6, 2022 · 1 comment · Fixed by #231
Closed

fbdev driver doesn't work when the device only supports 24 bits per pixel #230

Johennes opened this issue Aug 6, 2022 · 1 comment · Fixed by #231

Comments

@Johennes
Copy link
Contributor

Johennes commented Aug 6, 2022

In https://gitlab.com/cherrypicker/unl0kr/-/issues/35 we found out that the fbdev driver doesn't work well when the framebuffer has only 24 bits per pixel. The same memcpy code is used for both 32 and 24 bits per pixel

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t * fbp32 = (uint32_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
            memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
            color_p += w;
        }
    }

but when the framebuffer memory layout only uses 24 bits per pixel the 32-bit-wide color_p values will flow over into the next pixel.

I was able to fix the rendering by manually extracting the lower 24 bits from every color_p value.

    /*24 bit per pixel*/
    else if(vinfo.bits_per_pixel == 24) {
        uint8_t * fbp8 = (uint8_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 3;
            long int length = (act_x2 - act_x1 + 1);
            for (long int i = 0; i < length; i += 1) {
                uint32_t c = ((uint32_t *)color_p)[i];
                uint8_t *c8 = (uint8_t *)&c;
                fbp8[3*location + 3*i] = c8[0];
                fbp8[3*location + 3*i+1] = c8[1];
                fbp8[3*location + 3*i+2] = c8[2];
            }
            color_p += w;
        }
    }

However, this is probably a lot less performant than the memcpy. Is there any other way we could truncate the 32-bit color_p values into the lower 24-bits without doing it pixel by pixel?

@kisvegabor
Copy link
Member

Hi,

Thanks for reporting it.

In v9 we will add support for rendering in 24 bit color depth directly. Until that it needs to be converted pixel by pixel. 🙁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants