/* SPDX-License-Identifier: GPL-2.0-only * * Generic bit area filler and twister engine for packed pixel framebuffers * * Rewritten by: * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) * * Based on earlier work of: * Copyright (C) 2000 James Simmons (jsimmons@linux-fbdev.org) * Michal Januszewski <spock@gentoo.org> * Anton Vorontsov <avorontsov@ru.mvista.com> * Pavel Pisa <pisa@cmp.felk.cvut.cz> * Antonino A. Daplas <adaplas@gmail.com> * Geert Uytterhoeven * and others * * NOTES: * * Handles native and foreign byte order on both endians, standard and * reverse pixel order in a byte (<8 BPP), word length of 32/64 bits, * bits per pixel from 1 to the word length. Handles line lengths at byte * granularity while maintaining aligned accesses. * * Optimized path for power of two bits per pixel modes.
*/ #include"fb_draw.h"
/* inverts bits at a given offset */ staticinlinevoid fb_invert_offset(unsignedlong pat, int offset, conststruct fb_address *dst)
{
fb_write_offset(fb_read_offset(offset, dst) ^ pat, offset, dst);
}
/* state for pattern generator and whether swapping is necessary */ struct fb_pattern { unsignedlong pixels; int left, right; struct fb_reverse reverse;
};
/* used to get the pattern in native order */ staticunsignedlong fb_pattern_get(struct fb_pattern *pattern)
{ return pattern->pixels;
}
/* used to get the pattern in reverse order */ staticunsignedlong fb_pattern_get_reverse(struct fb_pattern *pattern)
{ return swab_long(pattern->pixels);
}
/* next static pattern */ staticvoid fb_pattern_static(struct fb_pattern *pattern)
{ /* nothing to do */
}
/* overwrite bits according to a pattern in a line */ static __always_inline void bitfill(conststruct fb_address *dst, struct fb_pattern *pattern, unsignedlong (*get)(struct fb_pattern *pattern), void (*rotate)(struct fb_pattern *pattern), int end)
{ unsignedlong first, last;
end += dst->bits;
first = fb_pixel_mask(dst->bits, pattern->reverse);
last = ~fb_pixel_mask(end & (BITS_PER_LONG-1), pattern->reverse);
if (end <= BITS_PER_LONG) {
last = last ? (last & first) : first;
first = get(pattern); if (last == ~0UL)
fb_write_offset(first, 0, dst); elseif (last)
fb_modify_offset(first, last, 0, dst);
} else { int offset = first != ~0UL;
if (last)
fb_modify_offset(get(pattern), last, offset, dst);
}
}
/* inverts bits according to a pattern in a line */ static __always_inline void bitinvert(conststruct fb_address *dst, struct fb_pattern *pattern, unsignedlong (*get)(struct fb_pattern *pattern), void (*rotate)(struct fb_pattern *pattern), int end)
{ unsignedlong first, last; int offset;
end += dst->bits;
first = fb_pixel_mask(dst->bits, pattern->reverse);
last = ~fb_pixel_mask(end & (BITS_PER_LONG-1), pattern->reverse);
if (end <= BITS_PER_LONG) {
offset = 0;
last = last ? (last & first) : first;
} else {
offset = first != ~0UL;
if (offset) {
first &= get(pattern); if (first)
fb_invert_offset(first, 0, dst);
rotate(pattern);
}
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.