/* SPDX-License-Identifier: GPL-2.0 * * Various common functions used by the framebuffer drawing code * * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org)
*/ #ifndef _FB_DRAW_H #define _FB_DRAW_H
/* swap bytes in a long, independent of word size */ #define swab_long _swab_long(BITS_PER_LONG) #define _swab_long(x) __swab_long(x) #define __swab_long(x) swab##x
/* move the address pointer by the number of words */ staticinlinevoid fb_address_move_long(struct fb_address *adr, int offset)
{
adr->address += offset * (BITS_PER_LONG / BITS_PER_BYTE);
}
/* move the address pointer forward with the number of bits */ staticinlinevoid fb_address_forward(struct fb_address *adr, unsignedint offset)
{ unsignedint bits = (unsignedint)adr->bits + offset;
/* move the address pointer backwards with the number of bits */ staticinlinevoid fb_address_backward(struct fb_address *adr, unsignedint offset)
{ int bits = adr->bits - (int)offset;
/* framebuffer read-modify-write access for replacing bits in the mask */ staticinlinevoid fb_modify_offset(unsignedlong val, unsignedlong mask, int offset, conststruct fb_address *dst)
{
fb_write_offset(fb_comp(val, fb_read_offset(offset, dst), mask), offset, dst);
}
/* * get current palette, if applicable for visual * * The pseudo color table entries (and colors) are right justified and in the * same byte order as it's expected to be placed into a native ordered * framebuffer memory. What that means: * * Expected bytes in framebuffer memory (in native order): * RR GG BB RR GG BB RR GG BB ... * * Pseudo palette entry on little endian arch: * RR | GG << 8 | BB << 16 * * Pseudo palette entry on a big endian arch: * RR << 16 | GG << 8 | BB
*/ staticinlineconst u32 *fb_palette(struct fb_info *info)
{ return (info->fix.visual == FB_VISUAL_TRUECOLOR ||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? info->pseudo_palette : NULL;
}
/* move pixels right on screen when framebuffer is in native order */ staticinlineunsignedlong fb_right(unsignedlong value, int index)
{ #ifdef __LITTLE_ENDIAN return value << index; #else return value >> index; #endif
}
/* move pixels left on screen when framebuffer is in native order */ staticinlineunsignedlong fb_left(unsignedlong value, int index)
{ #ifdef __LITTLE_ENDIAN return value >> index; #else return value << index; #endif
}
/* reverse bits of each byte in a long */ staticinlineunsignedlong fb_reverse_bits_long(unsignedlong val)
{ #ifdefined(CONFIG_HAVE_ARCH_BITREVERSE) && BITS_PER_LONG == 32 return bitrev8x4(val); #else
val = fb_comp(val >> 1, val << 1, ~0UL / 3);
val = fb_comp(val >> 2, val << 2, ~0UL / 5); return fb_comp(val >> 4, val << 4, ~0UL / 17); #endif
}
/* apply byte and bit reversals as necessary */ staticinlineunsignedlong fb_reverse_long(unsignedlong val, struct fb_reverse reverse)
{ if (reverse.pixel)
val = fb_reverse_bits_long(val); return reverse.byte ? swab_long(val) : val;
}
/* calculate a pixel mask for the given reversal */ staticinlineunsignedlong fb_pixel_mask(int index, struct fb_reverse reverse)
{ #ifdef FB_REV_PIXELS_IN_BYTE if (reverse.byte) return reverse.pixel ? fb_left(~0UL, index) : swab_long(fb_right(~0UL, index)); else return reverse.pixel ? swab_long(fb_left(~0UL, index)) : fb_right(~0UL, index); #else return reverse.byte ? swab_long(fb_right(~0UL, index)) : fb_right(~0UL, index); #endif
}
/* * initialise reversals based on info * * Normally the first byte is the low byte on little endian and in the high * on big endian. If it's the other way around then that's reverse byte order. * * Normally the first pixel is the LSB on little endian and the MSB on big * endian. If that's not the case that's reverse pixel order.
*/ staticinlinestruct fb_reverse fb_reverse_init(struct fb_info *info)
{ struct fb_reverse reverse; #ifdef __LITTLE_ENDIAN
reverse.byte = fb_be_math(info) != 0; #else
reverse.byte = fb_be_math(info) == 0; #endif #ifdef FB_REV_PIXELS_IN_BYTE
reverse.pixel = info->var.bits_per_pixel < BITS_PER_BYTE
&& (info->var.nonstd & FB_NONSTD_REV_PIX_IN_B); #else
reverse.pixel = false; #endif return reverse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.